`;
// 添加到页面
document.body.appendChild(container);
// 获取DOM元素引用
const overlay = document.getElementById(`${pickerId}-overlay`);
const pickerContainer = document.getElementById(`${pickerId}-container`);
const closeBtn = pickerContainer.querySelector('.close-btn');
const hueSlider = pickerContainer.querySelector('.hue-slider');
const hueHandle = pickerContainer.querySelector('.hue-handle');
const colorPanel = pickerContainer.querySelector('.color-panel');
const colorHandle = pickerContainer.querySelector('.color-handle');
const hexInput = document.getElementById(`${pickerId}-hex`);
const rSlider = document.getElementById(`${pickerId}-r`);
const gSlider = document.getElementById(`${pickerId}-g`);
const bSlider = document.getElementById(`${pickerId}-b`);
const rValue = document.getElementById(`${pickerId}-r-value`);
const gValue = document.getElementById(`${pickerId}-g-value`);
const bValue = document.getElementById(`${pickerId}-b-value`);
const confirmBtn = pickerContainer.querySelector('.confirm-btn');
const cancelBtn = pickerContainer.querySelector('.cancel-btn');
// 颜色变量
let h = 251; // 初始色相(对应#0532ff)
let s = 98; // 初始饱和度
let l = 51; // 初始亮度
let savedHexValue = hexInput.value; // 保存初始Hex值
// 移除弹窗的函数
function removePicker() {
container.remove();
}
// 关闭按钮事件
closeBtn.addEventListener('click', removePicker);
cancelBtn.addEventListener('click', removePicker);
// 确定按钮事件
confirmBtn.addEventListener('click', () => {
if (typeof callback === 'function') {
callback(hexInput.value);
}
removePicker();
});
// HSL转RGB
function hslToRgb(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
// RGB转HSL
function rgbToHsl(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const delta = max - min;
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
switch (max) {
case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
case g: h = (b - r) / delta + 2; break;
case b: h = (r - g) / delta + 4; break;
}
h /= 6;
}
h = Math.round(h * 360);
s = Math.round(s * 100);
l = Math.round(l * 100);
return [h, s, l];
}
// 绘制颜色面板
function drawColorPanel() {
const displayWidth = colorPanel.offsetWidth;
const displayHeight = colorPanel.offsetHeight;
const canvasWidth = colorPanel.width;
const canvasHeight = colorPanel.height;
const scaleX = canvasWidth / displayWidth;
const scaleY = canvasHeight / displayHeight;
const ctx = colorPanel.getContext('2d');
const imageData = ctx.createImageData(canvasWidth, canvasHeight);
const data = imageData.data;
for (let y = 0; y < canvasHeight; y++) {
for (let x = 0; x < canvasWidth; x++) {
const sVal = x / canvasWidth;
const lVal = (canvasHeight - y) / canvasHeight;
const [r, g, b] = hslToRgb(h, sVal * 100, lVal * 100);
const i = (y * canvasWidth + x) * 4;
data[i] = r;
data[i + 1] = g;
data[i + 2] = b;
data[i + 3] = 255;
}
}
ctx.putImageData(imageData, 0, 0);
}
// 更新色相滑块位置
function updateHueHandlePosition() {
const height = hueSlider.offsetHeight;
const top = height - (h / 360) * height;
hueHandle.style.top = `${top}px`;
}
// 更新颜色手柄位置
function updateColorHandlePosition() {
const width = colorPanel.offsetWidth;
const height = colorPanel.offsetHeight;
const handleSize = 20;
const x = (s / 100) * width - handleSize / 2;
const y = height - (l / 100) * height - handleSize / 2;
colorHandle.style.left = `${x}px`;
colorHandle.style.top = `${y}px`;
}
// 更新RGB滑块和显示
function updateRGBSliders(r, g, b) {
rSlider.value = r;
rValue.textContent = r;
gSlider.value = g;
gValue.textContent = g;
bSlider.value = b;
bValue.textContent = b;
}
// 更新Hex输入框
function updateHexInput(r, g, b) {
const hex = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
hexInput.value = hex;
savedHexValue = hex;
}
// 从HSL更新界面
function updateFromHSL() {
const [r, g, b] = hslToRgb(h, s, l);
updateRGBSliders(r, g, b);
updateHexInput(r, g, b);
drawColorPanel();
updateColorHandlePosition();
}
// 从RGB更新界面
function updateFromRGB() {
const r = parseInt(rSlider.value);
const g = parseInt(gSlider.value);
const b = parseInt(bSlider.value);
[h, s, l] = rgbToHsl(r, g, b);
updateHueHandlePosition();
drawColorPanel();
updateColorHandlePosition();
updateHexInput(r, g, b);
}
// 从Hex更新界面
function updateFromHex(hex) {
hex = hex.replace(/^#/, '');
if (hex.length === 3) hex = hex.split('').map(c => c + c).join('');
if (hex.length !== 6) hex = '0532ff';
const r = parseInt(hex.slice(0, 2), 16);
const g = parseInt(hex.slice(2, 4), 16);
const b = parseInt(hex.slice(4, 6), 16);
updateRGBSliders(r, g, b);
updateFromRGB();
}
// Hex输入框事件处理
hexInput.addEventListener('focus', () => {
savedHexValue = hexInput.value;
});
hexInput.addEventListener('input', (e) => {
const value = e.target.value;
const filtered = value.replace(/[^#0-9a-fA-F]/g, '');
const hashIndex = filtered.indexOf('#');
if (hashIndex > 0) {
const withoutHash = filtered.replace(/#/g, '');
e.target.value = '#' + withoutHash.substring(0, 6);
} else if (hashIndex === 0) {
e.target.value = filtered.substring(0, 7);
} else {
e.target.value = filtered.substring(0, 6);
}
const currentValue = e.target.value;
if ((currentValue.length === 7 && currentValue.startsWith('#')) ||
(currentValue.length === 6 && !currentValue.startsWith('#'))) {
updateFromHex(currentValue);
}
});
hexInput.addEventListener('blur', () => {
const value = hexInput.value.replace(/^#/, '').toUpperCase();
if (/^[0-9A-F]{6}$/.test(value)) {
hexInput.value = '#' + value;
updateFromHex(hexInput.value);
} else {
hexInput.value = savedHexValue;
}
});
// 监听色相条拖动
let isHueDragging = false;
const handleHueDrag = (e) => {
if (!isHueDragging) return;
e.preventDefault();
const rect = hueSlider.getBoundingClientRect();
let y = e.type.includes('touch')
? e.touches[0].clientY - rect.top
: e.clientY - rect.top;
h = 360 - (y / rect.height) * 360;
h = Math.max(0, Math.min(360, h));
updateHueHandlePosition();
updateFromHSL();
};
hueSlider.addEventListener('mousedown', (e) => { isHueDragging = true; handleHueDrag(e); });
hueSlider.addEventListener('touchstart', (e) => { isHueDragging = true; handleHueDrag(e); });
document.addEventListener('mousemove', handleHueDrag);
document.addEventListener('touchmove', handleHueDrag);
document.addEventListener('mouseup', () => isHueDragging = false);
document.addEventListener('touchend', () => isHueDragging = false);
// 监听颜色面板拖动
let isColorDragging = false;
const handleColorDrag = (e) => {
if (!isColorDragging) return;
e.preventDefault();
const rect = colorPanel.getBoundingClientRect();
let x = e.type.includes('touch')
? e.touches[0].clientX - rect.left
: e.clientX - rect.left;
let y = e.type.includes('touch')
? e.touches[0].clientY - rect.top
: e.clientY - rect.top;
s = (x / rect.width) * 100;
l = ((rect.height - y) / rect.height) * 100;
s = Math.max(0, Math.min(100, s));
l = Math.max(0, Math.min(100, l));
updateColorHandlePosition();
updateFromHSL();
};
colorPanel.addEventListener('mousedown', (e) => { isColorDragging = true; handleColorDrag(e); });
colorPanel.addEventListener('touchstart', (e) => { isColorDragging = true; handleColorDrag(e); });
document.addEventListener('mousemove', handleColorDrag);
document.addEventListener('touchmove', handleColorDrag);
document.addEventListener('mouseup', () => isColorDragging = false);
document.addEventListener('touchend', () => isColorDragging = false);
// 监听RGB滑块变化
rSlider.addEventListener('input', updateFromRGB);
gSlider.addEventListener('input', updateFromRGB);
bSlider.addEventListener('input', updateFromRGB);
// 响应式调整
function adjustForScreenSize() {
const containerWidth = pickerContainer.offsetWidth;
const colorSelection = pickerContainer.querySelector('.color-selection');
if (containerWidth < 350) {
colorSelection.style.flexDirection = 'column';
hueSlider.style.width = '100%';
hueSlider.style.height = '30px';
hueSlider.style.background = 'linear-gradient(to right, hsl(0, 100%, 50%), hsl(60, 100%, 50%), hsl(120, 100%, 50%), hsl(180, 100%, 50%), hsl(240, 100%, 50%), hsl(300, 100%, 50%), hsl(360, 100%, 50%))';
hueHandle.style.width = '12px';
hueHandle.style.height = '40px';
hueHandle.style.left = '0';
hueHandle.style.top = '-5px';
updateHueHandlePosition = () => {
const width = hueSlider.offsetWidth;
const left = (h / 360) * width;
hueHandle.style.left = `${left}px`;
};
} else {
colorSelection.style.flexDirection = 'row';
hueSlider.style.width = '30px';
hueSlider.style.height = '240px';
hueSlider.style.background = 'linear-gradient(to top, hsl(0, 100%, 50%), hsl(60, 100%, 50%), hsl(120, 100%, 50%), hsl(180, 100%, 50%), hsl(240, 100%, 50%), hsl(300, 100%, 50%), hsl(360, 100%, 50%))';
hueHandle.style.width = '40px';
hueHandle.style.height = '12px';
hueHandle.style.left = '-5px';
hueHandle.style.top = '0';
updateHueHandlePosition = () => {
const height = hueSlider.offsetHeight;
const top = height - (h / 360) * height;
hueHandle.style.top = `${top}px`;
};
}
drawColorPanel();
updateHueHandlePosition();
}
// 初始化
updateFromHex(hexInput.value);
updateHueHandlePosition();
drawColorPanel();
updateColorHandlePosition();
adjustForScreenSize();
// 窗口大小变化监听
window.addEventListener('resize', adjustForScreenSize);
// 移除弹窗时清理事件
const originalRemovePicker = removePicker;
removePicker = () => {
window.removeEventListener('resize', adjustForScreenSize);
originalRemovePicker();
};
}
// 获取表情图片URL的函数(基于已有全局变量smilies_array数据)
function getSmileyUrl(smileyKey) {
// 基础URL(公用部分)
const baseUrl = "https://cdn-bbs.mt2.cn/static/image/smiley/";
const smilies_array = window.smilies_array || []
// 遍历所有表情类型(12、5、14)
for (const type in smilies_array) {
if (smilies_array.hasOwnProperty(type)) {
// 遍历该类型下的所有分页
const pages = smilies_array[type];
for (const page in pages) {
if (pages.hasOwnProperty(page)) {
// 遍历当前分页的所有表情
const smilies = pages[page];
for (const smiley of smilies) {
// 找到匹配的表情标识(smiley[1]是表情标识)
if (smiley[1] === smileyKey) {
// 获取文件夹名称(smilies_type中'_类型'对应的文件夹)
const folder = smilies_type[`_${type}`][1];
// 获取文件名(smiley[2]是文件名)
const fileName = smiley[2];
// 拼接完整URL并返回
return `${baseUrl}${folder}/${fileName}`;
}
}
}
}
}
}
// 未找到对应表情时返回null
return null;
}
//bbcode2html,来源于:https://greasyfork.org/zh-CN/scripts/401359-mt%E8%AE%BA%E5%9D%9B
function replaceText(text) {
// 特殊字符转义预处理函数,防止文字被误以为html进行解析
function escapeHtml(str) {
if (typeof str !== 'string') return str; // 非字符串类型直接返回
return str.replace(/[&<>"']/g, (match) => {
const escapeMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return escapeMap[match];
});
}
// 1. 提取[code]标签内容并替换为占位符
const codeBlocks = []; // 存储处理后的代码块HTML
let codeIndex = 0; // 代码块索引
let processedText = escapeHtml(text);// 执行转义预处理
// 提取所有[code]标签内容
processedText = processedText.replace(
/\[code\]([\s\S]*?)\[\/code\]/g,
(match, codeContent) => {
// 提前处理代码块内容(转换为HTML)
let brSplit = codeContent.split("\n");
let content = brSplit.map(line => `
${line}
`).join('');
let codeHtml = `
${content}
`;
// 存储处理后的HTML并返回占位符
const placeholder = `__CODE_BLOCK_${codeIndex}__`;
codeBlocks.push(codeHtml);
codeIndex++;
return placeholder;
}
);
// 2. 处理其他所有标签(此时[code]已被占位符替代,不参与解析)
// 处理[attachimg]标签
let attachimgmatch = processedText.match(/\[attachimg\]([\s\S]+?)\[\/attachimg\]/g);
if (attachimgmatch) {
attachimgmatch.forEach((item) => {
let aimgidMatch = item.match(/\[attachimg\]([\s\S]+?)\[\/attachimg\]/);
let aimg_id = aimgidMatch ? aimgidMatch[1] : "";
let imgElement = document.getElementById(`aimg_${aimg_id}`);
let imgtitle = imgElement ? imgElement.getAttribute("title") : "";
let imgsrc = imgElement ? imgElement.getAttribute("src") : "";
if (!imgsrc) {
imgtitle = "该图片不存在";
}
processedText = processedText.replace(
item,
``
);
});
}
// 处理[url]标签
let url = processedText.match(/\[url(=[\s\S]*?)?\]([\s\S]*?)\[\/url\]/g);
if (url) {
url.forEach((item) => {
let urlMatch = item.match(/\[url(?:=([\s\S]*?))?\]([\s\S]*?)\[\/url\]/);
if (urlMatch) {
let _url_ = urlMatch[1] ? urlMatch[1].trim() : urlMatch[2].trim();
let _url_name_ = urlMatch[1] ? urlMatch[2].trim() : _url_;
processedText = processedText.replace(item, `${_url_name_}`);
}
});
}
// 处理[color]标签
let color = processedText.match(/\[color\=[\s\S]*?\]([\s\S]*?)\[\/color\]/g);
if (color) {
color.forEach((item) => {
let colorMatch = item.match(/\[color=([\s\S]*?)\]([\s\S]*?)\[\/color\]/);
let colorValue = colorMatch ? colorMatch[1] : "";
let colorText = colorMatch ? colorMatch[2] : "";
processedText = processedText.replace(item, `${colorText}`);
});
}
// 处理[backcolor]标签
let backcolor = processedText.match(/\[backcolor\=[\s\S]*?\]([\s\S]*?)\[\/backcolor\]/g);
if (backcolor) {
backcolor.forEach((item) => {
let backcolorMatch = item.match(/\[backcolor=([\s\S]*?)\]([\s\S]*?)\[\/backcolor\]/);
let backcolorValue = backcolorMatch ? backcolorMatch[1] : "";
let backcolorText = backcolorMatch ? backcolorMatch[2] : "";
processedText = processedText.replace(item, `${backcolorText}`);
});
}
// 处理[size]标签
let size = processedText.match(/\[size\=[\s\S]*?\]([\s\S]*?)\[\/size\]/g);
if (size) {
size.forEach((item) => {
let sizeMatch = item.match(/\[size=([\s\S]*?)\]([\s\S]*?)\[\/size\]/);
let sizeValue = sizeMatch ? sizeMatch[1] : "";
let sizeText = sizeMatch ? sizeMatch[2] : "";
processedText = processedText.replace(item, `${sizeText}`);
});
}
// 处理[img]标签
let img = processedText.match(/\[img(|\=[\s\S]+?)\]([\s\S]*?)\[\/img\]/g);
if (img) {
img.forEach((item) => {
let widthInfo = "100%";
let heightInfo = "";
let imgSizeMatch = item.match(/\[img\=([\s\S]+?)\]([\s\S]*?)\[\/img\]/);
if (imgSizeMatch) {
let sizeArr = imgSizeMatch[1].split(",");
widthInfo = sizeArr[0] || "100%";
heightInfo = sizeArr[1] || "";
}
let contentMatch = item.match(/\[img(|\=[\s\S]+?)\]([\s\S]*?)\[\/img\]/);
let content = contentMatch ? contentMatch[2] : "";
processedText = processedText.replace(
item,
``
);
})
}
// 处理[hide]标签(无参数)
let hide = processedText.match(/\[hide\]([\s\S]*?)\[\/hide\]/g);
if (hide) {
hide.forEach((item) => {
let contentMatch = item.match(/\[hide\]([\s\S]*?)\[\/hide\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(
item,
`
本帖隐藏的内容:
${content}
`
);
});
}
// 处理[hide=参数]标签
let hide2 = processedText.match(/\[hide=[\s\S]*?\]([\s\S]*?)\[\/hide\]/g);
if (hide2) {
hide2.forEach((item) => {
let match = item.match(/\[hide=([\s\S]*?)\]([\s\S]*?)\[\/hide\]/);
let otherInfo = match ? match[1].split(",") : [];
let integral = otherInfo.length === 2 ? otherInfo[1] : "";
processedText = processedText.replace(
item,
`
以下内容需要积分高于 ${integral} 才可浏览
`
);
});
}
// 处理[quote]标签
let quote = processedText.match(/\[quote\]([\s\S]*?)\[\/quote\]/g);
if (quote) {
quote.forEach((item) => {
let contentMatch = item.match(/\[quote\]([\s\S]*?)\[\/quote\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(
item,
`
回复 ${content}
`
);
});
}
// 处理[free]标签
let free = processedText.match(/\[free\]([\s\S]*?)\[\/free\]/g);
if (free) {
free.forEach((item) => {
let contentMatch = item.match(/\[free\]([\s\S]*?)\[\/free\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(
item,
`
${content}
`
);
});
}
// 处理[b]标签
let strong = processedText.match(/\[b\]([\s\S]*?)\[\/b\]/g);
if (strong) {
strong.forEach((item) => {
let contentMatch = item.match(/\[b\]([\s\S]*?)\[\/b\]/i);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(item, `${content}`);
});
}
// 处理[u]标签
let xhx = processedText.match(/\[u\]([\s\S]*?)\[\/u\]/g);
if (xhx) {
xhx.forEach((item) => {
let contentMatch = item.match(/\[u\]([\s\S]*?)\[\/u\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(item, `${content}`);
});
}
// 处理[i]标签
let qx = processedText.match(/\[i\]([\s\S]*?)\[\/i\]/g);
if (qx) {
qx.forEach((item) => {
let contentMatch = item.match(/\[i\]([\s\S]*?)\[\/i\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(item, `${content}`);
});
}
// 处理[s]标签
let strike = processedText.match(/\[s\]([\s\S]*?)\[\/s\]/g);
if (strike) {
strike.forEach((item) => {
let contentMatch = item.match(/\[s\]([\s\S]*?)\[\/s\]/);
let content = contentMatch ? contentMatch[1] : "";
processedText = processedText.replace(item, `${content}`);
});
}
// 处理表情标签
let smilies = processedText.match(/\[([\s\S]+?)\]/g);
if (smilies) {
smilies.forEach((item) => {
let smilieSrc = getSmileyUrl(item);
if (smilieSrc) {
processedText = processedText.replace(
item,
``
);
}
});
}
// 处理[media]标签
let media = processedText.match(/\[media(=[\s\S]*?)?\]([\s\S]*?)\[\/media\]/g);
if (media) {
media.forEach((item) => {
let mediaMatch = item.match(/\[media(?:=([\s\S]*?))?\]([\s\S]*?)\[\/media\]/);
if (mediaMatch) {
// 忽略对:[media]、[media=宽,高]、[media=类型,宽,高] 等格式的解析
// 解析媒体链接并过滤非法字符
let mediaUrl = mediaMatch[2].trim();
mediaUrl = mediaUrl.replace(/[<>"]/g, ''); // 简单XSS过滤
let mediaHtml = '';
// 适配主流视频平台(优先处理B站,兼容b23.tv短链接)
if (mediaUrl) {
// B站(bilibili.com、b23.tv)
if (mediaUrl.includes('bilibili.com') || mediaUrl.includes('b23.tv')) {
// 解析b23.tv短链接中的BV号/AV号(需实际请求或正则提取,这里简化处理)
let bvidMatch = mediaUrl.match(/BV(\w+)|av(\d+)/i) || mediaUrl.match(/b23\.tv\/(\w+)/i);
let aid = '', bvid = '';
if (bvidMatch) {
if (bvidMatch[1] && bvidMatch[1].startsWith('V')) {
bvid = bvidMatch[1]; // BV号
} else if (bvidMatch[2]) {
aid = bvidMatch[2]; // AV号
} else if (bvidMatch[1]) {
// b23.tv短链接后缀(需实际跳转获取真实BV/AV,这里简化为直接使用)
bvid = bvidMatch[1];
}
}
// 构造B站播放器链接(支持BV号和AV号)
let playerSrc = '';
if (bvid) {
playerSrc = `https://player.bilibili.com/player.html?bvid=BV${bvid}`;
} else if (aid) {
playerSrc = `https://player.bilibili.com/player.html?aid=${aid}`;
}
if (playerSrc) {
mediaHtml = ``;
}
}
// 经测试,论坛不支持优酷视频,此处预览仅供参考
// 适配优酷链接(含PC端、移动端、带参数)
else if (mediaUrl.includes('youku.com')) {
// 标准化URL:移除Query String,统一处理路径
let cleanUrl = mediaUrl.split('?')[0]; // 去掉?后的参数
// 正则匹配:支持PC端(/v_show/id_xxx.html)、移动端(/video/id_xxx)、ID含等号/字母/数字/下划线/短横线
let youkuMatch = cleanUrl.match(/id[_\/]([a-zA-Z0-9_\-=]+)(?:\.html)?/i);
if (youkuMatch) {
let vid = youkuMatch[1];
// 优酷新版iframe嵌入地址(兼容带等号的ID)
mediaHtml = ``;
}
}
// 腾讯视频(v.qq.com)
else if (mediaUrl.includes('v.qq.com')) {
let qqMatch = mediaUrl.match(/vid=([a-zA-Z0-9_\-]+)|\/([a-zA-Z0-9_\-]+)\.html/i);
let vid = qqMatch ? (qqMatch[1] || qqMatch[2]) : '';
if (vid) {
mediaHtml = ``;
}
}
// 通用视频格式(MP4/WEBM/FLV)
else if (/\.(mp4|webm|flv)$/i.test(mediaUrl)) {
mediaHtml = ``;
}
// 通用音频格式(MP3/WAV/OGG)
else if (/\.(mp3|wav|ogg)$/i.test(mediaUrl)) {
mediaHtml = ``;
}
}
// 无匹配平台时返回原链接,否则返回解析后的HTML
let replaceContent = mediaHtml || `${mediaUrl}`;
processedText = processedText.replace(item, replaceContent);
}
});
}
// 处理[email]标签
let email = processedText.match(/\[email(=[\s\S]*?)?\]([\s\S]*?)\[\/email\]/g);
if (email) {
email.forEach((item) => {
let emailMatch = item.match(/\[email(?:=([\s\S]*?))?\]([\s\S]*?)\[\/email\]/);
if (emailMatch) {
let _email_ = emailMatch[1] ? emailMatch[1].trim() : emailMatch[2].trim();
let _email_name_ = emailMatch[1] ? emailMatch[2].trim() : _email_;
processedText = processedText.replace(item, `${_email_name_}`);
}
});
}
// 处理[align]标签
let align = processedText.match(/\[align=[\s\S]+?\][\s\S]+?\[\/align\]/g);
if (align) {
align.forEach((item) => {
let match = item.match(/\[align=([\s\S]*?)\]([\s\S]+?)\[\/align\]/);
let _align_ = match ? match[1] : "";
let _content_ = match ? match[2] : "";
if (_align_ || _content_) {
processedText = processedText.replace(item, `
${_content_}
`);
}
});
}
// 处理[qq]标签
let qq = processedText.match(/\[qq\][\s\S]*?\[\/qq\]/g);
if (qq) {
qq.forEach((item) => {
let match = item.match(/\[qq\]([\s\S]*?)\[\/qq\]/);
let content = match ? match[1] : "";
processedText = processedText.replace(
item,
``
);
});
}
// 处理表格标签
let td = processedText.match(/\[td\][\s\S]+?\[\/td\]/g);
if (td) {
td.forEach((item) => {
let match = item.match(/\[td\]([\s\S]*?)\[\/td\]/);
let content = match ? match[1] : "";
processedText = processedText.replace(item, `
${content}
`);
});
}
let tr = processedText.match(/\[tr\][\s\S]+?\[\/tr\]/g);
if (tr) {
tr.forEach((item) => {
let match = item.match(/\[tr\]([\s\S]*?)\[\/tr\]/);
let content = match ? match[1] : "";
processedText = processedText.replace(item, `
${content}
`);
});
}
let table = processedText.match(/\[table\][\s\S]+?\[\/table\]/g);
if (table) {
table.forEach((item) => {
let match = item.match(/\[table\]([\s\S]*?)\[\/table\]/);
let content = match ? match[1].replace(/\n/g, "") : "";
processedText = processedText.replace(item, `
${content}
`);
});
}
// 处理[list]标签(支持带参数和无参数两种形式)
let list = processedText.match(/\[list(?:=([\s\S]*?))?\][\s\S]+?\[\/list\]/g);
if (list) {
list.forEach((item) => {
// 匹配带参数或无参数的list标签
let modelMatch = item.match(/\[list(?:=([\s\S]*?))?\]([\s\S]*?)\[\/list\]/);
let listModel = modelMatch ? modelMatch[1] : ""; // 无参数时为""
let content = modelMatch ? modelMatch[2] : "";
let listType = "";
let styleType = ''
// 处理列表类型(新增无参数情况的默认样式)
if (listModel === "a") {
listType = "litype_2"; // 小写字母列表
styleType = 'list-style-type:lower-alpha;'
} else if (listModel === "A") {
listType = "litype_3"; // 大写字母列表
styleType = 'list-style-type:upper-alpha;'
} else if (/[0-9]/.test(listModel)) {
listType = "litype_1"; // 数字列表
styleType = 'list-style-type:decimal;'
} else if (!listModel) {
listType = ""; // 无参数默认列表(圆点)
styleType = 'list-style-type:disc;'
} else {
listType = ""; // 其他参数情况(如*i等)
styleType = 'list-style-type:none;'
}
// 处理列表项
let liSplit = content.split("[*]");
if (liSplit.length > 1) {
// 移除空的第一项(因split导致)
if (liSplit[0].trim() === "") liSplit = liSplit.slice(1);
// 生成li标签
content = liSplit.map(line => `