| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- // 标识必须独一无二 - 标识是为了使用insertText插入标识文本后,查找到标识所在delta位置的索引
- export const linkFlag = '#-*=*-*=*-*=*@-link超链接标识link-@*=*-*=*-*=*-#'
- export function addLink(editorCtx, attr, callback) {
- // 先插入一段文本内容
- editorCtx.insertText({
- text: linkFlag
- })
- // 获取全文delta内容
- editorCtx.getContents({
- success(res) {
- let options = res.delta.ops
- const findex = options.findIndex(item => {
- return item.insert && typeof item.insert !== 'object' && item.insert?.indexOf(linkFlag) !== -1
- })
- // 根据标识查找到插入的位置
- if (findex > -1) {
- const findOption = options[findex]
- const findAttributes = findOption.attributes
- // 将该findOption分成三部分:前内容 要插入的link 后内容
- const [prefix, suffix] = findOption.insert.split(linkFlag);
- const handleOps = []
- // 前内容
- if (prefix) {
- const prefixOps = findAttributes ? {
- insert: prefix,
- attributes: findAttributes
- } : {
- insert: prefix
- }
- handleOps.push(prefixOps)
- }
- // 插入的link
- const linkOps = {
- insert: attr.text,
- attributes: {
- link: attr.href,
- textDecoration: attr.textDecoration || 'none', // 下划线
- color: attr.color || '#007aff'
- }
- }
- handleOps.push(linkOps)
- // 后内容
- if (suffix) {
- const suffixOps = findAttributes ? {
- insert: suffix,
- attributes: findAttributes
- } : {
- insert: suffix
- }
- handleOps.push(suffixOps)
- }
- // 删除原options[findex]并在findex位置插入上述三个ops
- options.splice(findex, 1);
- options.splice(findex, 0, ...handleOps);
- // 最后重新初始化内容,注意该方法会导致光标重置到最开始位置
- editorCtx.setContents({
- delta: {
- ops: options
- }
- })
- // 所以最后建议使富文本光标失焦,让用户手动聚焦光标
- editorCtx.blur()
- // 后续回调操作
- if (callback) callback()
- }
- }
- })
- }
- /**
- * 将含有特殊图片形式视频的富文本转换成正常视频的富文本
- * @param {String} html 要进行处理的富文本字符串
- * @returns {String} 返回处理结果
- */
- export function handleHtmlWithVideo(html) {
- // 正则表达式用于匹配img标签中带有alt属性且alt属性值为视频链接的模式
- const regex = /<img\s+src="[^"]*"\s+alt="([^"]*)"[^>]*>/g
- // 使用replace方法和一个函数回调来替换匹配到的内容
- return html.replace(regex, (match, videoUrl) => {
- // 替换为video标签,并添加controls属性以便用户可以控制播放
- return `<video width="80%" controls><source src="${videoUrl}" type="video/mp4"></video>`
- })
- }
- /**
- * 将img标签中内联style属性中的宽高样式提取出标签width与height属性
- * @param {Object} html 要处理的富文本字符串
- * @returns {Object} 返回处理结果
- */
- export function convertImgStylesToAttributes(html) {
- return html.replace(/<img\s+([^>]+)\s*>/g, function(match, attributes) {
- // 分割属性
- const attrs = attributes.split(/\s+/);
- // 找到style属性的位置
- const styleIndex = attrs.findIndex(attr => attr.startsWith('style='));
- if (styleIndex === -1) return match; // 如果没有找到style属性,则返回原样
- // 提取style属性值
- const styleAttr = attrs.splice(styleIndex, 1)[0];
- const style = styleAttr.match(/"([^"]*)"/)[1];
- // 解析 style 属性
- const styleObj = {};
- style.split(';').forEach(function(part) {
- if (part) {
- const [name, value] = part.split(':');
- styleObj[name.trim()] = value.trim();
- }
- });
- // 创建新的 img 标签
- let newTag = '<img';
- if (styleObj.width) {
- newTag += ` width="${styleObj.width}"`;
- }
- if (styleObj.height) {
- newTag += ` height="${styleObj.height}"`;
- }
- // 添加原有的属性,包括修改过的style属性
- newTag += ` ${styleAttr} ${attrs.join(' ')}`;
- // 关闭 img 标签
- newTag += '>';
- return newTag;
- });
- }
|