From 08c20d1eaaaaeb6964de70adc4879a2cce24e6ed Mon Sep 17 00:00:00 2001
From: pf2hqatk4 <3315488997@qq.com>
Date: Fri, 18 Apr 2025 18:15:38 +0800
Subject: [PATCH] Delete 'stt/wangEditor.js'
---
stt/wangEditor.js | 10026 --------------------------------------------
1 file changed, 10026 deletions(-)
delete mode 100644 stt/wangEditor.js
diff --git a/stt/wangEditor.js b/stt/wangEditor.js
deleted file mode 100644
index 1dd5de9..0000000
--- a/stt/wangEditor.js
+++ /dev/null
@@ -1,10026 +0,0 @@
-(function (global, factory) {
- // 检查是否在Node.js环境中,如果是则使用CommonJS模块规范导出
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- // 检查是否在AMD环境中,如果是则使用AMD模块定义
- typeof define === 'function' && define.amd ? define(factory) :
- // 否则将wangEditor挂载到全局对象上
- (global.wangEditor = factory());
-}(this, (function () { 'use strict';
-
-/*
- poly-fill
-*/
-
-var polyfill = function () {
-
- // Object.assign的polyfill实现
- if (typeof Object.assign != 'function') {
- Object.assign = function (target, varArgs) {
- // 如果目标对象为null或undefined,抛出TypeError异常
- if (target == null) {
- // 如果目标对象为null或undefined,抛出类型错误异常
- 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];
-
- // 如果当前源对象不为null或undefined
- if (nextSource != null) {
- // 遍历当前源对象的所有属性
- for (var nextKey in nextSource) {
- // 确保只复制源对象自身的属性,而不是继承的属性
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
- // 将当前属性赋值给目标对象
- to[nextKey] = nextSource[nextKey];
- }
- }
- }
- }
- // 返回合并后的目标对象
- return to;
- };
-
-
- // 检查浏览器是否支持 matches 方法,如果不支持则进行扩展
- if (!Element.prototype.matches) {
- // 将 matches 方法定义为 matchesSelector、mozMatchesSelector、msMatchesSelector、oMatchesSelector 或 webkitMatchesSelector 中的一种
- Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function (s) {
- // 使用 querySelectorAll 获取所有匹配选择器的元素
- var matches = (this.document || this.ownerDocument).querySelectorAll(s),
- i = matches.length;
- // 遍历匹配的元素列表,查找当前元素是否存在于其中
- while (--i >= 0 && matches.item(i) !== this) {}
- // 如果找到当前元素,返回 true;否则返回 false
- return i > -1;
- };
- }
-
-// 根据 html 代码片段创建 dom 对象
-
-function createElemByHTML(html) {
- // 声明一个变量div,用于存储创建的div元素
- var div = void 0;
- // 创建一个新的div元素并赋值给div变量
- div = document.createElement('div');
- // 将传入的HTML字符串设置为div元素的innerHTML
- div.innerHTML = html;
- // 返回div元素的子元素集合
- return div.children;
-}
-
-
-
-function isDOMList(selector) {
- // 如果选择器为空,返回false
- if (!selector) {
- return false;
- }
- // 如果选择器是HTMLCollection或NodeList的实例,返回true
- if (selector instanceof HTMLCollection || selector instanceof NodeList) {
- return true;
- }
- // 默认情况下,返回false
- return false;
-}
-
-
-
-function querySelectorAll(selector) {
- // 使用document.querySelectorAll方法根据选择器查找元素
- var result = document.querySelectorAll(selector);
-
- // 判断result是否为DOMList类型
- if (isDOMList(result)) {
- // 如果是DOMList类型,直接返回结果
- return result;
- } else {
- // 如果不是DOMList类型,将结果包装成数组后返回
- return [result];
- }
-}
-
-// 记录所有的事件绑定
-var eventList = [];
-
-// 创建构造函数
-
-function DomElement(selector) {
- // 如果未传入选择器,则直接返回
- if (!selector) {
- return;
- }
-
- // 如果传入的是DomElement实例,则直接返回该实例
- if (selector instanceof DomElement) {
- return selector;
- }
-
- // 将选择器赋值给当前实例的selector属性
- this.selector = selector;
- // 获取选择器的节点类型
- var nodeType = selector.nodeType;
-
- // 定义一个空数组用于存储选择结果
- var selectorResult = [];
- // 如果选择器是文档节点(nodeType为9),则将其放入数组中
- if (nodeType === 9) {
- selectorResult = [selector];
- // 如果选择器是元素节点(nodeType为1),则将其放入数组中
- } else if (nodeType === 1) {
- selectorResult = [selector];
- // 如果选择器是DOM列表或数组,则直接赋值给selectorResult
- } else if (isDOMList(selector) || selector instanceof Array) {
- selectorResult = selector;
- // 如果选择器是字符串类型
- } else if (typeof selector === 'string') {
- // 去除选择器中的换行符并去除首尾空格
- selector = selector.replace('/\n/mg', '').trim();
- // 如果选择器以'<'开头,表示HTML字符串,创建对应的DOM元素
- if (selector.indexOf('<') === 0) {
- selectorResult = createElemByHTML(selector);
- // 否则,使用querySelectorAll方法查找匹配的元素
- } else {
- selectorResult = querySelectorAll(selector);
- }
- }
-
- // 获取选择器结果的长度
- var length = selectorResult.length;
-
- // 如果长度为0,则直接返回当前对象
- if (!length) {
-
- return this;
- }
-
- // 声明变量i并初始化为undefined
- var i = void 0;
-
- // 循环遍历从0到length的每一个索引
- for (i = 0; i < length; i++) {
- // 将selectorResult数组中对应索引的值赋给当前对象的相应位置
- this[i] = selectorResult[i];
- }
-
- // 设置当前对象的长度属性为传入的length值
- this.length = length;
-
-
-omElement.prototype = {
- constructor: DomElement,
-
-
- forEach: function forEach(fn) {
- // 声明变量i用于循环计数
- var i = void 0;
- // 遍历当前对象的每一个元素
- for (i = 0; i < this.length; i++) {
- // 获取当前元素
- var elem = this[i];
- // 调用传入的函数,并将当前元素和索引作为参数传递
- var result = fn.call(elem, elem, i);
- // 如果传入的函数返回false,则中断循环
- if (result === false) {
- break;
- }
- }
- // 返回当前对象以支持链式调用
- return this;
- },
-
-
-
- clone: function clone(deep) {
- // 创建一个空数组用于存储克隆的节点
- var cloneList = [];
- // 遍历当前对象的每个元素
- this.forEach(function (elem) {
- // 将克隆的节点(根据deep参数决定是否深度克隆)添加到cloneList中
- cloneList.push(elem.cloneNode(!!deep));
- });
- // 返回包含克隆节点的新对象
- return $(cloneList);
- },
-
-
- get: function get(index) {
- // 获取当前对象的长度
- var length = this.length;
- // 如果索引大于等于长度,则取模以循环索引
- if (index >= length) {
- index = index % length;
- }
- // 返回指定索引处的元素,并包装成jQuery对象
- return $(this[index]);
- },
-
- first: function first() {
- // 调用get方法获取第一个元素
- return this.get(0);
- },
-
- last: function last() {
- // 获取当前对象的长度
- var length = this.length;
- // 调用get方法获取最后一个元素
- return this.get(length - 1);
- },
-
- on: function on(type, selector, fn) {
- // 如果fn未定义,则将selector赋值给fn,并将selector置为空
- if (!fn) {
- fn = selector;
- selector = null;
- }
-
-
- // 初始化一个空数组,用于存储事件类型
- var types = [];
- // 将传入的事件类型字符串按空格分割成数组
- types = type.split(/\s+/);
-
- // 遍历当前对象的每一个元素
- return this.forEach(function (elem) {
- // 遍历每一个事件类型
- types.forEach(function (type) {
- // 如果事件类型为空,则跳过本次循环
- if (!type) {
- return;
- }
-
- // 将事件信息(元素、事件类型、处理函数)推入事件列表
- eventList.push({
- elem: elem,
- type: type,
- fn: fn
- });
-
- // 如果没有选择器,直接在元素上添加事件监听器
- if (!selector) {
- elem.addEventListener(type, fn);
- return;
- }
-
-
- elem.addEventListener(type, function (e) {
- // 获取事件的目标元素
- var target = e.target;
- // 如果目标元素匹配选择器
- if (target.matches(selector)) {
- // 调用传入的函数,并将目标元素和事件对象作为参数传递
- fn.call(target, e);
- }
- });
-
- off: function off(type, fn) {
- // 遍历当前对象中的每一个元素,移除指定类型的事件监听器
- return this.forEach(function (elem) {
- elem.removeEventListener(type, fn);
- });
- },
-
- attr: function attr(key, val) {
- if (val == null) {
- // 如果val为null或undefined,则获取第一个元素的指定属性值
- return this[0].getAttribute(key);
- } else {
- // 如果val不为null或undefined,则设置每个元素的指定属性值
- return this.forEach(function (elem) {
- elem.setAttribute(key, val);
- });
- }
- },
-
-
- addClass: function addClass(className) {
- // 如果 className 为空,直接返回当前对象
- if (!className) {
- return this;
- }
- // 遍历当前对象中的每个元素
- return this.forEach(function (elem) {
- var arr = void 0;
- // 如果元素已经有 className
- if (elem.className) {
- // 解析当前 className 转换为数组
- arr = elem.className.split(/\s/);
- // 过滤掉空白的 class 名称
- arr = arr.filter(function (item) {
- return !!item.trim();
- });
- // 如果数组中不包含新的 className,则添加它
- if (arr.indexOf(className) < 0) {
- arr.push(className);
- }
- // 将数组重新拼接成字符串并赋值给元素的 className
- elem.className = arr.join(' ');
- } else {
- // 如果元素没有 className,直接赋值新的 className
- elem.className = className;
- }
- });
- },
-
- // 删除 class
- removeClass: function removeClass(className) {
- // 如果 className 为空,直接返回当前对象
- if (!className) {
- return this;
- }
- // 遍历每一个元素
- return this.forEach(function (elem) {
- var arr = void 0;
- // 如果元素有 className 属性
- if (elem.className) {
- // 解析当前 className 转换为数组
- arr = elem.className.split(/\s/);
- // 过滤掉要删除的 className
- arr = arr.filter(function (item) {
- item = item.trim();
- // 删除 class
- if (!item || item === className) {
- return false;
- }
- return true;
- });
- // 修改 elem.class
- elem.className = arr.join(' ');
- }
- });
- },
-
-
- css: function css(key, val) {
- // 将传入的键值对转换为CSS样式字符串
- var currentStyle = key + ':' + val + ';';
-
- // 遍历当前对象中的每一个元素
- return this.forEach(function (elem) {
- // 获取元素的style属性,并去除首尾空格
- var style = (elem.getAttribute('style') || '').trim();
- var styleArr = void 0,
- resultArr = [];
-
- // 如果style属性不为空
- if (style) {
- // 将style属性按分号分割成数组
- styleArr = style.split(';');
-
- // 遍历style数组中的每一个项
- styleArr.forEach(function (item) {
- // 将每一项按冒号分割成键值对数组,并去除首尾空格
- var arr = item.split(':').map(function (i) {
- return i.trim();
- });
-
- // 如果键值对数组长度为2,则将其重新组合成字符串并加入结果数组
- if (arr.length === 2) {
- resultArr.push(arr[0] + ':' + arr[1]);
- }
- });
- // 遍历resultArr数组,对每个元素进行处理
- resultArr = resultArr.map(function (item) {
- // 如果当前元素的开头部分与key相同,则替换为currentStyle
- if (item.indexOf(key) === 0) {
- return currentStyle;
- } else {
- // 否则保持原样
- return item;
- }
- });
-
- // 如果resultArr中不包含currentStyle,则将其添加到resultArr末尾
- if (resultArr.indexOf(currentStyle) < 0) {
- resultArr.push(currentStyle);
- }
-
- // 将处理后的样式数组转换为字符串并设置为元素的style属性
- elem.setAttribute('style', resultArr.join('; '));
- } else {
- // 如果不需要合并样式,直接设置元素的style属性为currentStyle
- elem.setAttribute('style', currentStyle);
- }
-
-
- show: function show() {
- // 将元素的CSS display属性设置为'block',使其显示
- return this.css('display', 'block');
- },
-
- hide: function hide() {
- // 将元素的CSS display属性设置为'none',使其隐藏
- return this.css('display', 'none');
- },
-
- children: function children() {
- // 获取当前元素的第一个子元素
- var elem = this[0];
- if (!elem) {
- // 如果当前元素不存在,返回null
- return null;
- }
-
- // 返回当前元素的所有子元素,使用$函数包装成jQuery对象
- return $(elem.children);
- },
-
- childNodes: function childNodes() {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 如果元素不存在,返回null
- if (!elem) {
- return null;
- }
-
- // 返回该元素的所有子节点
- return $(elem.childNodes);
- },
-
- append: function append($children) {
- // 遍历当前对象中的每个元素
- return this.forEach(function (elem) {
- // 遍历要添加的子节点
- $children.forEach(function (child) {
- // 将子节点添加到当前元素中
- elem.appendChild(child);
- });
- });
- },
-
- remove: function remove() {
- // 遍历当前对象中的每一个元素
- return this.forEach(function (elem) {
- // 如果元素有remove方法,则调用该方法移除元素
- if (elem.remove) {
- elem.remove();
- } else {
- // 否则获取元素的父节点并从父节点中移除该元素
- var parent = elem.parentElement;
- parent && parent.removeChild(elem);
- }
- });
- },
-
- isContain: function isContain($child) {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 获取传入子元素的第一个元素
- var child = $child[0];
- // 判断当前元素是否包含传入的子元素
- return elem.contains(child);
- },
-
- getSizeData: function getSizeData() {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 返回元素的边界矩形数据,包括 bottom, height, left, right, top, width 等属性
- return elem.getBoundingClientRect(); // 可得到 bottom height left right top width 的数据
- },
-
- getNodeName: function getNodeName() {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 返回元素的节点名称
- return elem.nodeName;
- },
-
-
- find: function find(selector) {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 使用querySelectorAll查找子元素,并返回包装后的结果
- return $(elem.querySelectorAll(selector));
- },
-
- text: function text(val) {
- if (!val) {
- // 如果未传入参数,则获取第一个元素的文本内容
- var elem = this[0];
- // 移除HTML标签,只保留纯文本
- return elem.innerHTML.replace(/<.*?>/g, function () {
- return '';
- });
- } else {
- // 如果传入了参数,则设置每个元素的文本内容
- return this.forEach(function (elem) {
- elem.innerHTML = val;
- });
- }
- },
-
-
- html: function html(value) {
- // 获取当前对象的第一个元素
- var elem = this[0];
-
- // 如果传入的值为null或undefined,则返回元素的innerHTML内容
- if (value == null) {
- return elem.innerHTML;
- } else {
- // 否则,将传入的值设置为元素的innerHTML内容
- elem.innerHTML = value;
- // 返回当前对象以支持链式调用
- return this;
- }
- },
-
- val: function val() {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 返回该元素的值,并去除前后空格
- return elem.value.trim();
- },
-
- focus: function focus() {
- // 遍历当前对象的每一个元素
- return this.forEach(function (elem) {
- // 将焦点设置到当前元素上
- elem.focus();
- });
- },
-
- parent: function parent() {
- // 获取当前对象的第一个元素
- var elem = this[0];
- // 返回该元素的父元素,并包装成jQuery对象
- return $(elem.parentElement);
- },
-
-
- parentUntil: function parentUntil(selector, _currentElem) {
- // 使用querySelectorAll查找所有匹配选择器的元素
- var results = document.querySelectorAll(selector);
- // 获取匹配元素的数量
- var length = results.length;
- // 如果没有匹配的元素
- if (!length) {
- // 返回null
- return null;
- }
-
- var elem = _currentElem || this[0]; // 获取当前元素,如果未定义则使用this的第一个元素
- if (elem.nodeName === 'BODY') { // 如果当前元素的节点名称是'BODY'
- return null; // 返回null
- }
-
- var parent = elem.parentElement; // 获取当前元素的父元素
- var i = void 0; // 声明变量i并初始化为undefined
- for (i = 0; i < length; i++) { // 遍历长度为length的数组
- if (parent === results[i]) { // 如果父元素等于results数组中的某个元素
- // 找到,并返回
- return $(parent); // 返回父元素的jQuery对象
- }
- }
-
- // 继续查找父元素,直到找到匹配选择器的父元素
- return this.parentUntil(selector, parent);
-},
-
-// 判断两个 elem 是否相等
-equal: function equal($elem) {
- // 如果传入的 $elem 是一个节点类型为1的元素(即元素节点)
- if ($elem.nodeType === 1) {
- // 比较当前对象的第一个元素和传入的 $elem 是否相同
- return this[0] === $elem;
- } else {
- // 否则,比较当前对象的第一个元素和传入的 $elem 的第一个元素是否相同
- return this[0] === $elem[0];
- }
-},
-
- // 将该元素插入到某个元素前面
- insertBefore: function insertBefore(selector) {
- // 获取参考节点的jQuery对象
- var $referenceNode = $(selector);
- // 获取参考节点的DOM对象
- var referenceNode = $referenceNode[0];
- // 如果参考节点不存在,直接返回当前对象
- if (!referenceNode) {
- return this;
- }
- // 遍历当前对象中的每个元素
- return this.forEach(function (elem) {
- // 获取参考节点的父节点
- var parent = referenceNode.parentNode;
- // 将当前元素插入到参考节点之前
- parent.insertBefore(elem, referenceNode);
- });
- },
-
- // 将该元素插入到某个元素后面
- insertAfter: function insertAfter(selector) {
- // 获取参考节点的jQuery对象
- var $referenceNode = $(selector);
- // 获取参考节点的DOM对象
- var referenceNode = $referenceNode[0];
- // 如果参考节点不存在,直接返回当前对象
- if (!referenceNode) {
- return this;
- }
- // 遍历当前对象中的每个元素
- return this.forEach(function (elem) {
- // 获取参考节点的父节点
- var parent = referenceNode.parentNode;
- // 如果参考节点是父节点的最后一个子节点
- if (parent.lastChild === referenceNode) {
- // 将当前元素追加到父节点的末尾
- parent.appendChild(elem);
- } else {
- // 否则,将当前元素插入到参考节点的下一个兄弟节点之前
- parent.insertBefore(elem, referenceNode.nextSibling);
- }
- });
- }
-
-
-function $(selector) {
- // 创建一个新的DomElement对象并返回
- return new DomElement(selector);
-}
-
-
-$.offAll = function () {
- // 遍历事件列表
- eventList.forEach(function (item) {
- // 获取元素、事件类型和处理函数
- var elem = item.elem;
- var type = item.type;
- var fn = item.fn;
- // 解绑事件监听器
- elem.removeEventListener(type, fn);
- });
-};
-
-
-
-
-var config = {
-
- // 默认菜单配置,包含各种编辑功能按钮
- menus: ['head', 'bold', 'fontSize', 'fontName', 'italic', 'underline', 'strikeThrough', 'foreColor', 'backColor', 'link', 'list', 'justify', 'quote', 'emoticon', 'image', 'table', 'video', 'code', 'undo', 'redo'],
-
- // 字体名称列表
- fontNames: ['宋体', '微软雅黑', 'Arial', 'Tahoma', 'Verdana'],
-
- // 颜色代码数组,用于设置文本和背景颜色
- colors: ['#000000', '#eeece0', '#1c487f', '#4d80bf', '#c24f4a', '#8baa4a', '#7b5ba1', '#46acc8', '#f9963b', '#ffffff'],
-
- // 表情配置
- emotions: [{
- // tab 的标题
- title: '默认',
- // type -> 'emoji' / 'image',表示表情的类型是图片
- type: 'image',
- // content -> 数组,包含表情的具体信息
- content: [{
- // alt 属性为表情的描述文字
- alt: '[坏笑]',
- // src 属性为表情图片的 URL
- src: 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/50/pcmoren_huaixiao_org.png'
- }, {
- alt: '[舔屏]',
- src: 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/40/pcmoren_tian_org.png'
- }, {
- alt: '[污]',
- src: 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/3c/pcmoren_wu_org.png'
- }]
- }, {
- // tab 的标题
- title: '新浪',
- // type -> 'emoji' / 'image'
- type: 'image',
- // content -> 数组,包含多个表情图片对象
- content: [{
- // 表情图片的 URL 地址
- src: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7a/shenshou_thumb.gif',
- // 表情图片的替代文本
- alt: '[草泥马]'
- }, {
- // 表情图片的 URL 地址
- src: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/60/horse2_thumb.gif',
- // 表情图片的替代文本
- alt: '[神马]'
- }, {
- // 表情图片的 URL 地址
- src: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/bc/fuyun_thumb.gif',
- // 表情图片的替代文本
- alt: '[浮云]'
- }]
-}, {
- // tab 的标题
- title: 'emoji',
- // type -> 'emoji' / 'image'
- type: 'emoji',
- // content -> 数组,包含多个 emoji 字符
- content: '😀 😃 😄 😁 😆 😅 😂 😊 😇 🙂 🙃 😉 😓 😪 😴 🙄 🤔 😬 🤐'.split(/\s/)
-}],
- title: 'emoji',
- // type -> 'emoji' / 'image'
- type: 'emoji',
- // content -> 数组,包含多个 emoji 字符
- content: '😀 😃 😄 😁 😆 😅 😂 😊 😇 🙂 🙃 😉 😓 😪 😴 🙄 🤔 😬 🤐'.split(/\s/)
-}],
-
- // 编辑区域的 z-index
- zIndex: 10000,
-
- // 是否开启 debug 模式(debug 模式下错误会 throw error 形式抛出)
- debug: false,
-
- // 插入链接时候的格式校验
- linkCheck: function linkCheck(text, link) {
- // text 是插入的文字
- // link 是插入的链接
- return true; // 返回 true 即表示成功
- // return '校验失败' // 返回字符串即表示失败的提示信息
- },
-
- // 插入网络图片的校验
- linkImgCheck: function linkImgCheck(src) {
- // src 即图片的地址
- return true; // 返回 true 即表示成功
- // return '校验失败' // 返回字符串即表示失败的提示信息
- },
-
- // 粘贴过滤样式,默认开启
- pasteFilterStyle: true,
-
- // 粘贴内容时,忽略图片。默认关闭
- pasteIgnoreImg: false,
-
-
- pasteTextHandle: function pasteTextHandle(content) {
- // content 即粘贴过来的内容(html 或 纯文本),可进行自定义处理然后返回
- return content;
- },
-
- showLinkImg: true,
-
- // 插入网络图片的回调
- linkImgCallback: function linkImgCallback(url) {
- // console.log(url) // url 即插入图片的地址
- },
-
- // 默认上传图片 max size: 5M
- uploadImgMaxSize: 5 * 1024 * 1024,
-
- // 配置一次最多上传几个图片
- // uploadImgMaxLength: 5,
-
- // 上传图片,是否显示 base64 格式
- uploadImgShowBase64: false,
-
- // 上传图片,server 地址(如果有值,则 base64 格式的配置则失效)
- // uploadImgServer: '/upload',
-
- // 自定义配置 filename
- uploadFileName: '',
-
- // 上传图片的自定义参数
- uploadImgParams: {
- // token: 'abcdef12345'
- },
-
- // 上传图片的自定义header
- uploadImgHeaders: {
- // 'Accept': 'text/x-json'
- },
-
- // 配置 XHR withCredentials
- withCredentials: false,
-
- // 自定义上传图片超时时间 ms
- uploadImgTimeout: 10000,
-
- // 上传图片 hook
- uploadImgHooks: {
-
- before: function before(xhr, editor, files) {
-
- },
- success: function success(xhr, editor, result) {
- // 图片上传并返回结果,图片插入成功之后触发
- },
- fail: function fail(xhr, editor, result) {
- // 图片上传并返回结果,但图片插入错误时触发
- },
- error: function error(xhr, editor) {
- // 图片上传出错时触发
- },
- timeout: function timeout(xhr, editor) {
- // 图片上传超时时触发
- }
- },
-
- // 是否上传七牛云,默认为 false
- qiniu: false
-
-};
-
-
-var UA = {
- // 获取用户代理字符串
- _ua: navigator.userAgent,
-
- // 判断是否为 Webkit 内核的浏览器
- isWebkit: function isWebkit() {
- // 定义匹配 Webkit 的正则表达式
- var reg = /webkit/i;
- // 测试用户代理字符串是否包含 'webkit'
- return reg.test(this._ua);
- },
-
- // 判断是否为 IE 浏览器
- isIE: function isIE() {
- // 检查 window 对象中是否存在 ActiveXObject 属性
- return 'ActiveXObject' in window;
- }
-};
-
-
-
-function objForEach(obj, fn) {
- // 定义变量key用于存储当前遍历的属性名
- var key = void 0,
- // 定义变量result用于存储函数fn的返回值
- result = void 0;
- // 使用for...in循环遍历对象的所有可枚举属性
- for (key in obj) {
- // 检查属性是否是对象自身的属性(而不是继承自原型链)
- if (obj.hasOwnProperty(key)) {
- // 调用传入的函数fn,并将当前属性名和属性值作为参数传递
- result = fn.call(obj, key, obj[key]);
- // 如果函数fn返回false,则中断循环
- if (result === false) {
- break;
- }
- }
- }
-}
-
-
-
-function arrForEach(fakeArr, fn) {
- // 声明变量i用于循环计数,item用于存储当前元素,result用于存储函数返回值
- var i = void 0,
- item = void 0,
- result = void 0;
- // 获取伪数组的长度,如果长度为undefined则默认为0
- var length = fakeArr.length || 0;
- // 使用for循环遍历伪数组
- for (i = 0; i < length; i++) {
- // 获取当前元素
- item = fakeArr[i];
- // 调用传入的函数,并将当前元素、索引和数组本身作为参数传递
- result = fn.call(fakeArr, item, i);
- // 如果函数返回false,则中断循环
- if (result === false) {
- break;
- }
- }
-}
-
-
-
-function getRandom(prefix) {
- // 使用Math.random()生成一个0到1之间的随机数,并将其转换为字符串
- // 然后通过slice(2)去掉字符串的前两位(即"0."),只保留小数部分
- return prefix + Math.random().toString().slice(2);
-}
-
-
-/function replaceHtmlSymbol(html) {
- // 如果输入的HTML字符串为null,则返回空字符串
- if (html == null) {
- return '';
- }
- // 使用正则表达式替换HTML字符串中的<、>、"和换行符为对应的HTML实体
- return html.replace(//gm, '>') // 替换所有的>为>
- .replace(/"/gm, '"') // 替换所有的"为"
- .replace(/(\r\n|\r|\n)/g, '
'); // 替换所有的换行符为
-}
-
-
-
-
-
-
-function isFunction(fn) {
- // 使用typeof运算符检查参数的类型是否为'function'
- return typeof fn === 'function';
-}
-
-
-function Bold(editor) {
- // 将传入的编辑器实例赋值给当前对象的editor属性
- this.editor = editor;
- // 创建一个包含加粗图标的div元素,并赋值给当前对象的$elem属性
- this.$elem = $('
设置标题
'), - 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)) { - return; - } - - // 执行格式化命令,将选中的内容格式化为指定的块类型 - editor.cmd.do('formatBlock', value); - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前元素 - var $elem = this.$elem; - // 定义正则表达式,用于匹配以 'h' 开头的字符串(忽略大小写) - var reg = /^h/i; - // 查询当前命令的值,判断是否为标题格式 - var cmdValue = editor.cmd.queryCommandValue('formatBlock'); - // 如果命令值匹配正则表达式,表示当前是标题格式 - if (reg.test(cmdValue)) { - // 设置活动状态为 true - this._active = true; - // 为当前元素添加 'w-e-active' 类,表示激活状态 - $elem.addClass('w-e-active'); - } else { - // 设置活动状态为 false - this._active = false; - // 移除当前元素的 'w-e-active' 类,表示非激活状态 - $elem.removeClass('w-e-active'); - } - } - - -function FontSize(editor) { - var _this = this; // 保存当前对象的引用,以便在嵌套函数中使用 - - this.editor = editor; // 将传入的编辑器对象赋值给当前实例的 editor 属性 - this.$elem = $('
'); // 创建菜单元素并添加到当前实例的 $elem 属性中 - this.type = 'droplist'; // 设置菜单类型为下拉列表 - - // 当前是否 active 状态 - this._active = false; // 初始化 active 状态为 false - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 160, // 设置下拉列表的宽度 - $title: $('字号
'), // 设置下拉列表的标题 - type: 'list', // 设置下拉列表的类型为列表形式展示 - list: [ - { $elem: $('x-small'), value: '1' }, // 定义第一个选项:字体大小为 x-small - { $elem: $('small'), value: '2' }, // 定义第二个选项:字体大小为 small - { $elem: $('normal'), value: '3' }, // 定义第三个选项:字体大小为 normal - { $elem: $('large'), value: '4' }, // 定义第四个选项:字体大小为 large - { $elem: $('x-large'), value: '5' }, // 定义第五个选项:字体大小为 x-large - { $elem: $('xx-large'), value: '6' } // 定义第六个选项:字体大小为 xx-large - ], - onClick: function onClick(value) { - // 注意 this 是指向当前的 FontSize 对象 - _this._command(value); // 调用当前对象的 _command 方法,并传递选中的值 - } - }); -} - - -FontSize.prototype = { - constructor: FontSize, - - - _command: function _command(value) { - // 获取当前编辑器实例 - var editor = this.editor; - // 调用编辑器的命令接口,设置字体大小 - editor.cmd.do('fontSize', value); - } -}; - - -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', // 设置下拉列表类型为列表形式展示 - list: fontNames.map(function (fontName) { - // 将每个字体名称映射为一个对象,包含显示的元素和值 - return { $elem: $('' + fontName + ''), value: fontName }; - }), - onClick: function onClick(value) { - // 注意 this 是指向当前的 FontName 对象 - // 当点击某个字体时,执行命令 - _this._command(value); - } - }); -} - - -FontName.prototype = { - // 构造函数,指向FontName类 - constructor: FontName, - - - _command: function _command(value) { - // 获取当前编辑器实例 - var editor = this.editor; - // 调用编辑器的命令接口,设置字体名称 - editor.cmd.do('fontName', value); - } -}; - - - -var emptyFn = function emptyFn() {}; -// 定义一个空函数,用于占位或默认回调 - -// 记录已经显示 panel 的菜单 -var _isCreatedPanelMenus = []; -// 初始化一个数组,用于存储已经创建的 panel 菜单 - -// 构造函数 -function Panel(menu, opt) { - this.menu = menu; - // 将传入的 menu 参数赋值给实例的 menu 属性 - this.opt = opt; - // 将传入的 opt 参数赋值给实例的 opt 属性 -} - - -Panel.prototype = { - constructor: Panel, - - - show: function show() { - // 保存当前对象的引用 - var _this = this; - - // 获取当前面板的菜单 - var menu = this.menu; - // 如果菜单已经创建过,则直接返回 - if (_isCreatedPanelMenus.indexOf(menu) >= 0) { - // 如果菜单已经创建,则直接返回 - return; - } - var editor = menu.editor; // 获取编辑器实例 - var $body = $('body'); // 获取 body 元素 - var $textContainerElem = editor.$textContainerElem; // 获取文本容器元素 - var opt = this.opt; // 获取配置选项 - - // panel 的容器 - var $container = $(''); // 创建一个新的 div 作为面板容器 - 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(); - }); - - - // 创建一个包含类名 'w-e-panel-tab-title' 的设置列表
'), // 设置下拉列表标题 - type: 'list', // 设置下拉列表展示形式为列表 - list: [ - { $elem: $(' 有序列表'), value: 'insertOrderedList' }, // 添加有序列表选项 - { $elem: $(' 无序列表'), value: 'insertUnorderedList' } // 添加无序列表选项 - ], - onClick: function onClick(value) { - // 注意 this 是指向当前的 List 对象 - _this._command(value); // 调用命令方法执行相应的操作 - } - }); -} - - -ist.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)) { // 如果父元素等于文本元素 - // 如果是根节点,则不处理 - return; // 退出函数 - } - - $selectionElem.insertAfter($parent); // 将选中元素插入到父元素的后面 - $parent.remove(); // 移除父元素 - }, - - - 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'); // 移除活动样式类 - } - } - }; - - -function Justify(editor) { - // 保存当前对象的引用 - var _this = this; - - // 将传入的编辑器对象赋值给当前实例的 editor 属性 - this.editor = editor; - // 创建一个包含图标和样式的 div 元素,并赋值给当前实例的 $elem 属性 - this.$elem = $(' '); - // 设置类型为 'droplist' - this.type = 'droplist'; - - // 初始化一个布尔值,表示当前是否处于 active 状态 - this._active = false; - - // 初始化 droplist 组件 - this.droplist = new DropList(this, { - // 设置 droplist 的宽度 - width: 100, - // 设置 droplist 的标题 - $title: $('对齐方式
'), - // 设置 droplist 的类型为列表形式展示 - type: 'list', - // 定义列表项及其对应的值 - 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; - // 调用编辑器的cmd对象的do方法,执行传入的命令 - editor.cmd.do(value); - } -}; - - -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', // 设置下拉列表内容以 inline-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); - } -}; - - -function BackColor(editor) { - var _this = this; // 保存当前对象的引用,以便在回调函数中使用 - - this.editor = editor; // 将传入的编辑器对象赋值给当前实例的 editor 属性 - this.$elem = $(' '); // 创建菜单元素并添加到当前实例的 $elem 属性中 - this.type = 'droplist'; // 设置菜单类型为下拉列表 - - // 获取配置的颜色 - var config = editor.config; // 从编辑器配置中获取配置对象 - var colors = config.colors || []; // 获取配置中的颜色数组,如果没有则使用空数组 - - // 当前是否 active 状态 - this._active = false; // 初始化 active 状态为 false - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 120, // 设置下拉列表的宽度 - $title: $('背景色
'), // 设置下拉列表的标题 - type: 'inline-block', // 设置下拉列表内容以 inline-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); - } -}; - - -function Quote(editor) { - // 将传入的编辑器实例赋值给当前对象的 editor 属性 - this.editor = editor; - - // 创建一个包含特定 HTML 结构的 jQuery 对象,并赋值给当前对象的 $elem 属性 - this.$elem = $(' '); - - // 设置事件类型为 'click' - this.type = 'click'; - - // 初始化当前对象的 active 状态为 false - this._active = false; -} - -// 原型 -Quote.prototype = { - constructor: Quote, - - onClick: function onClick(e) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前选中的容器元素 - var $selectionElem = editor.selection.getSelectionContainerElem(); - // 获取选中元素的节点名称 - var nodeName = $selectionElem.getNodeName(); - - // 判断是否为非IE浏览器 - if (!UA.isIE()) { - // 如果选中的元素是 BLOCKQUOTE,则撤销引用格式 - if (nodeName === 'BLOCKQUOTE') { - editor.cmd.do('formatBlock', ''); - } else { - // 否则,将选中的元素转换为引用格式 - editor.cmd.do('formatBlock', '
'); - } - return; - } - - // 定义变量 content 和 $targetELem,初始值为 undefined - var content = void 0, - $targetELem = void 0; - if (nodeName === 'P') { - // 如果当前节点是 P 标签 - // 将 P 标签的内容赋值给 content - content = $selectionElem.text(); - // 创建一个新的 blockquote 元素,并将 P 标签的内容插入其中 - $targetELem = $(''); - - // 设置事件类型为点击事件 - this.type = 'click'; - - // 初始化当前对象是否处于 active 状态的属性,默认值为 false - this._active = false; -} - - -Italic.prototype = { - constructor: Italic, - - - onClick: function onClick(e) { - // 获取编辑器实例 - var editor = this.editor; - // 检查当前选区是否为空 - var isSeleEmpty = editor.selection.isSelectionEmpty(); - - if (isSeleEmpty) { - // 如果选区为空,则创建一个空的选区 - editor.selection.createEmptyRange(); - } - - // 执行斜体命令 - editor.cmd.do('italic'); - } -}; - - if (isSeleEmpty) { - // 如果选择为空,则折叠选区并恢复选区 - editor.selection.collapseRange(); - editor.selection.restoreSelection(); - } - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; // 获取编辑器实例 - var $elem = this.$elem; // 获取当前元素的 jQuery 对象 - if (editor.cmd.queryCommandState('italic')) { - // 如果编辑器命令状态为斜体,则设置 active 状态为 true 并添加 'w-e-active' 类 - this._active = true; - $elem.addClass('w-e-active'); - } else { - // 否则设置 active 状态为 false 并移除 'w-e-active' 类 - this._active = false; - $elem.removeClass('w-e-active'); - } - } - }; - - -function Redo(editor) { - // 将传入的编辑器实例赋值给当前对象的 editor 属性 - this.editor = editor; - - // 创建一个包含重做图标的 div 元素,并赋值给当前对象的 $elem 属性 - this.$elem = $(' '); - - // 设置事件类型为 'click' - this.type = 'click'; - - // 初始化当前是否处于 active 状态的属性,默认值为 false - this._active = false; -} - - -Redo.prototype = { - constructor: Redo, - - - onClick: function onClick(e) { - // 获取当前编辑器实例 - var editor = this.editor; - - // 执行重做命令 - editor.cmd.do('redo'); - } -}; - - -function StrikeThrough(editor) { - // 初始化编辑器实例 - this.editor = editor; - // 创建菜单元素并设置类名和图标 - this.$elem = $(' '); - // 设置事件类型为点击 - this.type = 'click'; - - // 当前是否 active 状态 - this._active = false; -} - -StrikeThrough.prototype = { - constructor: StrikeThrough, - - // 点击事件处理函数 - onClick: function onClick(e) { - // 获取编辑器实例 - var editor = this.editor; - // 判断当前选区是否为空 - var isSeleEmpty = editor.selection.isSelectionEmpty(); - - if (isSeleEmpty) { - // 选区是空的,插入并选中一个“空白” - editor.selection.createEmptyRange(); - } - - // 执行 strikeThrough 命令 - editor.cmd.do('strikeThrough'); - - if (isSeleEmpty) { - // 需要将选取折叠起来 - editor.selection.collapseRange(); - // 恢复之前的选取范围 - editor.selection.restoreSelection(); - } - }, - - - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; // 获取编辑器实例 - var $elem = this.$elem; // 获取当前元素 - if (editor.cmd.queryCommandState('strikeThrough')) { - // 如果命令状态为删除线,则设置 active 状态为 true - this._active = true; - // 添加 'w-e-active' 类以表示激活状态 - $elem.addClass('w-e-active'); - } else { - // 否则设置 active 状态为 false - this._active = false; - // 移除 'w-e-active' 类以表示非激活状态 - $elem.removeClass('w-e-active'); - } - } - }; - - -function Underline(editor) { - // 初始化Underline对象,并设置编辑器实例 - this.editor = editor; - // 创建菜单元素,包含下划线图标 - this.$elem = $(' '); - // 设置事件类型为点击 - this.type = 'click'; - - // 当前是否激活状态 - this._active = false; -} - -Underline.prototype = { - constructor: Underline, - - - onClick: function onClick(e) { - // 阻止默认行为和冒泡 - e.preventDefault(); - e.stopPropagation(); - - // 获取编辑器实例 - var editor = this.editor; - // 判断当前选区是否为空 - var isSeleEmpty = editor.selection.isSelectionEmpty(); - if (isSeleEmpty) { - // 如果当前选择为空,则创建一个空的选择范围 - editor.selection.createEmptyRange(); - } - - // 执行下划线命令 - editor.cmd.do('underline'); - - if (isSeleEmpty) { - // 如果当前选择为空,则将光标折叠到起始位置并恢复之前的选择 - editor.selection.collapseRange(); - editor.selection.restoreSelection(); - } - }, - - - tryChangeActive: function tryChangeActive(e) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前元素的jQuery对象 - var $elem = this.$elem; - // 检查编辑器命令'underline'的状态 - if (editor.cmd.queryCommandState('underline')) { - // 如果命令状态为激活,设置_active属性为true - this._active = true; - // 给元素添加'w-e-active'类 - $elem.addClass('w-e-active'); - } else { - // 如果命令状态为未激活,设置_active属性为false - this._active = false; - // 从元素中移除'w-e-active'类 - $elem.removeClass('w-e-active'); - } - } - -function Undo(editor) { - // 保存编辑器实例 - this.editor = editor; - // 创建菜单元素并设置类名和图标 - this.$elem = $(' '); - // 设置事件类型为点击 - this.type = 'click'; - - // 当前是否 active 状态 - this._active = false; -} - -Undo.prototype = { - constructor: Undo, - - - onClick: function onClick(e) { - // 获取编辑器实例 - var editor = this.editor; - - // 执行撤销命令 - editor.cmd.do('undo'); - } -}; - - -function List(editor) { - var _this = this; // 保存当前对象的引用,以便在嵌套函数中使用 - - this.editor = editor; // 将传入的编辑器实例赋值给当前对象 - this.$elem = $(' '); // 创建菜单元素并添加到当前对象 - this.type = 'droplist'; // 设置菜单类型为下拉列表 - - // 当前是否 active 状态 - this._active = false; // 初始化 active 状态为 false - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 120, // 设置下拉列表宽度为 120 - $title: $('' + content + ''); - // 将新的 blockquote 元素插入到 P 标签之后 - $targetELem.insertAfter($selectionElem); - // 移除原来的 P 标签 - $selectionElem.remove(); - // 结束函数执行 - return; - } - if (nodeName === 'BLOCKQUOTE') { - // 如果当前节点是 BLOCKQUOTE 标签 - // 将 BLOCKQUOTE 标签的内容赋值给 content - content = $selectionElem.text(); - // 创建一个新的 P 元素,并将 BLOCKQUOTE 标签的内容插入其中 - $targetELem = $('' + content + '
'); - // 将新的 P 元素插入到 BLOCKQUOTE 标签之后 - $targetELem.insertAfter($selectionElem); - // 移除原来的 BLOCKQUOTE 标签 - $selectionElem.remove(); - } - }, - - tryChangeActive: function tryChangeActive(e) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前元素的jQuery对象 - var $elem = this.$elem; - // 定义正则表达式,用于匹配BLOCKQUOTE标签 - var reg = /^BLOCKQUOTE$/i; - // 查询当前命令的值,判断是否为BLOCKQUOTE格式 - var cmdValue = editor.cmd.queryCommandValue('formatBlock'); - // 如果当前命令值为BLOCKQUOTE格式 - if (reg.test(cmdValue)) { - // 设置_active属性为true - this._active = true; - // 给元素添加'w-e-active'类 - $elem.addClass('w-e-active'); - } else { - // 设置_active属性为false - this._active = false; - // 移除元素的'w-e-active'类 - $elem.removeClass('w-e-active'); - } - } - - - -function Code(editor) { - // 将传入的编辑器实例赋值给当前对象的editor属性 - this.editor = editor; - // 创建一个包含特定HTML结构的jQuery元素,并赋值给当前对象的$elem属性 - this.$elem = $(' '); - // 设置当前对象的类型为'panel' - this.type = 'panel'; - - // 当前未使用 - // 初始化_active属性为false,表示当前状态未激活 - 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) { - // 如果当前插件已经激活,则显示带有当前HTML内容的代码块面板 - this._createPanel($startElem.html()); - } else { - // 如果当前插件未激活,则显示一个空的代码块面板 - this._createPanel(); - } - }, - - _createPanel: function _createPanel(value) { - var _this = this; - - // 如果 value 为空,则设置为空字符串 - value = value || ''; - // 根据 value 是否为空判断是新建还是编辑模式 - var type = !value ? 'new' : 'edit'; - // 生成随机的文本框 ID - var textId = getRandom('texxt'); - // 生成随机的按钮 ID - var btnId = getRandom('btn'); - - // 创建一个新的 Panel 对象 - var panel = new Panel(this, { - width: 500, - // 一个 Panel 包含多个 tab - tabs: [{ - // 标题 - title: '插入代码', - // 模板,包含一个文本框和一个按钮 - tpl: '
\n \n\n', - // 事件绑定 - events: [ - // 插入代码的事件处理函数 - { - selector: '#' + btnId, - type: 'click', - fn: function fn() { - // 获取文本框的值或 HTML 内容 - var $text = $('#' + textId); - var text = $text.val() || $text.html(); - // 替换 HTML 特殊字符 - text = replaceHtmlSymbol(text); - if (type === 'new') { - // 新插入操作 - _this._insertCode(text); - } else { - // 编辑更新操作 - _this._updateCode(text); - } - - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - } - ] - }); - - // 显示 panel - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 插入代码 - _insertCode: function _insertCode(value) { - // 获取当前编辑器实例 - var editor = this.editor; - // 执行插入HTML命令,将传入的代码值包裹在标签中并插入到编辑器中 - editor.cmd.do('insertHTML', '
' + value + '
'); - }, - - // 更新代码 - _updateCode: function _updateCode(value) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前选中的DOM元素 - var $selectionELem = editor.selection.getSelectionContainerElem(); - // 如果未选中任何元素,则直接返回 - if (!$selectionELem) { - return; - } - // 将选中元素的HTML内容更新为传入的值 - $selectionELem.html(value); - // 恢复选区到之前的位置 - editor.selection.restoreSelection(); - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - // 获取编辑器实例 - var editor = this.editor; - // 获取当前元素的 jQuery 对象 - var $elem = this.$elem; - // 获取当前选中的容器元素 - var $selectionELem = editor.selection.getSelectionContainerElem(); - // 如果未选中任何元素,则直接返回 - if (!$selectionELem) { - return; - } - // 获取选中元素的父元素 - var $parentElem = $selectionELem.parent(); - // 判断选中的元素是否为
且其父元素是否为
- if ($selectionELem.getNodeName() === 'CODE' && $parentElem.getNodeName() === 'PRE') { - // 设置 active 状态为 true - this._active = true; - // 给当前元素添加 'w-e-active' 类 - $elem.addClass('w-e-active'); - } else { - // 设置 active 状态为 false - this._active = false; - // 移除当前元素的 'w-e-active' 类 - $elem.removeClass('w-e-active'); - } - } - - -function Emoticon(editor) { - // 初始化表情对象,传入编辑器实例 - this.editor = editor; - // 创建表情菜单的DOM元素 - this.$elem = $('' + item + ''; - } - }); - } - // 图片表情 - if (emotType === 'image') { - content.forEach(function (item) { - var src = item.src; - var alt = item.alt; - if (src) { - // 加一个 data-w-e 属性,点击图片的时候不再提示编辑图片 - faceHtml += ''); - // 设置菜单类型为面板 - this.type = 'panel'; - - // 当前是否激活状态 - 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 += ''; - } - }); - } - - 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('