Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5479b5f26 | ||
|
|
8c20ccb608 | ||
|
|
2df3e19d48 | ||
|
|
83d7817442 | ||
|
|
e16da38bb2 | ||
|
|
d4d52aa2c4 | ||
|
|
798321f7d5 | ||
|
|
f6e60d6d7f | ||
|
|
5d15a500f9 | ||
|
|
635fd7737b | ||
|
|
7b8aed4623 | ||
|
|
fa542c437c | ||
|
|
4f65ff0d34 | ||
|
|
06291b4c86 | ||
|
|
28905e369d | ||
|
|
aa827c0d33 | ||
|
|
3c33536812 | ||
|
|
452f134314 | ||
|
|
a07cd2de12 | ||
|
|
02076bf550 | ||
|
|
8fcecf7645 | ||
|
|
957bb04039 | ||
|
|
eb0819135f | ||
|
|
fc45478707 | ||
|
|
263edb43b8 | ||
|
|
dba5d1da63 | ||
|
|
2f87c0e6af | ||
|
|
60f5e9a701 | ||
|
|
2865e3aeb4 | ||
|
|
689bc3a72e | ||
|
|
1c1e6dc458 | ||
|
|
58ebf2bffb | ||
|
|
9b1ecd084f | ||
|
|
345d96ae55 | ||
|
|
35749f6127 | ||
|
|
f2a108a9b9 | ||
|
|
7d8195dd5c | ||
|
|
970985cd10 | ||
|
|
f65e174e7f | ||
|
|
2d123310e5 | ||
|
|
affa62a0cb | ||
|
|
0cd976c3b1 | ||
|
|
65aeb6a2de | ||
|
|
174248156c | ||
|
|
9d8bff65fc | ||
|
|
80c649a013 | ||
|
|
0184a276c5 | ||
|
|
024daaeecc | ||
|
|
b5271f1925 | ||
|
|
532a47406d | ||
|
|
043e01fde2 | ||
|
|
a2e26d3b55 | ||
|
|
0d3e45a47f | ||
|
|
16c4b3b738 | ||
|
|
87bbfcbd9f | ||
|
|
6be8c9c580 | ||
|
|
4a0e46e1cf | ||
|
|
298a21a3ee | ||
|
|
41d786ef49 | ||
|
|
b2b489c828 | ||
|
|
1136617dd9 | ||
|
|
2f2434ca5c |
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[Bug] "
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[Feature request] "
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Need Help
|
||||
about: Create a issue to find help
|
||||
title: "[Help] "
|
||||
labels: help wanted
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -14,258 +14,117 @@ jobs:
|
||||
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 }}
|
||||
|
||||
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
D1_DATABASE_ID: ${{ secrets.D1_DATABASE_ID }}
|
||||
KV_NAMESPACE_ID: ${{ secrets.KV_NAMESPACE_ID }}
|
||||
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
|
||||
DOMAIN: ${{ secrets.DOMAIN }}
|
||||
ADMIN: ${{ secrets.ADMIN }}
|
||||
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
||||
INIT_URL: ${{ secrets.INIT_URL }}
|
||||
|
||||
outputs:
|
||||
worker_url: ${{ steps.deploy.outputs.worker_url }}
|
||||
|
||||
deployment_skipped: ${{ steps.deploy.outputs.deployment_skipped }}
|
||||
|
||||
steps:
|
||||
- name: 🚚 检出代码仓库 / Checkout repository
|
||||
- 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
|
||||
- name: 📦 Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "./mail-worker/pnpm-lock.yaml"
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "./mail-worker/package-lock.json"
|
||||
|
||||
- name: 📦 安装依赖 / Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: 📥 Install dependencies
|
||||
run: npm ci
|
||||
working-directory: ./mail-worker
|
||||
|
||||
- name: 📡 禁用 Wrangler 遥测 / Disable wrangler telemetry
|
||||
- name: 📡 Disable wrangler telemetry
|
||||
working-directory: ./mail-worker
|
||||
run: pnpm wrangler telemetry disable
|
||||
run: npx 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
|
||||
- name: 🛠️ Prepare Config, Set Secrets and Deploy
|
||||
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
|
||||
if [ -z "$D1_DATABASE_ID" ] || [ -z "$KV_NAMESPACE_ID" ] || [ -z "$R2_BUCKET_NAME" ]; then
|
||||
echo "⚠️ Required secrets (D1_DATABASE_ID, KV_NAMESPACE_ID, or R2_BUCKET_NAME) are not set."
|
||||
echo "🟡 Skipping deployment."
|
||||
echo "deployment_skipped=true" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
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."
|
||||
echo "deployment_skipped=false" >> $GITHUB_OUTPUT
|
||||
CONFIG_FILE="wrangler-action.toml"
|
||||
echo "⚙️ Dynamically updating '$CONFIG_FILE' with binding IDs..."
|
||||
|
||||
- name: ♻️ 初始化数据库 / Initialize database
|
||||
sed -i "s|\${D1_DATABASE_ID}|${D1_DATABASE_ID}|g" "$CONFIG_FILE"
|
||||
sed -i "s|\${KV_NAMESPACE_ID}|${KV_NAMESPACE_ID}|g" "$CONFIG_FILE"
|
||||
sed -i "s|\${R2_BUCKET_NAME}|${R2_BUCKET_NAME}|g" "$CONFIG_FILE"
|
||||
|
||||
echo "🔍 Debug: Checking configuration after replacement..."
|
||||
echo "R2_BUCKET_NAME value: '$R2_BUCKET_NAME'"
|
||||
echo "R2 bucket configuration in $CONFIG_FILE:"
|
||||
grep -A 2 -B 2 "bucket_name" "$CONFIG_FILE" || true
|
||||
|
||||
echo "🔒 Setting Worker secrets..."
|
||||
WORKER_NAME="cloud-mail"
|
||||
for VAR in DOMAIN ADMIN JWT_SECRET; do
|
||||
if [ -n "${!VAR}" ]; then
|
||||
VAR_LOWER=$(echo "$VAR" | tr '[:upper:]' '[:lower:]')
|
||||
echo ">> Processing secret: '$VAR_LOWER'"
|
||||
(echo "${!VAR}" | npx wrangler secret put "$VAR_LOWER" --name "$WORKER_NAME" -c "$CONFIG_FILE") || true
|
||||
else
|
||||
echo "⚠️ Warning: GitHub Secret '$VAR' is not set. Skipping."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "🚀 Configuration updated. Starting deployment..."
|
||||
npx wrangler deploy -c "$CONFIG_FILE" | grep -v "https://.*\.workers\.dev" || true
|
||||
echo "✅ Deployment command executed."
|
||||
|
||||
- name: 🗄️ Initialize Database (if INIT_URL is set)
|
||||
if: ${{ steps.deploy.outputs.deployment_skipped == 'false' }}
|
||||
run: |
|
||||
echo "🛠️ Starting database initialization..."
|
||||
if [ -z "$INIT_URL" ]; then
|
||||
echo "✅ Deployment successful. INIT_URL not set, skipping initialization."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "⏳ Waiting 15 秒之前 before checking initialization status..."
|
||||
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}")
|
||||
HTTP_CODE=$(curl -s -w "%{http_code}" -o response.txt "$INIT_URL")
|
||||
RESPONSE_BODY=$(cat response.txt)
|
||||
|
||||
echo "🔎 Checking response... (Status: $HTTP_CODE)"
|
||||
|
||||
if [ "$RESPONSE_BODY" = "success" ]; then
|
||||
echo "✅ Setup completed."
|
||||
if [ "$HTTP_CODE" = "200" ] && [ "$RESPONSE_BODY" = "初始化成功" ]; then
|
||||
echo "🎉✅ Fresh initialization successful!"
|
||||
elif [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ Database is already initialized or in a stable state. Response: $RESPONSE_BODY"
|
||||
else
|
||||
echo "❌ Failed. HTTP: $HTTP_CODE, Response: $RESPONSE_BODY"
|
||||
exit 1
|
||||
echo "⚠️ Database initialization check failed with HTTP status: $HTTP_CODE. Please check your worker logs."
|
||||
fi
|
||||
|
||||
- name: 🗑️ 删除运行记录 / Delete workflow runs
|
||||
- name: 📣 Notify Final Status
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${{ job.status }}" == "success" ]; then
|
||||
if [ "${{ steps.deploy.outputs.deployment_skipped }}" == "true" ]; then
|
||||
echo "🟡 Deployment was skipped due to missing configuration."
|
||||
else
|
||||
echo "🎉🎉🎉 Hooray! Deployment completed successfully! 🎉🎉🎉"
|
||||
fi
|
||||
else
|
||||
echo "❌❌❌ Oh no! The deployment failed. Please check the logs above for errors. ❌❌❌"
|
||||
fi
|
||||
|
||||
- name: Delete workflow runs
|
||||
uses: GitRML/delete-workflow-runs@main
|
||||
continue-on-error: true
|
||||
with:
|
||||
retain_days: '1'
|
||||
retain_days: '3'
|
||||
keep_minimum_runs: '0'
|
||||
|
||||
@@ -9,7 +9,6 @@ lerna-debug.log*
|
||||
node_modules
|
||||
dist-ssr
|
||||
*.local
|
||||
dist
|
||||
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
@@ -24,4 +23,4 @@ dist
|
||||
mail-vue/node_modules
|
||||
mail-vue/dist
|
||||
.wrangler
|
||||
.venv
|
||||
.venv
|
||||
@@ -1,143 +1,176 @@
|
||||
|
||||
<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>
|
||||
<img src="doc/demo/logo.png" width="80px" />
|
||||
</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.
|
||||
<div align="center">
|
||||
<h1>Cloud Mail</h1>
|
||||
</div>
|
||||
<div align="center">
|
||||
<h4>A responsive email service built with Vue 3 that supports email sending and can be deployed on Cloudflare. 🎉</h4>
|
||||
</div>
|
||||
|
||||
|
||||
## Project Showcase
|
||||
|
||||
- [Live Demo](https://skymail.ink)<br>
|
||||
- [Deployment Guide](https://doc.skymail.ink/en/)<br>
|
||||
[**👉 Online Demo**](https://skymail.ink)
|
||||
|
||||
[**👉 Beginner’s Guide – UI Deployment**](https://doc.skymail.ink)
|
||||
|
||||
|  |  |
|
||||
|--------------------------|--------------------------|
|
||||
|--------------------------|---------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
## 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.
|
||||
- **📧 Email Sending**: Integrated with Resend for bulk email sending, embedded images, attachments, and status tracking.
|
||||
|
||||
- **🛡️ Admin Features**: Admin controls for user and email management with RBAC-based access control.
|
||||
- **🛡️ Admin Features**: Admins can manage users and emails, with RBAC permission control to limit access to features and resources.
|
||||
|
||||
- **🔀 Multiple Accounts**: Users can add multiple email accounts.
|
||||
|
||||
- **📦 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
|
||||
- **📈 Data Visualization**: Use Echarts to visualize system data, including user email growth.
|
||||
|
||||
- **🔢 Verification Code Recognition**: Auto-detect codes via Workers AI
|
||||
|
||||
- **📈 Data Visualization**: Use ECharts to visualize system data, including user email growth.
|
||||
- **⭐ Starred Emails**: Mark important emails for quick access.
|
||||
|
||||
- **🎨 Personalization**: Customize website title, login background, and transparency.
|
||||
|
||||
- **⚙️ Feature Settings**: Toggle on or off features like registration, email sending, and more, with the option to make the site private.
|
||||
|
||||
- **🤖 CAPTCHA**: Integrated with Turnstile CAPTCHA to prevent automated registration.
|
||||
|
||||
- **📜 More Features**: Under development...
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/)
|
||||
- **Framework**: [Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/)
|
||||
|
||||
- **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/)
|
||||
- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/)
|
||||
|
||||
- **Email Service**: [Resend](https://resend.com/)
|
||||
|
||||
- **Cache**: [Cloudflare KV](https://developers.cloudflare.com/kv/)
|
||||
- **Caching**: [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
|
||||
## Setup Guide
|
||||
|
||||
```
|
||||
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
|
||||
### System Requirements
|
||||
|
||||
Nodejs v18.20 +
|
||||
|
||||
Cloudflare account (with a bound domain)
|
||||
|
||||
**Clone the project to your local machine:**
|
||||
``` shell
|
||||
git clone https://github.com/eoao/cloud-mail
|
||||
cd cloud-mail/mail-worker
|
||||
```
|
||||
|
||||
## Sponsor
|
||||
**Install Dependencies:**
|
||||
```shell
|
||||
npm i
|
||||
```
|
||||
|
||||
<a href="https://doc.skymail.ink/support.html">
|
||||
**Configure the Project**
|
||||
|
||||
mail-worker/wrangler.toml
|
||||
|
||||
```toml
|
||||
[[d1_databases]]
|
||||
binding = "db" # Default binding name for D1 database, cannot be changed
|
||||
database_name = "" # Database name
|
||||
database_id = "" # Database ID
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "kv" # Default binding name for KV storage, cannot be changed
|
||||
id = "" # KV namespace ID
|
||||
|
||||
|
||||
[[r2_buckets]]
|
||||
binding = "r2" # Default binding name for R2 storage, cannot be changed
|
||||
bucket_name = "" # R2 bucket name
|
||||
|
||||
[assets]
|
||||
binding = "assets" # Static asset binding name, cannot be changed
|
||||
directory = "./dist" # Directory for frontend Vue project build, default: dist
|
||||
|
||||
[vars]
|
||||
orm_log = false
|
||||
domain = [] # Configure email domains, example: ["example1.com", "example2.com"]
|
||||
admin = "" # Admin email, example: "[email protected]"
|
||||
jwt_secret = "" # JWT secret for login tokens, choose a random string
|
||||
```
|
||||
|
||||
**Deploy Remotely**
|
||||
|
||||
1. Create KV, D1 database, and R2 object storage in Cloudflare Console.
|
||||
2. In the project directory `mail-worker/wrangler.toml`, configure the environment variables and database IDs/names.
|
||||
3. Run the deployment command:
|
||||
|
||||
```shell
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
4. In Cloudflare → Account Home → Your Domain → Email → Email Routing → Route Rules → Catch-all Address, edit and route to the worker.
|
||||
|
||||
5. In your browser, visit `https://your-project-domain/api/init/your-jwt-secret` to initialize or update the D1 and KV databases.
|
||||
|
||||
6. After deployment, log in to the site with the admin account to configure R2 domains, Turnstile keys, and more.
|
||||
|
||||
|
||||
**Run Locally**
|
||||
|
||||
1. Run locally. Databases and object storage will automatically be set up, no manual creation needed. Data is stored in the `mail-worker/.wrangler` folder.
|
||||
|
||||
```shell
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. In your browser, visit `http://127.0.0.1:8787/api/init/your-jwt-secret` to initialize D1 and KV databases.
|
||||
|
||||
3. For local testing, you can set the R2 domain to `http://127.0.0.1:8787/api/file`.
|
||||
|
||||
**Email Sending**
|
||||
|
||||
1. Register on Resend, then click on “Domains” to add and verify your domain. Wait for verification.
|
||||
|
||||
2. Go to "API Keys" to create an API key, then copy the token and paste it in the project website settings.
|
||||
|
||||
3. Go to "Webhooks" and add a callback URL `https://your-project-domain/api/webhooks`.
|
||||
Select the following events: ✅ (email.bounced, email.complained, email.delivered, email.delivery_delayed).
|
||||
|
||||
|
||||
**Project Update**
|
||||
|
||||
After the update, run `https://your-project-domain/api/init/your-jwt-secret` to synchronize the database schema.
|
||||
|
||||
## Support
|
||||
|
||||
<a href="https://support.skymail.ink">
|
||||
<img width="170px" src="./doc/images/support.png" alt="">
|
||||
</a>
|
||||
</a><br><br>
|
||||
|
||||
|
||||
**Special Sponsors**
|
||||
|
||||
[DartNode](https://dartnode.com):Providing cloud computing service resource support
|
||||
|
||||
[](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,90 +1,75 @@
|
||||
<p align="center">
|
||||
<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>
|
||||
<img src="doc/demo/logo.png" width="80px" />
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
<h1>Cloud Mail</h1>
|
||||
</div>
|
||||
<div align="center">
|
||||
<h4>使用Vue3开发的响应式简约邮箱服务,支持邮件发送附件收发,可以部署到Cloudflare云平台实现免费白嫖🎉</h4>
|
||||
</div>
|
||||
<div align="center">
|
||||
<span>简体中文 | <a href="/README-en.md" style="margin-left: 5px">English </a></span>
|
||||
</div>
|
||||
|
||||
## 项目简介
|
||||
|
||||
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台,本项目支持署到 Cloudflare Workers ,降低服务器成本,搭建自己的邮箱服务
|
||||
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台 QQ邮箱,谷歌邮箱等,本项目使用Cloud flare部署,Resend推送邮件,无需服务器费用,搭建属于自己的邮箱服务
|
||||
|
||||
## 项目展示
|
||||
## 项目展示
|
||||
|
||||
- [在线演示](https://skymail.ink)<br>
|
||||
- [部署文档](https://doc.skymail.ink)<br>
|
||||
[**👉 在线演示**](https://skymail.ink)
|
||||
|
||||
[**👉 小白保姆教程-界面部署**](https://doc.skymail.ink)
|
||||
|
||||
|  |  |
|
||||
|-----------------------|-----------------------|
|
||||
|  |  |
|
||||
|--------------------------|---------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
|
||||
## 功能介绍
|
||||
|
||||
- **💰 低成本使用**: 可部署到 Cloudflare Workers 降低服务器成本
|
||||
- **💰免费白嫖**:无需服务器,部署到Cloudflare Workers 免费使用,不要钱
|
||||
|
||||
- **💻 响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
|
||||
- **💻响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
|
||||
|
||||
- **📧 邮件发送**:集成Resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
|
||||
- **📧邮件发送**:集成resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
|
||||
|
||||
- **🛡️ 管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
|
||||
- **🛡️管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
|
||||
|
||||
- **📦 附件收发**:支持收发附件,使用R2对象存储保存和下载文件
|
||||
- **🔀多号模式**:开启后一个用户可以添加多个邮箱,默认一用户一邮箱,类似各大邮箱平台
|
||||
|
||||
- **🔔 邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
|
||||
- **📦附件收发**:支持收发附件,使用R2对象存储保存和下载文件
|
||||
|
||||
- **📡 开放API**:支持使用API批量生成用户,多条件查询邮件
|
||||
- **🔔邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
|
||||
|
||||
- **🔢 验证码识别**:使用Workers AI,自动识别邮件验证码
|
||||
- **📈数据可视化**:使用echarts对系统数据详情,用户邮件增长可视化显示
|
||||
|
||||
- **📈 数据可视化**:使用ECharts对系统数据详情,用户邮件增长可视化显示
|
||||
- **⭐星标邮件**:标记重要邮件,以便快速查阅
|
||||
|
||||
- **🎨 个性化设置**:可以自定义网站标题,登录背景,透明度
|
||||
- **🎨个性化设置**:可以自定义网站标题,登录背景,透明度
|
||||
|
||||
- **🤖 人机验证**:集成Turnstile人机验证,防止人机批量注册
|
||||
- **⚙️功能设置**:可以对注册,邮件发送,添加等功能关闭和开启,设为私人站点
|
||||
|
||||
- **📜 更多功能**:正在开发中...
|
||||
- **🤖人机验证**:集成Turnstile人机验证,防止人机批量注册
|
||||
|
||||
- **📜更多功能**:正在开发中...
|
||||
|
||||
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **平台**:[Cloudflare Workers](https://developers.cloudflare.com/workers/)
|
||||
- **框架**:[Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/)
|
||||
|
||||
- **Web框架**:[Hono](https://hono.dev/)
|
||||
|
||||
- **ORM:**[Drizzle](https://orm.drizzle.team/)
|
||||
|
||||
- **前端框架**:[Vue3](https://vuejs.org/)
|
||||
|
||||
- **UI框架**:[Element Plus](https://element-plus.org/)
|
||||
- **平台:** [Cloudflare workers](https://developers.cloudflare.com/workers/)
|
||||
|
||||
- **邮件推送:** [Resend](https://resend.com/)
|
||||
|
||||
@@ -94,56 +79,120 @@
|
||||
|
||||
- **文件存储**:[Cloudflare R2](https://developers.cloudflare.com/r2/)
|
||||
|
||||
## 目录结构
|
||||
|
||||
|
||||
|
||||
|
||||
## 使用教程
|
||||
|
||||
### 环境要求
|
||||
|
||||
Nodejs v18.20 +
|
||||
|
||||
Cloudflare 账号 (需要绑定域名)
|
||||
|
||||
|
||||
**克隆项目到本地**
|
||||
``` shell
|
||||
git clone https://github.com/eoao/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 = "" #登录身份令牌的密钥,随便填一串字符串
|
||||
|
||||
```
|
||||
cloud-mail
|
||||
├── mail-worker # worker后端项目
|
||||
│ ├── src
|
||||
│ │ ├── 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 # 项目配置
|
||||
```
|
||||
|
||||
|
||||
|
||||
**远程部署**
|
||||
|
||||
1. 在 Cloudflare 控制台创建KV,D1数据库,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密钥 等
|
||||
|
||||
|
||||
[👉 使用 Github Action 部署](/doc/github-action.md)
|
||||
|
||||
**本地运行**
|
||||
|
||||
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`
|
||||
|
||||
**邮件发送**
|
||||
|
||||
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)
|
||||
|
||||
**项目更新**
|
||||
|
||||
更新后需要执行 `https://你的项目域名/api/init/你的jwt_secret` 来同步数据库结构
|
||||
|
||||
## 赞助
|
||||
|
||||
<a href="https://doc.skymail.ink/support.html" >
|
||||
|
||||
<a href="https://support.skymail.ink" >
|
||||
<img width="170px" src="./doc/images/support.png" alt="">
|
||||
</a>
|
||||
</a><br><br>
|
||||
|
||||
|
||||
**特别赞助商**
|
||||
|
||||
[DartNode](https://dartnode.com):提供云计算服务资源支持
|
||||
|
||||
[](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
|
||||
|
||||
## 许可证
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 450 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 525 KiB After Width: | Height: | Size: 461 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 252 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 64 KiB |
@@ -1,4 +1,3 @@
|
||||
NODE_ENV = 'dev'
|
||||
VITE_APP_TITLE = '开发环境'
|
||||
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
|
||||
VITE_PWA_NAME = 'Cloud Mail'
|
||||
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
|
||||
@@ -1,5 +1,3 @@
|
||||
NODE_ENV = 'release'
|
||||
VITE_APP_TITLE = '发布环境'
|
||||
VITE_BASE_URL = '/api'
|
||||
VITE_PWA_NAME = 'Cloud Mail'
|
||||
VITE_OUT_DIR = ../mail-worker/dist
|
||||
VITE_BASE_URL = '/api'
|
||||
@@ -1,4 +1,3 @@
|
||||
NODE_ENV = 'remote'
|
||||
VITE_APP_TITLE = '远程环境'
|
||||
VITE_BASE_URL = 'https://skymail.ink/api'
|
||||
VITE_PWA_NAME = 'Cloud Mail'
|
||||
VITE_BASE_URL = 'https://mornglow.top/api'
|
||||
@@ -1,139 +1,97 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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>
|
||||
<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">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
|
||||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></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">
|
||||
<img class="loading-image" src="/mail-pwa.png" alt="Cloud Mail">
|
||||
<div class="loading-progress" aria-hidden="true"></div>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -7,23 +7,19 @@
|
||||
"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.15.2",
|
||||
"axios": "^1.7.8",
|
||||
"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.13.1",
|
||||
"element-plus": "^2.9.11",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"path": "^0.12.7",
|
||||
"pinia": "^3.0.2",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
@@ -38,7 +34,6 @@
|
||||
"terser": "^5.39.0",
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
"unplugin-vue-components": "^28.7.0",
|
||||
"vite": "7.1.5",
|
||||
"vite-plugin-pwa": "^1.0.3"
|
||||
"vite": "6.3.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/assets/*
|
||||
Cache-Control: public, max-age=31556952, immutable
|
||||
/tinymce/*
|
||||
Cache-Control: public, max-age=604800, immutable
|
||||
/image/*
|
||||
Cache-Control: public, max-age=604800, immutable
|
||||
|
Before Width: | Height: | Size: 622 B |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,55 +0,0 @@
|
||||
.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;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
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
|
||||
@@ -1 +1,4 @@
|
||||
!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.")}))}();
|
||||
/**
|
||||
* 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.")}))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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 +1,4 @@
|
||||
!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)}))}();
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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 +1,4 @@
|
||||
/**
|
||||
* 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))))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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),{})))}();
|
||||
@@ -1 +1,4 @@
|
||||
!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)}))}();
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1 +1,4 @@
|
||||
!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))))}();
|
||||
/**
|
||||
* 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))))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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(" ",e)}</span>`:r(" ",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 +1,4 @@
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1 +1,4 @@
|
||||
/**
|
||||
* 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)}))}();
|
||||
@@ -1,10 +1 @@
|
||||
/* 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}`)
|
||||
@@ -1,10 +1 @@
|
||||
/* 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}
|
||||
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}
|
||||
|
||||
@@ -1,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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,10 +1 @@
|
||||
/* 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}
|
||||
|
||||