Compare commits

..
216 Commits
Author SHA1 Message Date
vanishcode 76843a1aef feat: change delete user button color to danger for better visibility 2026-08-04 10:45:52 +08:00
vanishcode 59ad0264db test: enhance passkey support tests and update wrangler config 2026-08-04 10:45:52 +08:00
vanishcode da0b954a17 feat(web): add passkey authentication UI 2026-08-04 10:45:52 +08:00
vanishcode 4e91689026 feat(worker): add passkey authentication 2026-08-04 10:45:52 +08:00
vanishcode 53d24b4f06 chore(worker): enable Node.js compatibility 2026-08-04 10:45:52 +08:00
vitalii.semianchuk 121c13704a fix: null check logic, silenced flag inversion, sequential query perf
- role-service had if (!userIds && userIds.length === 0) which crashes
  with TypeError when userIds is null — changed && to ||
- oauth-service was setting silenced based on the already-inverted
  active value instead of the original silenced field from the API
- email-service was awaiting three queries individually then passing
  the resolved values to Promise.all, making them run sequentially
  instead of in parallel
2026-08-02 14:15:06 +08:00
eoao 43ed02392e feat: improve add user dialog 2026-06-09 19:20:37 +08:00
eoao 4ea9527cb7 revert: add login background darken factor 2026-06-09 17:41:36 +08:00
eoao 4bf5c97017 style: align dividers 2026-06-09 17:05:02 +08:00
eoao 82ae8f07d5 chore: reduce scheduled tasks 2026-06-09 17:04:46 +08:00
eoao 679cb4c035 fix: mask Telegram bot token 2026-05-23 06:53:52 +08:00
eoao 629a32c651 fix: validation not working 2026-05-23 04:32:33 +08:00
eoao 80a0cb65a5 ci: restore automatic database creation
This reverts commit edba6b80d3.
2026-05-12 21:55:00 +08:00
eoao a84b2ae469 style: reorder personalization settings options 2026-05-12 22:14:17 +08:00
Esing 22c35119c0 feat: add login background darken factor 2026-05-12 22:12:02 +08:00
eoao edba6b80d3 ci: remove automatic database creation 2026-05-12 13:21:06 +08:00
呼乎户 6ae3d43f9e fix: rename CF_EMAIL to CLOUDFLARE_EMAIL in deployment workflow (#364) 2026-05-12 12:58:27 +08:00
eoao 40fc68e56c fix: fix missing fields in database initialization 2026-05-12 12:41:22 +08:00
eoao e68099edb3 fix: update Cloudflare email sending default status 2026-05-10 18:36:22 +08:00
eoao fdf4259701 feat: convert attachment path to ArrayBuffer 2026-05-10 18:33:54 +08:00
eoao f6eaf6d0fd feat: use ArrayBuffer for attachment sending 2026-05-10 17:43:54 +08:00
eoao 421a963a92 ci: add environment variables 2026-05-10 17:34:12 +08:00
eoao 53c4db3bc9 chore: normalize configuration casing 2026-05-10 17:26:23 +08:00
eoao f227bd75ca feat: add Cloudflare email sending to system settings 2026-05-10 17:23:12 +08:00
eoao 23b1d5e6be fix: resolve worker attachment sending failure 2026-05-10 14:11:23 +08:00
eoao 3a0ded3d01 ci: update nodejs version 2026-05-10 13:54:56 +08:00
eoao db0e930bd1 feat: add Cloudflare Email Sending support 2026-05-10 13:42:03 +08:00
eoao 1f898e8f65 chore: update wrangler 2026-05-10 13:36:33 +08:00
eoao 421dc3b10a chore: add comments to configuration 2026-05-10 13:22:16 +08:00
eoao fbf889ab12 ci: add environment variables 2026-05-10 13:16:36 +08:00
eoao 44bbf9c3da feat: add analytics data cache toggle 2026-05-10 13:12:22 +08:00
eoao 80242d5c24 feat: add scheduled cache refresh task configuration 2026-05-10 12:58:02 +08:00
eoao 09516c9cc8 feat: add analytics page data caching 2026-05-10 12:56:02 +08:00
eoao 84e7e2e9d8 fix: resolve TG message character limit overflow 2026-05-10 01:02:02 +08:00
eoao 65680c46fd feat: update verification code recognition logic 2026-05-10 00:58:11 +08:00
eoao ead8f9e2b8 feat: optimize verification code recognition strategy 2026-05-10 00:55:27 +08:00
eoao 7423a25fd6 feat: update verification code recognition to 8 digits 2026-05-10 00:48:31 +08:00
eoao 5f45563c49 chore: update README.md 2026-05-10 00:46:55 +08:00
eoao a45324a742 chore: update version 2026-05-10 00:44:22 +08:00
eoao ac2c17e31c chore: remove default AI model from config file 2026-05-10 00:29:33 +08:00
eoao 6189a91000 fix: resolve system settings display refresh bug 2026-05-10 00:28:32 +08:00
eoao a46192b214 feat: display verification code in frontend email list 2026-05-10 00:26:45 +08:00
eoao 92e18ea683 feat: AI verification code recognition settings 2026-05-10 02:17:42 +08:00
eoao baa70a863c feat: add Telegram message verification code copy 2026-05-10 01:15:50 +08:00
eoao d48b139aed feat: AI-powered email verification code recognition 2026-05-10 00:26:45 +08:00
eoao c96e349fda chore: update dependencies 2026-05-09 00:23:22 +08:00
eoao 984b734d4c feat: hide login domain 2026-05-09 00:18:54 +08:00
eoao a1c47d73e8 style: style optimization 2026-05-09 00:12:44 +08:00
eoao 1b95707819 fix: permission vulnerability 2026-05-08 23:58:03 +08:00
eoao c14615d1ef style: style optimization 2026-05-08 23:55:56 +08:00
eoao 8bf9adbd13 feat: add blacklist description text 2026-05-08 23:44:22 +08:00
eoao 24f271a1ed feat: add Chinese-English language toggle 2026-05-08 23:35:05 +08:00
eoao f0bf6da963 fix: blacklist domain check 2026-05-08 23:26:22 +08:00
eoao 522db4ee3a fix: pin pnpm version to 9 to resolve CI setup error 2026-05-08 22:57:02 +08:00
eoao b60add170c feat: add email blacklist filtering 2026-05-08 22:40:17 +08:00
eoao 154f536c61 style: update initial loading indicator 2026-05-07 02:20:27 +08:00
eoao e92a44b069 fix: repair failed user check for email favorites 2026-04-06 23:03:58 +08:00
eoao 980b62f6ac 新增 github action 部署变量
x
2026-03-21 23:27:50 +08:00
eoao af18ad3562 新增设置登录项目github图标隐藏 2026-03-21 23:19:36 +08:00
eoao 9ab766879e 修复编辑器select组件样式污染 2026-02-11 15:58:18 +08:00
eoao dafb8dda01 修复TG一些邮件解析为空和格式优化 2026-02-08 10:02:33 +08:00
eoao 216f7272d8 修改一些已知BUG
优化站内发件无需第三方

修改一些已知BUG
2026-02-08 00:40:52 +08:00
eoao 24e37288e5 新增邮件转发 2026-02-07 12:24:45 +08:00
eoao ee1b76cd1b 新增站内发送权限 2026-02-07 08:40:19 +08:00
eoao 5da6b44ad6 优化站内发件无需第三方 2026-02-07 20:02:01 +08:00
eoao 3ea917a572 修复用户删除状态导致的收件异常 2026-02-03 21:14:43 +08:00
eoao 5d2b49ff70 修复可能导致收件失败问题回退优化自动刷新 2026-01-28 22:13:23 +08:00
eoao bfb896bae6 删除 GitHub Actions 设置邮件接收步骤 2026-01-24 00:06:00 +08:00
eoao 1d4979bc43 删除新邮件底部弹窗 2026-01-23 16:58:59 +08:00
eoao 9f5076e3b5 新增更多部署错误提示 2026-01-23 00:22:00 +08:00
eoao d7c3cf27b0 新增邮件和用户列表右键菜单 2026-01-22 23:50:00 +08:00
eoao 31dbf1a9e6 新增批量删除用户 2026-01-22 22:22:00 +08:00
eoao 8a47418c91 新增邮箱列表置顶排序 2026-01-20 21:46:00 +08:00
ifsheldon cbae3ffbdf fix: Handle HTTP redirects in workflow curl requests (#240)
* update workflow

* fix workflow
2026-01-22 15:41:07 +08:00
eoao d3235bdd17 优化降低所需配置简化部署 2026-01-19 19:22:00 +08:00
eoao ec3bd76666 优化邮件列表改为虚拟滚动列表 2026-01-15 19:46:00 +08:00
eoao 5c11d16bdf 新增全部邮件自动刷新 2026-01-14 00:00:37 +08:00
eoao 7694278045 优化自动刷新邮件请求次数 2026-01-12 22:33:00 +08:00
eoao 97b2be8d25 优化部署流程和变量错误提示 2026-01-11 21:06:00 +08:00
eoao dc38535ea8 修复账号ID导致的BUG 2026-01-07 22:02:00 +08:00
eoao 693e3aa9f1 修改README 2026-01-02 23:09:00 +08:00
eoao 6f83a440dc 修复附件和背景保存异常 2026-01-03 00:01:47 +08:00
eoao e723af4229 修复邮件接收异常 2026-01-01 19:16:43 +08:00
eoao 88a4b9dff5 KV存储改为默认开启
保存

保存
2026-01-01 15:11:41 +08:00
eoao 69632c8cc6 修改自动刷新邮件失效 2025-12-10 23:09:00 +08:00
eoao 9ef1edb341 修改README.md 2025-12-07 22:09:00 +08:00
eoao dcd9e9c95f 新增显示所有邮箱邮件 2025-12-07 22:08:00 +08:00
eoao 70923fee59 修复切换邮箱自动刷新错乱 2025-11-23 13:29:11 +08:00
eoao c61bda1828 修复其他列表显示已读图标问题 2025-11-18 23:22:00 +08:00
eoao 0c4be2b723 新增自动刷新邮件弹窗通知 2025-11-18 22:44:00 +08:00
eoao 9a089da3b7 新增邮件显示已读未读功能 2025-11-18 22:08:00 +08:00
eoao 0395992b5b 新增注册邮箱名自定义字符过滤 2025-11-16 12:56:38 +08:00
eoao 025dc1fbdb 设置登录背景加载超时时间 2025-11-09 08:08:00 +08:00
eoao 56b42d29b3 新增设置注册邮箱前缀最小位数 2025-11-08 22:25:00 +08:00
eoao a343a4a08f 修复 Delete workflow 限不足时报错 2025-11-08 21:44:00 +08:00
eoao 8c6cdd0279 新增 LinuxDo Oauth2 登录 2025-11-08 21:33:00 +08:00
eoao 3cf347ad7a 修改README.md 2025-11-06 22:59:00 +08:00
eoao 6cd3dcb7ef 发送邮件正文图片链接改为内置附件 2025-11-06 22:55:00 +08:00
eoao 4d00f0aeb7 修复<>字符导致TG消息发送失败 2025-10-25 08:35:00 +08:00
eoao 37cad0f281 修复一些附件文件名无后缀导致报错 2025-10-25 08:22:00 +08:00
eoao a4a1db22e8 新增TG自定义是否显示文本消息 2025-10-23 23:55:00 +08:00
eoao 7980e6a444 修复TG一些邮件和图片不显示 2025-10-23 23:11:00 +08:00
eoao d5a5bf8c29 修改README文档 2025-10-23 17:58:27 +08:00
eoao aded699314 新增自定义显示TG邮件消息内容 2025-10-23 00:22:45 +08:00
eoao 57638aa8e1 新增TG邮件查看HTML 2025-10-22 21:33:45 +08:00
eoao fdf9e95d67 新增KV数据库存储附件 2025-10-21 20:45:20 +08:00
eoao dad4a22356 修复发送成功无法记录联系人 2025-10-18 22:32:00 +08:00
eoao 083dc8daab 修复无法接收无人邮件 2025-10-13 00:22:00 +08:00
eoao 1b441774a4 新增最近联系人功能 2025-10-10 22:22:00 +08:00
eoao 8ee140743a 邮件内容样式优化 2025-09-27 00:22:00 +08:00
eoao ad36be00a2 补充修复一些邮件接收异常 2025-09-26 17:55:38 +08:00
eoao 46cfd61b12 修复一些邮件接收异常 2025-09-26 00:10:17 +08:00
eoao 88da574dfb Github Action 支持无R2, 自动获取初始化地址 2025-09-25 22:23:00 +08:00
eoao 172f34dfe3 图标改成项目内置 2025-09-24 00:22:00 +08:00
eoao 86fddf4a5d 修复邮件数量统计错误 2025-09-22 21:32:23 +08:00
eoao 82bd308d56 新增全部用户查看删除邮箱 2025-09-21 19:20:00 +08:00
eoao 457304eafb 修复请求影响延迟 2025-09-14 11:49:37 +08:00
eoao b21b63aea7 修复删除S3文件没有MD5异常 2025-09-06 21:33:30 +08:00
eoao 062c9f7dff 修复浏览器无法初始化地址 2025-09-06 19:24:14 +08:00
eoao 8b74656c83 修复Turnstile加载失败 2025-09-06 12:01:40 +08:00
eoao 2c6803475b PWA注册改为异步避免影响加载速度 2025-09-05 17:26:08 +08:00
eoao 25a27ec038 修复批量删除邮件时漏掉附件 2025-09-05 16:24:54 +08:00
eoao b046f49ea2 修复使用S3有时无法接收邮件 2025-09-05 16:23:46 +08:00
梦念逍遥 2fd34b407e 修复npm缓存错误 (#112) 2025-09-04 12:35:21 +08:00
eoao 613582c13e 修改版本和图片域名转换 2025-09-04 01:22:00 +08:00
eoao 4d31dbc9c4 邮件拒收退回 2025-09-04 01:01:00 +08:00
eoao c72230e812 修改报错提示 2025-09-04 00:40:00 +08:00
eoao 2390143dc6 禁用Workbox 2025-09-04 00:29:34 +08:00
eoao b4954e948b 优化多个地方 2025-09-03 08:31:44 +08:00
eoao 97a7950808 修改图标和权限*拦截邮件 2025-09-01 08:22:22 +08:00
eoao 6f25991ff2 删除静态资源转为部署时自动打包 2025-08-31 12:07:21 +08:00
eoao 86a80900c1 新增支持s3协议对象存储 2025-08-31 12:04:19 +08:00
eoao 562528e968 新增pwa 2025-08-30 07:36:38 +08:00
eoao 45994c24e3 添加静态资源 2025-08-28 22:28:00 +08:00
eoao ce09d4ac46 饼状图不在统计noreply 2025-08-28 22:23:00 +08:00
eoao 6219a1474e 部署报错详细提示 2025-08-28 22:22:00 +08:00
eoao 375613c219 新增批量删除邮件 2025-08-28 22:11:00 +08:00
eoao 344389cf0f 腾讯EdgeOne部署配置 2025-08-27 17:35:11 +08:00
eoao fc0a5564f4 添加配置浏览器缓存所有静态资源 2025-08-26 23:44:22 +08:00
eoao 00fd14ad88 修改登录背景图片加载显示 2025-08-26 23:34:22 +08:00
eoao 01cef2355d 邮件列表加载动画优化和打包拆分 2025-08-26 23:10:55 +08:00
eoao de0bb288ec 修复登录界面首次进入加载背景异常 2025-08-22 22:02:00 +08:00
eoao 799cc4277f 修复浏览器刷新时有黑影闪过 2025-08-22 19:03:53 +08:00
eoao 0eae1bd9b8 修复写邮件按钮位置靠右 2025-08-22 17:22:40 +08:00
eoao 8cd75868bc 修复全部邮件权限无效问题 2025-08-22 01:05:00 +08:00
eoao ff8ba81661 新增深色模式 2025-08-22 00:13:56 +08:00
eoao d3325f0fe3 Update issue templates 2025-08-19 16:01:41 +08:00
eoao ea8ad14049 修复切换语言时间格式没有变化 2025-09-21 19:26:50 +08:00
LLLLLLiuleiandliulei 6dc126d3b0 对字符串domain尝试转换为json (#79)
Co-authored-by: liulei <[email protected]>
2025-08-13 01:53:10 +08:00
eoao ab977ae64a API Token 有效时间改成无限 2025-08-11 10:44:33 +08:00
eoao 181dcd87a3 修复其他语言下英语样式仍是中文的 2025-08-10 20:32:57 +08:00
eoao 6a11324ef9 修复login_domain字段可能初始化失败 2025-08-10 19:27:41 +08:00
eoao 46127a8d67 新增支持API添加用户,查询邮件 2025-08-10 11:37:46 +08:00
eoao 2437ff4599 修复超级管理员账号会被禁用发件 2025-08-04 17:58:06 +08:00
eoao 658c1776d5 新增公告弹窗和无人收件开关 2025-08-03 21:03:54 +08:00
eoao 3a40cfc63b 新增规则触发人机验证和加载失败提示 2025-07-29 20:00:00 +08:00
eoao d03b7ca21d 修复无法自适应浏览器语言 2025-07-29 14:09:00 +08:00
eoao 12833cd901 新增权限域名限制和链接背景上传 2025-07-26 23:11:00 +08:00
Abner 0e86b93e0c 修复 wrangler 配置文件占位符替换时序问题 (#57)
- 移除 telemetry 命令的配置文件参数避免在替换前读取配置
- 重新组织工作流步骤,确保配置文件占位符替换在所有 wrangler 命令之前执行
- 添加调试信息显示 R2_BUCKET_NAME 值和配置文件内容
- 修复 R2 bucket name 验证错误
- 调整数据库初始化等待时间从 10 秒增加到 15 秒
2025-07-27 10:23:21 +08:00
eoao 775d976f10 修改文档和版本号 2025-07-24 18:05:00 +08:00
eoao 7267f03482 修复注册码权限无效bug 2025-07-22 23:33:46 +08:00
eoao bbcff4908d 新增中英文切换 2025-07-22 22:02:23 +08:00
eoao 249edb9e19 修改注册密码长度限制 2025-07-18 21:18:12 +08:00
eoao 196fb4a6b5 修改版本号 2025-07-18 01:16:44 +08:00
eoao bd28de5522 修复请求响应过慢 2025-07-16 20:07:39 +08:00
eoao 7762670c78 修复可选注册码报错
(cherry picked from commit b40c62f94d6e33814db1498534d585b5b8d4303f)
2025-07-16 20:38:00 +08:00
eoao 12e39c5f9c 修复注册密码提示问题 2025-07-16 20:30:00 +08:00
eoao 254325431b 新增注册码、草稿箱、权限拦截邮件、发件菜单隐藏 2025-07-15 20:09:56 +08:00
eoao 7e5a383bc6 修复gmail附件和回复编辑器图片不显示 2025-07-10 09:00:14 +08:00
Abner f2c12216c8 fix 部署描述及action部署在未配置变量时输出成功提示 2025-07-09 19:26:36 +08:00
eoaoandAbner 1ecce5af21 新增 GitHub Actions 自动化部署
Co-authored-by: Abner <[email protected]>
2025-07-09 16:35:01 +08:00
eoao ab6ea3847e 修复邮件图片移动端无法自适应 2025-07-07 22:43:57 +08:00
eoao 5bc8dfdf00 修复收件内嵌图片只能显示一张 2025-07-07 22:38:56 +08:00
eoao b0daf8f5fd 优化移动端404图片大小 2025-07-05 23:28:17 +08:00
eoao cfebeb1fda 修复邮件列表截取文字加载图片导致大量爆红 2025-07-04 21:11:41 +08:00
eoao fc249dde6e 删除配置 2025-07-04 20:22:59 +08:00
eoao 3385635b26 修改版本号 2025-07-04 20:16:33 +08:00
MengNianxiaoyao e426ee7cbe 修正错误文本
(cherry picked from commit 773f0cdcbb05eb27eeeb73e86d18a4f8e44cdb57)
2025-07-04 18:55:01 +08:00
eoao e2aeaf3783 优化登录身份缓存机制 2025-07-04 20:02:00 +08:00
eoao 7a0711071d 截取邮箱名做发件名防止出现空名 2025-06-30 22:44:30 +08:00
eoao 22b56781d5 修复星标邮件列表不同步和图表空数据不为0 2025-06-30 15:27:59 +08:00
eoao 52e5915d93 调整移动动端空状态大小、加载时标题改成空 2025-06-29 22:01:39 +08:00
eoao c72213b97d 修复邮件列表发件无法搜索和不显示邮箱 2025-06-29 14:25:39 +08:00
eoao 33141fe7dd 邮件详情样式优化和查询优化 2025-06-29 11:57:53 +08:00
eoao bd244e48ec 修复纯文本邮件文字不会自动行 2025-06-28 22:01:42 +08:00
eoao cd8767c1ce 修改版本号 2025-06-28 21:43:24 +08:00
eoao 99bbdb3df1 修复某些情况取消星标不同步 2025-06-28 21:35:43 +08:00
eoao 2bef5ee0f6 新增点击复制邮箱功能 2025-06-28 20:22:52 +08:00
eoao 136c0496b8 新增tg和第三方邮件转发 2025-06-28 13:35:37 +08:00
eoao 010e0451ab 优化编辑器表情底部空白和table不显示线 2025-06-25 19:30:07 +08:00
eoao 6af78c21ea 饼状图不再统计空名 2025-06-25 11:46:34 +08:00
eoao 9aa8d3a410 新增无人收件和支持一些字符邮箱 2025-06-25 10:39:21 +08:00
eoao 621859c454 修复富文本居中图片后内容页还是靠左 2025-06-21 08:36:41 +08:00
eoao f9956507fe 修复数据可视化最后一天为0 2025-06-20 00:52:17 +08:00
eoao 7ec485907a 新增打包文件 2025-06-17 09:23:00 +08:00
eoao bb6440b387 设置柱状图默认值 2025-06-17 09:23:00 +08:00
eoao b6142483ed 修改版本号 2025-06-17 09:21:00 +08:00
eoao 605829f180 新增邮件群发和数据可视化 2025-06-17 09:20:00 +08:00
eoao ea309f9171 修改图片压缩规则,优化样式 2025-06-06 19:20:59 +08:00
eoao 8054c0390c 修复透明度覆盖影响设置问题,优化样式 2025-06-06 00:23:31 +08:00
eoao 1c40dc8338 修复星标不能查看,附件等多个bug,优化样式 2025-06-05 23:09:05 +08:00
eoao cdcd22962f 修复邮件正文不是utc+8时间 2025-06-05 15:02:57 +08:00
eoao 9f9dc3d019 修改文档和修改项目错字 2025-06-05 08:53:24 +08:00
eoao 0692f8ec5e 修复无法接收邮件问题 2025-06-04 22:12:54 +08:00
eoao dac0383bab 修改登录页面 2025-06-04 00:20:53 +08:00
eoao 3190b47bb9 修复自动刷新问题 2025-06-03 13:29:52 +08:00
eoao 9b8598da57 修复人机验证不显示问题 2025-06-03 12:58:33 +08:00
eoao 462bb132e2 修复内容显示问题 2025-06-03 07:53:22 +08:00
eoao 2341d14b2d 新增邮件发送和管理员功能 2025-05-29 17:38:50 +08:00
eoao de742d31e7 添加教程,更新打包文件
删除描述
2025-04-29 04:49:33 +08:00
eoao 59c5be2623 修复a标签变成黑色问题 2025-04-27 17:19:37 +08:00
eoao aa02573217 修改错字 2025-04-27 11:47:53 +08:00
eoao ba2a56e1f0 修改配置 2025-04-27 09:32:25 +08:00
eoao 741f839d09 添加说明和MIT 2025-04-27 09:09:43 +08:00
eoao ba3442ccb1 添加打包文件 2025-04-26 17:33:50 +08:00
eoao 24ba4772e6 保存 2025-04-26 17:24:39 +08:00
397 changed files with 24473 additions and 21756 deletions
+10
View File
@@ -0,0 +1,10 @@
---
name: Bug report
about: Create a report to help us improve
title: "[Bug] "
labels: bug
assignees: ''
---
+10
View File
@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[Feature request] "
labels: enhancement
assignees: ''
---
+10
View File
@@ -0,0 +1,10 @@
---
name: Need Help
about: Create a issue to find help
title: "[Help] "
labels: help wanted
assignees: ''
---
+271
View File
@@ -0,0 +1,271 @@
name: 🚀 Deploy cloud-mail to Cloudflare Workers
on:
push:
branches: [ main ]
paths:
- "mail-worker/**"
- "mail-vue/**"
workflow_dispatch:
jobs:
Deploy-cloud-mail:
name: 🏗️ Build and Deploy
runs-on: ubuntu-latest
env:
NAME: ${{ secrets.NAME || vars.NAME || 'cloud-mail' }}
CUSTOM_DOMAIN: ${{ secrets.CUSTOM_DOMAIN || vars.CUSTOM_DOMAIN }}
DOMAIN: ${{ secrets.DOMAIN || vars.DOMAIN }}
ADMIN: ${{ secrets.ADMIN || vars.ADMIN }}
JWT_SECRET: ${{ secrets.JWT_SECRET || vars.JWT_SECRET }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN || vars.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || vars.CLOUDFLARE_ACCOUNT_ID }}
D1_DATABASE_ID: ${{ secrets.D1_DATABASE_ID || vars.D1_DATABASE_ID }}
KV_NAMESPACE_ID: ${{ secrets.KV_NAMESPACE_ID || vars.KV_NAMESPACE_ID }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME || vars.R2_BUCKET_NAME }}
PROJECT_LINK: ${{ secrets.PROJECT_LINK || vars.PROJECT_LINK }}
AI_MODEL: ${{ secrets.AI_MODEL || vars.AI_MODEL || '@cf/meta/llama-3.1-8b-instruct' }}
CLOUDFLARE_EMAIL: ${{ secrets.CF_EMAIL || vars.CF_EMAIL || false }}
ANALYSIS_CACHE: ${{ secrets.ANALYSIS_CACHE || vars.ANALYSIS_CACHE || false }}
LINUXDO_CLIENT_ID: ${{ secrets.LINUXDO_CLIENT_ID || vars.LINUXDO_CLIENT_ID }}
LINUXDO_CLIENT_SECRET: ${{ secrets.LINUXDO_CLIENT_SECRET || vars.LINUXDO_CLIENT_SECRET }}
LINUXDO_CALLBACK_URL: ${{ secrets.LINUXDO_CALLBACK_URL || vars.LINUXDO_CALLBACK_URL }}
LINUXDO_SWITCH: ${{ secrets.LINUXDO_SWITCH || vars.LINUXDO_SWITCH }}
outputs:
worker_url: ${{ steps.deploy.outputs.worker_url }}
steps:
- name: 🚚 检出代码仓库 / Checkout repository
uses: actions/checkout@v4
- name: ⚙ 设置 pnpm / Set up pnpm
uses: pnpm/[email protected]
with:
version: 9
- name: ⚙ 设置 Node.js / Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "./mail-worker/pnpm-lock.yaml"
- name: 📦 安装依赖 / Install dependencies
run: pnpm install --frozen-lockfile
working-directory: ./mail-worker
- name: 📡 禁用 Wrangler 遥测 / Disable wrangler telemetry
working-directory: ./mail-worker
run: pnpm wrangler telemetry disable
- name: 🛠️ 设置环境 / Set up environment
working-directory: ./mail-worker
run: |
echo "🔐 Starting environment setup..."
if [ -z "$JWT_SECRET" ] || grep -q '[?%#/\\]' <<< "$JWT_SECRET"; then
echo "❌ JWT_SECRET variable is empty or contains invalid characters (?, %, #, /, \\)."
exit 1
fi
if ! jq -e 'type == "array"' <<< "$DOMAIN" ; then
echo "❌ DOMAIN variable must be a JSON array (e.g., [\"example.com\"])."
exit 1
fi
if [ -z "$ADMIN" ]; then
echo "❌ ADMIN variable cannot be empty."
exit 1
fi
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then
echo "❌ CLOUDFLARE_ACCOUNT_ID variable cannot be empty."
exit 1
fi
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "❌ CLOUDFLARE_API_TOKEN variable cannot be empty."
exit 1
fi
if [ -z "$CUSTOM_DOMAIN" ]; then
echo "::warning:: CUSTOM_DOMAIN variable is not set."
fi
CONFIG_FILE="wrangler-action.toml"
if [ -z "$R2_BUCKET_NAME" ]; then
sed -i '/\[\[r2_buckets\]\]/,/^$/d' "$CONFIG_FILE"
fi
if [ -z "$PROJECT_LINK" ]; then
sed -i '/^project_link = /d' "$CONFIG_FILE"
fi
if [ -z "$LINUXDO_CLIENT_ID" ] || [ -z "$LINUXDO_CLIENT_SECRET" ]; then
sed -i '/^linuxdo_client_id = /,/^linuxdo_switch = /d' "$CONFIG_FILE"
fi
if [ -z "$CUSTOM_DOMAIN" ]; then
sed -i '/\[\[routes\]\]/,/^$/d' "$CONFIG_FILE"
fi
if [ "$(printf '%s' "$CLOUDFLARE_EMAIL" | tr '[:upper:]' '[:lower:]')" = "true" ]; then
cat >> "$CONFIG_FILE" <<'EOF'
[[send_email]]
name = "email"
EOF
fi
sed -i "s|\${NAME}|${NAME}|g" "$CONFIG_FILE"
sed -i "s|\${CUSTOM_DOMAIN}|${CUSTOM_DOMAIN}|g" "$CONFIG_FILE"
sed -i "s|\"\${DOMAIN}\"|${DOMAIN}|g" "$CONFIG_FILE"
sed -i "s|\${ADMIN}|${ADMIN}|g" "$CONFIG_FILE"
sed -i "s|\${JWT_SECRET}|${JWT_SECRET}|g" "$CONFIG_FILE"
sed -i "s|\${R2_BUCKET_NAME}|${R2_BUCKET_NAME}|g" "$CONFIG_FILE"
sed -i "s|\${PROJECT_LINK}|${PROJECT_LINK}|g" "$CONFIG_FILE"
sed -i "s|\${ANALYSIS_CACHE}|${ANALYSIS_CACHE}|g" "$CONFIG_FILE"
sed -i "s|\${AI_MODEL}|${AI_MODEL}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CLIENT_ID}|${LINUXDO_CLIENT_ID}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CLIENT_SECRET}|${LINUXDO_CLIENT_SECRET}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CALLBACK_URL}|${LINUXDO_CALLBACK_URL}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_SWITCH}|${LINUXDO_SWITCH}|g" "$CONFIG_FILE"
echo "✅ Environment setup completed."
- name: ⚡ 设置KV数据库 / Set up KV database
working-directory: ./mail-worker
run: |
CONFIG_FILE="wrangler-action.toml"
if [ -n "$KV_NAMESPACE_ID" ]; then
sed -i "s|\${KV_NAMESPACE_ID}|${KV_NAMESPACE_ID}|g" "$CONFIG_FILE"
echo "✅ Using the database from environment variables."
exit 0
fi
echo "🔍 Checking if the database exists..."
set +e
KV_LIST=$(pnpm wrangler kv namespace list 2>&1)
STATUS=$?
set -e
if [ $STATUS -ne 0 ]; then
echo "$KV_LIST"
exit 1
fi
if echo "$KV_LIST" | jq -e ".[] | select(.title == \"$NAME\")" >/dev/null; then
echo "✅ Database $NAME already exists."
KV_ID=$(echo "$KV_LIST" | jq -r ".[] | select(.title == \"$NAME\") | .id")
echo "KV_NAMESPACE_ID: $KV_ID"
else
echo "⚠️ Database $NAME does not exist. Starting creation..."
pnpm wrangler kv namespace create $NAME
KV_LIST=$(pnpm wrangler kv namespace list)
KV_ID=$(echo "$KV_LIST" | jq -r ".[] | select(.title == \"$NAME\") | .id")
fi
sed -i "s|\${KV_NAMESPACE_ID}|$KV_ID|g" "$CONFIG_FILE"
echo "✅ Setup completed."
- name: 🐬 设置D1数据库 / Set up D1 database
working-directory: ./mail-worker
run: |
CONFIG_FILE="wrangler-action.toml"
if [ -n "$D1_DATABASE_ID" ]; then
sed -i "s|\${D1_DATABASE_ID}|${D1_DATABASE_ID}|g" "$CONFIG_FILE"
echo "✅ Using the database from environment variables."
exit 0
fi
echo "🔍 Checking if the database exists..."
set +e
DB_LIST=$(pnpm wrangler d1 list --json 2>&1)
STATUS=$?
set -e
if [ $STATUS -ne 0 ]; then
echo "$DB_LIST"
exit 1
fi
if echo "$DB_LIST" | jq -e ".[] | select(.name == \"$NAME\")" >/dev/null; then
echo "✅ Database $NAME already exists."
D1_ID=$(echo "$DB_LIST" | jq -r ".[] | select(.name == \"$NAME\") | .uuid")
echo "D1_DATABASE_ID: $D1_ID"
else
echo "⚠️ Database $NAME does not exist. Starting creation..."
pnpm wrangler d1 create $NAME
DB_LIST=$(pnpm wrangler d1 list --json)
D1_ID=$(echo "$DB_LIST" | jq -r ".[] | select(.name == \"$NAME\") | .uuid")
fi
sed -i "s|\${D1_DATABASE_ID}|$D1_ID|g" "$CONFIG_FILE"
echo "✅ Setup completed."
- name: 🚀 开始部署 / Start deployment
id: deploy
working-directory: ./mail-worker
run: |
echo "🚀 Starting deployment..."
pnpm wrangler deploy -c wrangler-action.toml 2>&1 \
| tee deploy.log \
| grep -v "https://.*\.workers\.dev" \
| sed -E 's/env\.domain .*/env.domain (***)/' \
|| true
DEPLOY_EXIT_CODE=${PIPESTATUS[0]}
if [ $DEPLOY_EXIT_CODE -ne 0 ]; then
exit 1
fi
WORKER_URL=$(grep -o "https://.*\.workers\.dev" deploy.log || echo "")
if [ -n "$WORKER_URL" ]; then
echo "::add-mask::$WORKER_URL"
fi
echo "worker_url=$WORKER_URL" >> $GITHUB_OUTPUT
echo "✅ Setup completed."
- name: ♻️ 初始化数据库 / Initialize database
run: |
echo "🛠️ Starting database initialization..."
sleep 15
WORKER_URL="${CUSTOM_DOMAIN:+https://$CUSTOM_DOMAIN}"
WORKER_URL="${WORKER_URL:-${{ steps.deploy.outputs.worker_url }}}"
if [ -z "$WORKER_URL" ]; then
echo "❌ Preview URL not available. Please set CUSTOM_DOMAIN."
exit 1
fi
HTTP_CODE=$(curl -sL -w "%{http_code}" -o response.txt "$WORKER_URL/api/init/${JWT_SECRET}")
RESPONSE_BODY=$(cat response.txt)
if [ "$RESPONSE_BODY" = "success" ]; then
echo "✅ Setup completed."
else
echo "❌ Failed. HTTP: $HTTP_CODE, Response: $RESPONSE_BODY"
exit 1
fi
- name: 🗑️ 删除运行记录 / Delete workflow runs
uses: GitRML/delete-workflow-runs@main
continue-on-error: true
with:
retain_days: '1'
keep_minimum_runs: '0'
+2 -1
View File
@@ -9,6 +9,7 @@ lerna-debug.log*
node_modules
dist-ssr
*.local
dist
.vscode/*
!.vscode/extensions.json
@@ -23,4 +24,4 @@ dist-ssr
mail-vue/node_modules
mail-vue/dist
.wrangler
.venv
.venv
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2025 LaziestRen
Copyright (c) 2025 eoao
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
+148
View File
@@ -0,0 +1,148 @@
<p align="center">
<img src="doc/demo/logo.png" width="80px" />
<h1 align="center">Cloud Mail</h1>
<p align="center">A simple, responsive email service designed to run on Cloudflare Workers 🎉</p>
<p align="center">
<a href="/README.md" style="margin-left: 5px">简体中文</a> | English
</p>
<p align="center">
<a href="https://github.com/maillab/cloud-mail/tree/main?tab=MIT-1-ov-file" target="_blank" >
<img src="https://img.shields.io/badge/license-MIT-green" />
</a>
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank" >
<img src="https://img.shields.io/github/v/release/maillab/cloud-mail" alt="releases" />
</a>
<a href="https://github.com/maillab/cloud-mail/issues" >
<img src="https://img.shields.io/github/issues/maillab/cloud-mail" alt="issues" />
</a>
<a href="https://github.com/maillab/cloud-mail/stargazers" target="_blank">
<img src="https://img.shields.io/github/stars/maillab/cloud-mail" alt="stargazers" />
</a>
<a href="https://github.com/maillab/cloud-mail/forks" target="_blank" >
<img src="https://img.shields.io/github/forks/maillab/cloud-mail" alt="forks" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/20459" target="_blank" >
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" >
</a>
</p>
</p>
## Description
With only one domain, you can create multiple different email addresses, similar to major email platforms. This project can be deployed on Cloudflare Workers to reduce server costs and build your own email service.
## Project Showcase
- [Live Demo](https://skymail.ink)<br>
- [Deployment Guide](https://doc.skymail.ink/en/)<br>
| ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) |
|--------------------------|--------------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
## Features
- **💰 Low-Cost Usage**: No server required — deploy to Cloudflare Workers to reduce costs.
- **💻 Responsive Design**: Automatically adapts to both desktop and most mobile browsers.
- **📧 Email Sending**: Integrated with Resend, supporting bulk email sending and attachments.
- **🛡️ Admin Features**: Admin controls for user and email management with RBAC-based access control.
- **📦 Attachment Support**: Send and receive attachments, stored and downloaded via R2 object storage.
- **🔔 Email Push**: Forward received emails to Telegram bots or other email providers.
- **📡 Open API**: Supports batch user creation via API and multi-condition email queries
- **🔢 Verification Code Recognition**: Auto-detect codes via Workers AI
- **📈 Data Visualization**: Use ECharts to visualize system data, including user email growth.
- **🎨 Personalization**: Customize website title, login background, and transparency.
- **🤖 CAPTCHA**: Integrated with Turnstile CAPTCHA to prevent automated registration.
- **📜 More Features**: Under development...
## Tech Stack
- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **Web Framework**: [Hono](https://hono.dev/)
- **ORM**: [Drizzle](https://orm.drizzle.team/)
- **Frontend Framework**: [Vue3](https://vuejs.org/)
- **UI Framework**: [Element Plus](https://element-plus.org/)
- **Email Service**: [Resend](https://resend.com/)
- **Cache**: [Cloudflare KV](https://developers.cloudflare.com/kv/)
- **Database**: [Cloudflare D1](https://developers.cloudflare.com/d1/)
- **File Storage**: [Cloudflare R2](https://developers.cloudflare.com/r2/)
## Project Structure
```
cloud-mail
├── mail-worker # Backend worker project
│ ├── src
│ │ ├── api # API layer
│ │ ├── const # Project constants
│ │ ├── dao # Data access layer
│ │ ├── email # Email processing and handling
│ │ ├── entity # Database entities
│ │ ├── error # Custom exceptions
│ │ ├── hono # Web framework, middleware, error handling
│ │ ├── i18n # Internationalization
│ │ ├── init # Database and cache initialization
│ │ ├── model # Response data models
│ │ ├── security # Authentication and authorization
│ │ ├── service # Business logic layer
│ │ ├── template # Message templates
│ │ ├── utils # Utility functions
│ │ └── index.js # Entry point
│ ├── package.json # Project dependencies
│ └── wrangler.toml # Project configuration
├─ mail-vue # Frontend Vue project
│ ├── src
│ │ ├── axios # Axios configuration
│ │ ├── components # Custom components
│ │ ├── echarts # ECharts integration
│ │ ├── i18n # Internationalization
│ │ ├── init # Startup initialization
│ │ ├── layout # Main layout components
│ │ ├── perm # Permissions and access control
│ │ ├── request # API request layer
│ │ ├── router # Router configuration
│ │ ├── store # Global state management
│ │ ├── utils # Utility functions
│ │ ├── views # Page components
│ │ ├── app.vue # Root component
│ │ ├── main.js # Entry JS file
│ │ └── style.css # Global styles
│ ├── package.json # Project dependencies
└── └── env.release # Environment configuration
```
## Sponsor
<a href="https://doc.skymail.ink/support.html">
<img width="170px" src="./doc/images/support.png" alt="">
</a>
## License
This project is licensed under the [MIT](LICENSE) license.
## Communication
[Telegram](https://t.me/cloud_mail_tg)
+93 -164
View File
@@ -1,75 +1,90 @@
<p align="center">
<img src="demo/logo.png" width="10%" />
<img src="doc/demo/logo.png" width="80px" />
<h1 align="center">Cloud Mail</h1>
<p align="center">基于 Cloudflare 的简约响应式邮箱服务,支持邮件发送、附件收发 🎉</p>
<p align="center">
简体中文 | <a href="/README-en.md" style="margin-left: 5px">English </a>
</p>
<p align="center">
<a href="https://github.com/maillab/cloud-mail/tree/main?tab=MIT-1-ov-file" target="_blank" >
<img src="https://img.shields.io/badge/license-MIT-green" />
</a>
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank" >
<img src="https://img.shields.io/github/v/release/maillab/cloud-mail" alt="releases" />
</a>
<a href="https://github.com/maillab/cloud-mail/issues" >
<img src="https://img.shields.io/github/issues/maillab/cloud-mail" alt="issues" />
</a>
<a href="https://github.com/maillab/cloud-mail/stargazers" target="_blank">
<img src="https://img.shields.io/github/stars/maillab/cloud-mail" alt="stargazers" />
</a>
<a href="https://github.com/maillab/cloud-mail/forks" target="_blank" >
<img src="https://img.shields.io/github/forks/maillab/cloud-mail" alt="forks" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/20459" target="_blank" >
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" >
</a>
</p>
</p>
<div align="center">
<h1>Cloud Mail</h1>
</div>
<div align="center">
<h4>使用Vue3开发的响应式简约邮箱服务,支持邮件发送附件收发,可以部署到Cloudflare云平台实现免费白嫖🎉</h4>
</div>
## 项目简介
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台 QQ邮箱,谷歌邮箱等,本项目使用Cloud flare部署,Rsend推送邮件,无需服务器费用,搭建属于自己的邮箱服务
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台,本项目支持署到 Cloudflare Workers ,降低服务器成本,搭建自己的邮箱服务
## 项目展示
- [在线演示](https://skymail.ink)<br>
- [部署文档](https://doc.skymail.ink)<br>
## 项目展示
[**👉 在线演示**](https://skymail.ink)
[**👉 小白保姆教程-界面部署**](https://doc.skymail.ink)
| ![](demo/demo1.png) | ![](demo/demo2.png) |
|---------------------|---------------------|
| ![](demo/demo3.png) | ![](demo/demo4.png) |
| ![](demo/demo5.png) | ![](demo/demo6.png) |
| ![](demo/demo7.png) | ![](demo/demo8.png) |
| ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) |
|-----------------------|-----------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
## 功能介绍
- **💰免费白嫖**:无需服务器,部署到Cloudflare Workers 免费使用,不要钱
- **💰 低成本使用**部署到 Cloudflare Workers 降低服务器成本
- **💻响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
- **💻 响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
- **📧邮件发送**:集成resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
- **📧 邮件发送**:集成Resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
- **🛡️管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
- **🛡️ 管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
- **🔀多号模式**:开启后一个用户可以添加多个邮箱,默认一用户一邮箱,类似各大邮箱平台
- **📦 附件收发**:支持收发附件,使用R2对象存储保存和下载文件
- **📦附件收发**:支持收发附件,使用R2对象存储保存和下载文件
- **🔔 邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
- **🔔邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
- **📡 开放API**:支持使用API批量生成用户,多条件查询邮件
- **📈数据可视化**:使用echarts对系统数据详情,用户邮件增长可视化显示
- **🔢 验证码识别**:使用Workers AI,自动识别邮件验证码
- **⭐星标邮件**:标记重要邮件,以便快速查阅
- **📈 数据可视化**:使用ECharts对系统数据详情,用户邮件增长可视化显示
- **🎨个性化设置**:可以自定义网站标题,登录背景,透明度
- **🎨 个性化设置**:可以自定义网站标题,登录背景,透明度
- **⚙️功能设置**:可以对注册,邮件发送,添加等功能关闭和开启,设为私人站点
- **🤖 人机验证**:集成Turnstile人机验证,防止人机批量注册
- **🤖人机验证**:集成Turnstile人机验证,防止人机批量注册
- **📜更多功能**:正在开发中...
- **📜 更多功能**:正在开发中...
## 技术栈
- **框架**[Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/)
- **平台**[Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **Web框架**[Hono](https://hono.dev/)
- **ORM**[Drizzle](https://orm.drizzle.team/)
- **平台:** [Cloudflare workers](https://developers.cloudflare.com/workers/)
- **前端框架**[Vue3](https://vuejs.org/)
- **UI框架**[Element Plus](https://element-plus.org/)
- **邮件推送:** [Resend](https://resend.com/)
@@ -79,142 +94,56 @@
- **文件存储**[Cloudflare R2](https://developers.cloudflare.com/r2/)
## 使用教程
### 环境要求
Nodejs v18.20 +
Cloudflare 账号 (需要绑定域名)
**克隆项目到本地**
``` shell
git clone https://github.com/LaziestRen/cloud-mail #拉取代码
cd cloud-mail/mail-worker #进入worker目录
```
**安装依赖**
```shell
npm i
```
**项目配置**
mail-worker/wrangler.toml
```toml
[[d1_databases]]
binding = "db" #d1数据库绑定名默认不可修改
database_name = "" #d1数据库名字
database_id = "" #d1数据库id
[[kv_namespaces]]
binding = "kv" #kv绑定名默认不可修改
id = "" #kv数据库id
[[r2_buckets]]
binding = "r2" #r2对象存储绑定名默认不可修改
bucket_name = "" #r2对象存储桶的名字
[assets]
binding = "assets" #静态资源绑定名默认不可修改
directory = "./dist" #前端vue项目打包的静态资源存放位置,默认dist
[vars]
orm_log = false
domain = [] #邮件域名可以配置多个示例: ["example1.com","example2.com"]
admin = "" #管理员的邮箱 示例: [email protected]
jwt_secret = "" #登录身份令牌的密钥,随便填一串字符串
```
**远程部署**
1. 在 Cloudflare 控制台创建KVD1数据库,R2对象存储
2. 在项目目录 mail-worker/wrangler.toml 配置文件中配置对应环境变量,以及创建的数据库id和名称
3. 执行远程部署命令
```shell
npm run deploy
```
4. 在Cloudflare→账户主页→你的域名→电子邮件→电子邮件路由→路由规则→Catch-all地址,编辑发送到worker
5. 浏览器输入 https://你的项目域名/api/init/你的jwt_secret 初始化或更新 d1和kv数据库
6. 部署完成登录网站,使用管理员账号可以在设置页面添加配置 R2域名 Turnstile密钥 等
**邮件发送**
1. 在 resend 官网注册后,点击左侧 Domains 添加并验证你的域名,等待验证完成
2. 点击左侧 Api Keys 创建立api key 复制token回到项目网站设置页面添加 resend token
3. 点击左侧 Webhooks 添加回调地址 https://你的项目域名/api/webhooks
勾选✅ (email.bounced email.complained email.delivered email.delivery_delayed)
**本地运行**
1. 本地运行,数据库,对象存储会自动安装,无需创建,数据库数据保存在 mail-worker/.wrangler文件夹
```shell
npm run dev
```
2. 浏览器输入 http://127.0.0.1:8787/api/init/你的jwt_secret 初始化d1和kv数据库
3. 本地运行项目设置页面r2域名可设置为 http://127.0.0.1:8787/api/file
## 目录结构
```
cloud-mail
├── mail-worker #worker后端项目
├── mail-worker # worker后端项目
│ ├── src
│ │ ├── api #接口层
│ │ ├── const #常量
│ │ ├── email #邮件接收
│ │ ├── entity #数据库实体层
│ │ ├── error #自定义异常
│ │ ├── hono #web框架配置 拦截器等
│ │ ├── init #数据库缓存初始化
│ │ ├── model #响应体数据封装
│ │ ├── security #身份认证层
│ │ ├── service #服务层
│ │ ├── utils #工具类
│ │ ── index.js #入口文件
│ ├── pageckge.json #项目依赖
── wrangler.toml #项目配置
└── mail-vue #vue前端项目
├── src
── assets #静态资源字体等
│ ├── axios #axios配置
│ ├── components #自定义组件
│ ├── layout #主体布局组件
│ ├── request #api接口
│ ├── router #路由配置
│ ├── store #全局状态管理
│ ├── utils #工具类
│ ├── views #页面组件
│ ├── app.vue #根组件
│ ├── main.js #入口js
── style.css #全局css
├── package.json #项目依赖
── env.dev #项目配置
│ │ ├── api # api接口层
│ │ ├── const # 项目常量
│ │ ├── dao # 数据访问层
│ │ ├── email # 邮件处理接收
│ │ ├── entity # 数据库实体
│ │ ├── error # 自定义异常
│ │ ├── hono # web框架配置、拦截器、全局异常等
│ │ ├── i18n # 语言国际化
│ │ ├── init # 数据库缓存初始化
│ │ ├── model # 响应体数据封装
│ │ ├── security # 身份权限认证
│ │ ── service # 业务服务层
│ ├── template # 消息模板
── utils # 工具类
│ │ └── index.js # 入口文件
├── pageckge.json # 项目依赖
── wrangler.toml # 项目配置
├── mail-vue # vue前端项目
│ ├── src
│ ├── axios # axios配置
│ ├── components # 自定义组件
│ ├── echarts # echarts组件导入
│ ├── i18n # 语言国际化
│ ├── init # 入站初始化
│ ├── layout # 主体布局组件
│ ├── perm # 权限认证
── request # api接口
│ │ ├── router # 路由配置
│ │ ── store # 全局状态管理
│ │ ├── utils # 工具类
│ │ ├── views # 页面组件
│ │ ├── app.vue # 入口组件
│ │ ├── main.js # 入口js
│ │ └── style.css # 全局css
│ ├── package.json # 项目依赖
└── └── env.release # 项目配置
```
## 赞助
<a href="https://doc.skymail.ink/support.html" >
<img width="170px" src="./doc/images/support.png" alt="">
</a>
## 许可证
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

+38
View File
@@ -0,0 +1,38 @@
## Github Action 部署
**配置 Github 仓库**
1. Fork 或克隆仓库 [https://github.com/eoao/cloud-mail](https://github.com/eoao/cloud-mail)
2. 进入您的 GitHub 仓库设置
3. 转到 Settings → Secrets and variables → Actions → New Repository secrets
4. 添加以下 Secrets
| Secret 名称 | 必需 | 用途 |
| ----------------------- | :--: | ----------------------------------------------------- |
| `CLOUDFLARE_API_TOKEN` | ✅ | Cloudflare API 令牌(需要 Workers 和相关资源权限) |
| `CLOUDFLARE_ACCOUNT_ID` | ✅ | Cloudflare 账户 ID |
| `D1_DATABASE_ID` | ✅ | 您的 D1 数据库的 ID |
| `KV_NAMESPACE_ID` | ✅ | 您的 KV 命名空间的 ID |
| `R2_BUCKET_NAME` | ✅ | 您的 R2 存储桶的名称 |
| `DOMAIN` | ✅ | 您要用于邮件服务的域名(例如 `["xx.xx"],多域名用,分隔` |
| `ADMIN` | ✅ | 您的管理员邮箱地址(例如 `[email protected]` |
| `JWT_SECRET` | ✅ | 用于生成和验证 JWT 的随机长字符串 |
| `INIT_URL` | ❌ | (可选)部署后用于初始化数据库的 Worker URL(格式参考下述手动初始化) |
---
**获取 Cloudflare API 令牌**
1. 访问 [Cloudflare Dashboard](https://dash.cloudflare.com/profile/api-tokens)
2. 创建新的 API 令牌
3. 选择"编辑 Cloudflare Workers"模板,并参照下表添加相应权限
![dc2e1dc8dcd217644759c46c6c705de1](https://i.miji.bid/2025/07/07/dc2e1dc8dcd217644759c46c6c705de1.png)
4. 保存令牌并复制到 GitHub Secrets 中的 `CLOUDFLARE_API_TOKEN`
**获取 Cloudflare 账户 ID**
1. 账户 ID 可以在 Cloudflare 仪表盘的账户设置中找到。
2. 复制到 GitHub Secrets 中的 `CLOUDFLARE_ACCOUNT_ID`
**运行工作流**
1. 然后在Action页面手动运行工作流,后续同步上游后会自动部署到 Cloudflare Workers。如未配置 `INIT_URL`,则需要手动访问 `https://你的项目域名/api/init/你的jwt_secret` 进行数据库初始化。
2. 自动同步上游可使用bot或者手动点击Sync Upstream按钮。
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

+2 -1
View File
@@ -1,3 +1,4 @@
NODE_ENV = 'dev'
VITE_APP_TITLE = '开发环境'
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
VITE_PWA_NAME = 'Cloud Mail'
+3 -1
View File
@@ -1,3 +1,5 @@
NODE_ENV = 'release'
VITE_APP_TITLE = '发布环境'
VITE_BASE_URL = '/api'
VITE_BASE_URL = '/api'
VITE_PWA_NAME = 'Cloud Mail'
VITE_OUT_DIR = ../mail-worker/dist
+2 -1
View File
@@ -1,3 +1,4 @@
NODE_ENV = 'remote'
VITE_APP_TITLE = '远程环境'
VITE_BASE_URL = 'xxxxxx'
VITE_BASE_URL = 'https://skymail.ink/api'
VITE_PWA_NAME = 'Cloud Mail'
+129 -86
View File
@@ -1,96 +1,139 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title></title>
<link rel="icon" href="./src/assets/favicon.svg" type="image/svg+xml">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="theme-color" content="#F1F1F1" id="theme-color-meta">
<meta name="description" content="Cloud Mail 是一个 Serverless 响应式邮箱服务,支持邮件发送,可部署到 Cloudflare 平台,降低服务器成本。Cloud Mail is a serverless responsive email service that supports email sending and can be deployed on Cloudflare to reduce server costs.">
<title>Cloud Mail</title>
<link rel="icon" href="/public/mail.png" type="image/png">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script>
const uiStoreStr = localStorage.getItem('ui')
if (uiStoreStr) {
const uiStore = JSON.parse(uiStoreStr)
const root = document.documentElement
root.setAttribute('class', uiStore.dark ? 'dark' : '');
const metaTag = document.getElementById('theme-color-meta');
const isMobile = !window.matchMedia("(pointer: fine) and (hover: hover)").matches;
metaTag.setAttribute('content', uiStore.dark ? (isMobile ? '#141414' : '#000000') : (isMobile ? '#FFFFFF' : '#F1F1F1'));
}
</script>
</head>
<style>
html {
background: #FFFFFF;
}
.dark {
background: #141414;
}
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 500;
background: var(--el-bg-color);
}
.loading-hide {
pointer-events: none;
opacity: 0;
}
.loading-icon {
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
}
.loading-image {
width: 70px;
height: 70px;
object-fit: contain;
}
.loading-progress {
position: relative;
width: 64px;
height: 4px;
overflow: hidden;
border-radius: 999px;
background: rgba(64, 158, 255, 0.18);
}
.loading-progress::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: inherit;
background: #409EFF;
transform: scaleX(0);
transform-origin: left center;
animation: loading-progress-grow 2.4s linear forwards;
}
.loading-progress::after {
content: "";
position: absolute;
top: 0;
width: 24px;
height: 100%;
border-radius: inherit;
background: rgba(64, 158, 255, 0.45);
filter: blur(4px);
transform: translateX(-24px);
animation: loading-progress-peg 2.4s linear forwards;
}
.loading-complete .loading-progress::before {
animation: none;
transform: scaleX(1);
transition: transform 200ms linear;
}
.loading-complete .loading-progress::after {
animation: none;
transform: translateX(60px);
transition: transform 200ms linear;
}
@keyframes loading-progress-grow {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
@keyframes loading-progress-peg {
0% {
transform: translateX(-24px);
}
100% {
transform: translateX(60px);
}
}
</style>
<body>
<div id="loading-first">
<div class="loading-icon">
<svg class="circular" viewBox="0 0 20 20">
<g class="loading-path">
<circle r="3.375" class="dot1" rx="0" ry="0" />
<circle r="3.375" class="dot2" rx="0" ry="0" />
<circle r="3.375" class="dot4" rx="0" ry="0" />
<circle r="3.375" class="dot3" rx="0" ry="0" />
</g>
</svg>
</div>
<div id="loading-first" >
<div class="loading-icon">
<img class="loading-image" src="/mail-pwa.png" alt="Cloud Mail">
<div class="loading-progress" aria-hidden="true"></div>
</div>
</div>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<style>
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
z-index: 500;
}
.loading-icon {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.circular {
height: 30px;
width: 30px;
animation: loading-rotate 1s linear infinite;
}
.loading-path .dot1 {
transform: translate(3.75px, 3.75px);
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
}
.loading-path .dot2 {
transform: translate(calc(100% - 3.75px), 3.75px);
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.4s;
}
.loading-path .dot3 {
transform: translate(3.75px, calc(100% - 3.75px));
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 1.2s;
}
.loading-path .dot4 {
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.8s;
}
@keyframes loading-rotate {
to {
transform: rotate(360deg);
}
}
@keyframes custom-spin-move {
to {
opacity: 1;
}
}
</style>
+8
View File
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}
-3853
View File
File diff suppressed because it is too large Load Diff
+10 -5
View File
@@ -7,24 +7,28 @@
"dev": "vite --mode dev",
"remote": "vite --mode remote",
"build": "vite build --mode release",
"eo": "vite build --mode eo",
"preview": "vite preview"
},
"dependencies": {
"@iconify/vue": "^4.3.0",
"@simplewebauthn/browser": "^13.3.0",
"@vueuse/components": "^14.1.0",
"@vueuse/core": "^12.0.0",
"axios": "^1.7.8",
"axios": "1.15.2",
"compressorjs": "^1.2.1",
"date-time-format-timezone": "^1.0.22",
"dayjs": "^1.11.13",
"dexie": "^4.0.11",
"echarts": "^5.6.0",
"element-plus": "^2.9.5",
"element-plus": "^2.13.1",
"lodash-es": "^4.17.21",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.2.0",
"screenfull": "^6.0.2",
"vue": "^3.5.13",
"vue-cropper": "^1.1.4",
"vue-i18n": "^11.1.10",
"vue-router": "^4.5.0"
},
"devDependencies": {
@@ -34,6 +38,7 @@
"terser": "^5.39.0",
"unplugin-auto-import": "^19.3.0",
"unplugin-vue-components": "^28.7.0",
"vite": "6.3.4"
"vite": "7.1.5",
"vite-plugin-pwa": "^1.0.3"
}
}
+5244
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
/assets/*
Cache-Control: public, max-age=31556952, immutable
/tinymce/*
Cache-Control: public, max-age=604800, immutable
/image/*
Cache-Control: public, max-age=604800, immutable
Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+55
View File
@@ -0,0 +1,55 @@
.tox-dialog__body-content {
margin: 0 !important;
}
img {
max-width: 100% !important;
height: auto !important;
}
p {
margin: 0 !important;
}
a {
text-decoration: none;
color: #0E70DF;
}
body {
margin: 10px 8px 0 5px !important;
font-size: 14px;
}
:root {
--scrollbar-thumb-color: #FFFFFF;
--scrollbar-track-color: #A8ABB2;
}
.mceNonEditable {
color: #303133;
background: #FFFFFF;
}
@media (pointer: fine) and (hover: hover) {
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: var(--scrollbar-track-color);
}
::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb-color);
border-radius: 10px;
cursor: pointer;
}
}
.mce-item-table:not([border]), .mce-item-table:not([border]) caption, .mce-item-table:not([border]) td, .mce-item-table:not([border]) th, .mce-item-table[border="0"], .mce-item-table[border="0"] caption, .mce-item-table[border="0"] td, .mce-item-table[border="0"] th, table[style*="border-width: 0px"], table[style*="border-width: 0px"] caption, table[style*="border-width: 0px"] td, table[style*="border-width: 0px"] th {
border: none;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
Below is a list of third party libraries that this software uses:
----------------------------------------------------------------
dompurify - Patched by Tiny
owner: Mario Heiderich
repo: https://github.com/cure53/DOMPurify
version: 3.2.4
license: MPL-2.0 OR Apache-2.0
prismjs
owner: Lea Verou
repo: https://github.com/PrismJS/prism
version: 1.25.0
license: MIT
prism-themes
owner: Lea Verou
repo: https://github.com/PrismJS/prism-themes
version: 1.9.0
license: MIT
File diff suppressed because one or more lines are too long
+1 -4
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:"OL"===l?3:4,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,disc,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();
-3
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>e.options.get("allow_html_in_named_anchor");const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}();
+1 -4
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e);const l=e=>undefined===e;const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=4&&b.substr(0,4)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e);const n=e=>undefined===e;const o=e=>!(e=>null==e)(e),r=Object.hasOwnProperty,a=e=>"\ufeff"===e,s=e=>t=>t.options.get(e),l=s("autolink_pattern"),i=s("link_default_target"),c=s("link_default_protocol"),d=s("allow_unsafe_link_target");var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!a(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=l(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),r.call(t,n))||"false"===i.getContentEditable(e)||null!==i.getParent(e,"a[href]");var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return P="www.",(b=t).length>=4&&b.substr(0,4)===P?t=c(e)+"://"+t:((e,t,o=0,r)=>{const a=e.indexOf(t,o);return-1!==a&&(!!n(r)||a+t.length<=r)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,P;return null},k=(e,n)=>{const{dom:o,selection:r}=e,{rng:a,url:s}=n,l=r.getBookmark();r.setRng(a);const c="createlink",u={command:c,ui:!1,value:s};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(c,!1,s),e.dispatch("ExecCommand",u);const n=i(e);if(t(n)){const t=r.getNode();o.setAttrib(t,"target",n),"_blank"!==n||d(e)||o.setAttrib(t,"rel","noopener")}}r.moveToBookmark(l),e.nodeChanged()},p=e=>{const t=m(e,-1);o(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);o(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),n=o("min_height"),s=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),g=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},l=(e,t,o,n)=>{var s;const i=parseInt(null!==(s=e.getStyle(t,o,n))&&void 0!==s?s:"",10);return isNaN(i)?0:i},a=(e,o,r,c)=>{var d;const u=e.dom,h=e.getDoc();if(!h)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void g(e,!0);const m=h.documentElement,f=c?c():i(e),p=null!==(d=n(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=l(u,m,"margin-top",!0),v=l(u,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+f;C<0&&(C=0);const H=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+H>p&&(y=C+H);const b=s(e);b&&y>b?(y=b,g(e,!0)):g(e,!1);const w=o.get();if(w.set&&(e.dom.setStyles(e.getDoc().documentElement,{"min-height":0}),e.dom.setStyles(e.getBody(),{"min-height":"inherit"})),y!==w.totalHeight&&(C-f!==w.contentHeight||!w.set)){const n=y-w.totalHeight;if(u.setStyle(e.getContainer(),"height",y+"px"),o.set({totalHeight:y,contentHeight:C,set:!0}),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&n<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(()=>{let e={totalHeight:0,contentHeight:0,set:!1};return{get:()=>e,set:t=>{e=t}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{const n=()=>r(e);e.on("init",(s=>{const r=i(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,s,n)})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{a(e,o,t,n)}))})(e,o)}}))}();
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t);const r=t=>undefined===t;var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},y=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},g=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{const r=()=>f(t)&&!t.mode.isReadOnly();e.setEnabled(r());const o=()=>e.setEnabled(r());return t.on("StoreDraft RestoreDraft RemoveDraft",o),()=>t.off("StoreDraft RestoreDraft RemoveDraft",o)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{y(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{g(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&g(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>y(t),restoreDraft:()=>g(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}();
File diff suppressed because one or more lines are too long
-3
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}();
File diff suppressed because one or more lines are too long
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o<r;o++)e(t[o],o)},c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},p=t=>d(t.dom.host),w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=w,i=p,t=>r(i(t))));var r,i},b=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||w(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const o=[];for(let r=0,n=t.length;r<n;r++){const n=t[r];e(n,r)&&o.push(n)}return o})(((t,e)=>{const o=t.length,r=new Array(o);for(let n=0;n<o;n++){const o=t[n];r[n]=e(o,n)}return r})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?y(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{y(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(b(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,r=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(n=String).prototype.isPrototypeOf(r)||(null===(i=o.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var r,o,n,i})(t),o=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1),Array.prototype.slice;const u=(t,e)=>{for(let r=0,o=t.length;r<o;r++)e(t[r],r)};i(Array.from)&&Array.from;const c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const r=t.dom;if(1!==r.nodeType)return!1;{const t=r;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}},m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=t=>d(t.dom.host),p=(t,e)=>{t.dom.removeAttribute(e)},w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const r=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(r=e)&&n(r.dom.host)?a.some(e):a.none();var r})(d(e)).fold((()=>r.body.contains(e)),(o=w,i=y,t=>o(i(t))));var o,i},b=t=>"rtl"===((t,e)=>{const r=t.dom,o=window.getComputedStyle(r).getPropertyValue(e);return""!==o||w(t)?o:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(r,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const r=[];for(let o=0,n=t.length;o<n;o++){const n=t[o];e(n,o)&&r.push(n)}return r})(((t,e)=>{const r=t.length,o=new Array(r);for(let n=0;n<r;n++){const r=t[n];o[n]=e(r,n)}return o})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(r=t,o="ol,ul",((t,e,r)=>{let n=t.dom;const s=i(r)?r:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,o))return a.some(t);if(s(t))break}return a.none()})(r,0,n)):a.some(t)).getOr(t);var r,o,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?p(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(r(n)||o(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{p(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>r=>{const o=o=>{const n=d(o.element);r.setActive(b(n)===e),r.setEnabled(t.selection.isEditable())};return t.on("NodeChange",o),r.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",o)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -4
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=e=>"function"==typeof e;var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),g=p("importcss_file_filter"),_=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),M=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s<r;++s){if(!o(e[s]))throw new Error("Arr.flatten item "+s+" was not an array, input: "+e);b.apply(t,e[s])}return t})(((e,t)=>{const s=e.length,r=new Array(s);for(let o=0;o<s;o++){const s=e[o];r[o]=t(s,o)}return r})(r,n))).concat(e);var r,n}}})(),r={},n=T(y(e)),p=(e=>a.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=_(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/",c=e.editorManager.suffix;return t===o+"/content"+(e.inline?".inline":"")+`${c}.css`||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet&&e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(g(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),M(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=e=>"function"==typeof e;Array.prototype.slice;const c=Array.prototype.push;n(Array.from)&&Array.from;var i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),l=tinymce.util.Tools.resolve("tinymce.EditorManager"),a=tinymce.util.Tools.resolve("tinymce.Env"),p=tinymce.util.Tools.resolve("tinymce.util.Tools");const u=e=>t=>t.options.get(e),m=u("importcss_merge_classes"),f=u("importcss_exclusive"),y=u("importcss_selector_converter"),d=u("importcss_selector_filter"),h=u("importcss_groups"),g=u("importcss_append"),_=u("importcss_file_filter"),v=u("skin"),b=u("skin_url"),x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=p.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),m(e)?s.classes=n:s.attributes={class:n},s},A=(e,t)=>null===t||f(e),k=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s<r;++s){if(!o(e[s]))throw new Error("Arr.flatten item "+s+" was not an array, input: "+e);c.apply(t,e[s])}return t})(((e,t)=>{const s=e.length,r=new Array(s);for(let o=0;o<s;o++){const s=e[o];r[o]=t(s,o)}return r})(r,n))).concat(e);var r,n}}})(),r={},n=T(d(e)),u=(e=>p.map(e,(e=>p.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(h(e)),m=(t,s)=>{if(((e,t,s,r)=>!(A(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{A(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=y(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||i.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};p.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let i,u=t.href;if(u=(e=>{const t=a.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=v(e);if(s){const r=b(e),o=r?e.documentBaseURI.toAbsolute(r):l.baseURL+"/skins/ui/"+s,n=l.baseURL+"/skins/content/",c=e.editorManager.suffix;return t===o+"/content"+(e.inline?".inline":"")+`${c}.css`||-1!==t.indexOf(n)}return!1})(e,u)){p.each(t.imports,(e=>{c(e,!0)}));try{i=t.cssRules||t.rules}catch(e){}p.each(i,(e=>{e.styleSheet&&e.styleSheet?c(e.styleSheet,!0):e.selectorText&&p.each(e.selectorText.split(","),(e=>{o.push(p.trim(e))}))}))}};p.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{p.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>p.grep(e,(e=>!e.filter||e.filter(t))))(u,e);if(s.length>0)p.each(s,(s=>{const r=m(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=m(e,null);s&&t.addItem(s)}}}));const f=t.toFormats();e.dispatch("addStyleModifications",{items:f,replace:!g(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),k(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),n=t("insertdatetime_timeformat"),r=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length<t)for(let a=0;a<t-e.length;a++)e="0"+e;return e},d=(e,t,a=new Date)=>(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)&&e.selection.isEditable()){const a=d(e,t);let n;n=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const r=e.dom.getParent(e.selection.getStart(),"time");r?((e,t,a,n)=>{const r=e.dom.create("time",{datetime:a},n);e.dom.replace(r,t),e.selection.select(r,!0),e.selection.collapse(!1)})(e,r,n,a):e.insertContent('<time datetime="'+n+'">'+a+"</time>")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");const g=e=>t=>{const a=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",a),a(),()=>{e.off("NodeChange",a)}};e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,n)=>{u(e,null!=n?n:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:n(e))}))})(e),(e=>{const t=r(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=r(e);return t.length>0?t[0]:n(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)},onSetup:g(e)});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)}))),onSetup:g(e)})})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=n=>e=>typeof e===n,o=e("boolean"),a=e("number"),t=n=>e=>e.options.get(n),i=t("nonbreaking_force_tab"),s=t("nonbreaking_wrap"),r=(n,e)=>{let o="";for(let a=0;a<e;a++)o+=n;return o},c=(n,e)=>{const o=s(n)||n.plugins.visualchars?`<span class="${(n=>!!n.plugins.visualchars&&n.plugins.visualchars.isEnabled())(n)?"mce-nbsp-wrap mce-nbsp":"mce-nbsp-wrap"}" contenteditable="false">${r("&nbsp;",e)}</span>`:r("&nbsp;",e);n.undoManager.transact((()=>n.insertContent(o)))};var l=tinymce.util.Tools.resolve("tinymce.util.VK");const u=n=>e=>{const o=()=>{e.setEnabled(n.selection.isEditable())};return n.on("NodeChange",o),o(),()=>{n.off("NodeChange",o)}};n.add("nonbreaking",(n=>{(n=>{const e=n.options.register;e("nonbreaking_force_tab",{processor:n=>o(n)?{value:n?3:0,valid:!0}:a(n)?{value:n,valid:!0}:{valid:!1,message:"Must be a boolean or number."},default:!1}),e("nonbreaking_wrap",{processor:"boolean",default:!0})})(n),(n=>{n.addCommand("mceNonBreaking",(()=>{c(n,1)}))})(n),(n=>{const e=()=>n.execCommand("mceNonBreaking");n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:e,onSetup:u(n)}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:e,onSetup:u(n)})})(n),(n=>{const e=i(n);e>0&&n.on("keydown",(o=>{if(o.keyCode===l.TAB&&!o.isDefaultPrevented()){if(o.shiftKey)return;o.preventDefault(),o.stopImmediatePropagation(),c(n,e)}}))})(n)}))}();
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env");const t=e=>a=>a.options.get(e),n=t("pagebreak_separator"),o=t("pagebreak_split_block"),r="mce-pagebreak",s=e=>{const t=`<img src="${a.transparentSrc}" class="${r}" data-mce-resize="false" data-mce-placeholder />`;return e?`<p>${t}</p>`:t},c=e=>a=>{const t=()=>{a.setEnabled(e.selection.isEditable())};return e.on("NodeChange",t),t(),()=>{e.off("NodeChange",t)}};e.add("pagebreak",(e=>{(e=>{const a=e.options.register;a("pagebreak_separator",{processor:"string",default:"\x3c!-- pagebreak --\x3e"}),a("pagebreak_split_block",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mcePageBreak",(()=>{e.insertContent(s(o(e)))}))})(e),(e=>{const a=()=>e.execCommand("mcePageBreak");e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:a,onSetup:c(e)}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:a,onSetup:c(e)})})(e),(e=>{const a=n(e),t=()=>o(e),c=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,(e=>"\\"+e)),"gi");e.on("BeforeSetContent",(e=>{e.content=e.content.replace(c,s(t()))})),e.on("PreInit",(()=>{e.serializer.addNodeFilter("img",(n=>{let o,s,c=n.length;for(;c--;)if(o=n[c],s=o.attr("class"),s&&-1!==s.indexOf(r)){const n=o.parent;if(n&&e.schema.getBlockElements()[n.name]&&t()){n.type=3,n.value=a,n.raw=!0,o.remove();continue}o.type=3,o.value=a,o.raw=!0}}))}))})(e),(e=>{e.on("ResolveName",(a=>{"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,r)&&(a.name="pagebreak")}))})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-3
View File
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const o=e=>"function"==typeof e;var t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),n=tinymce.util.Tools.resolve("tinymce.util.Tools");const a=e=>o=>o.options.get(e),c=a("save_enablewhendirty"),i=a("save_onsavecallback"),s=a("save_oncancelcallback"),r=(e,o)=>{e.notificationManager.open({text:o,type:"error"})},l=e=>o=>{const t=()=>{o.setEnabled(!c(e)||e.isDirty())};return t(),e.on("NodeChange dirty",t),()=>e.off("NodeChange dirty",t)};e.add("save",(e=>{(e=>{const o=e.options.register;o("save_enablewhendirty",{processor:"boolean",default:!0}),o("save_onsavecallback",{processor:"function"}),o("save_oncancelcallback",{processor:"function"})})(e),(e=>{e.ui.registry.addButton("save",{icon:"save",tooltip:"Save",enabled:!1,onAction:()=>e.execCommand("mceSave"),onSetup:l(e),shortcut:"Meta+S"}),e.ui.registry.addButton("cancel",{icon:"cancel",tooltip:"Cancel",enabled:!1,onAction:()=>e.execCommand("mceCancel"),onSetup:l(e)}),e.addShortcut("Meta+S","","mceSave")})(e),(e=>{e.addCommand("mceSave",(()=>{(e=>{const n=t.DOM.getParent(e.id,"form");if(c(e)&&!e.isDirty())return;e.save();const a=i(e);if(o(a))return a.call(e,e),void e.nodeChanged();n?(e.setDirty(!1),n.onsubmit&&!n.onsubmit()||("function"==typeof n.submit?n.submit():r(e,"Error: Form submit field collision.")),e.nodeChanged()):r(e,"Error: No form element found.")})(e)})),e.addCommand("mceCancel",(()=>{(e=>{const t=n.trim(e.startContent),a=s(e);o(a)?a.call(e,e):e.resetContent(t)})(e)}))})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const o=(t,o,e)=>{t.dom.toggleClass(t.getBody(),"mce-visualblocks"),e.set(!e.get()),((t,o)=>{t.dispatch("VisualBlocks",{state:o})})(t,e.get())},e=t=>t.options.get("visualblocks_default_state");const s=(t,o)=>e=>{e.setActive(o.get());const s=t=>e.setActive(t.state);return t.on("VisualBlocks",s),()=>t.off("VisualBlocks",s)};t.add("visualblocks",((t,l)=>{(t=>{(0,t.options.register)("visualblocks_default_state",{processor:"boolean",default:!1})})(t);const a=(()=>{let t=!1;return{get:()=>t,set:o=>{t=o}}})();((t,e,s)=>{t.addCommand("mceVisualBlocks",(()=>{o(t,0,s)}))})(t,0,a),((t,o)=>{const e=()=>t.execCommand("mceVisualBlocks");t.ui.registry.addToggleButton("visualblocks",{icon:"visualblocks",tooltip:"Show blocks",onAction:e,onSetup:s(t,o),context:"any"}),t.ui.registry.addToggleMenuItem("visualblocks",{text:"Show blocks",icon:"visualblocks",onAction:e,onSetup:s(t,o),context:"any"})})(t,a),((t,s,l)=>{t.on("PreviewFormats AfterPreviewFormats",(o=>{l.get()&&t.dom.toggleClass(t.getBody(),"mce-visualblocks","afterpreviewformats"===o.type)})),t.on("init",(()=>{e(t)&&o(t,0,l)}))})(t,0,a)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/dark/content.css', `body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}`)
+10 -1
View File
@@ -1 +1,10 @@
body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{background-color: #141414;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/default/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/document/content.css', `@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/tinymce-5-dark/content.css', `body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}`)
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/tinymce-5/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/writer/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1 +1,10 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More