@paroicms/quill-editor-plugin 1.23.2 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/backend/dist/plugin.js
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const version = (0, data_formatters_lib_1.strVal)(require((0, node_path_1.join)(packageDir, "package.json")).version);
|
|
1
|
+
import { isObj, strVal } from "@paroi/data-formatters-lib";
|
|
2
|
+
import { escapeHtml, resolveModuleDirectory, } from "@paroicms/public-server-lib";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { convertQuillDeltaToHtml, convertQuillDeltaToPlainText } from "./quill-delta.js";
|
|
6
|
+
const projectDir = resolveModuleDirectory(import.meta.url, { parent: true });
|
|
7
|
+
const packageDir = dirname(projectDir);
|
|
8
|
+
const version = strVal(JSON.parse(readFileSync(join(packageDir, "package.json"), "utf-8")).version);
|
|
10
9
|
const plugin = {
|
|
11
10
|
version,
|
|
12
11
|
siteInit(service) {
|
|
13
|
-
service.setPublicAssetsDirectory(
|
|
14
|
-
service.setBoAssetsDirectory(
|
|
15
|
-
service.registerSiteSchemaLibrary(
|
|
12
|
+
service.setPublicAssetsDirectory(join(packageDir, "public-front", "dist"));
|
|
13
|
+
service.setBoAssetsDirectory(join(packageDir, "bo-front", "dist"));
|
|
14
|
+
service.registerSiteSchemaLibrary(join(packageDir, "site-schema-lib"));
|
|
16
15
|
service.registerFieldPreprocessor("quillDelta", (service, value, options) => {
|
|
17
|
-
if (!
|
|
16
|
+
if (!isObj(value) || !isObj(value.delta))
|
|
18
17
|
return;
|
|
19
18
|
const delta = value.delta;
|
|
20
19
|
if (options.outputType === "plainText")
|
|
21
|
-
return
|
|
22
|
-
return
|
|
20
|
+
return convertQuillDeltaToPlainText(service, delta);
|
|
21
|
+
return convertQuillDeltaToHtml(service, delta, options);
|
|
23
22
|
});
|
|
24
|
-
service.addHeadTag(`<link rel="stylesheet" href="${
|
|
23
|
+
service.addHeadTag(`<link rel="stylesheet" href="${escapeHtml(`${service.pluginAssetsUrl}/public-front-plugin.css`)}">`, `<script type="module" src="${escapeHtml(`${service.pluginAssetsUrl}/public-front-plugin.mjs`)}"></script>`);
|
|
25
24
|
if (service.pluginConf.backOffice?.code) {
|
|
26
25
|
service.addHeadTag(`<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/styles/default.min.css">`, `<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/highlight.min.js"></script>`, `<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/languages/typescript.min.js"></script>`, `<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/languages/javascript.min.js"></script>`, `<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/languages/xml.min.js"></script>`, `<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/languages/json.min.js"></script>`, `<script>
|
|
27
26
|
hljs.highlightAll();
|
|
@@ -36,4 +35,4 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
36
35
|
}
|
|
37
36
|
},
|
|
38
37
|
};
|
|
39
|
-
|
|
38
|
+
export default plugin;
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const data_formatters_lib_1 = require("@paroi/data-formatters-lib");
|
|
6
|
-
const quill_delta_to_html_1 = require("@paroi/quill-delta-to-html");
|
|
7
|
-
const public_server_lib_1 = require("@paroicms/public-server-lib");
|
|
8
|
-
async function convertQuillDeltaToHtml(service, delta, options) {
|
|
1
|
+
import { nbValOrUndef, strVal, strValOrUndef } from "@paroi/data-formatters-lib";
|
|
2
|
+
import { QuillDeltaToHtmlAsyncConverter, QuillDeltaToHtmlConverter, } from "@paroi/quill-delta-to-html";
|
|
3
|
+
import { applyRatioToImageSize, escapeHtml, generateObfuscatedHtml, isImageSize, obfuscateAsHtmlLink, stripHtmlTags, toAbsoluteUrl, } from "@paroicms/public-server-lib";
|
|
4
|
+
export async function convertQuillDeltaToHtml(service, delta, options) {
|
|
9
5
|
const ops = delta.ops;
|
|
10
6
|
preprocessDelta(ops);
|
|
11
|
-
const converter = new
|
|
7
|
+
const converter = new QuillDeltaToHtmlAsyncConverter(ops, {
|
|
12
8
|
multiLineParagraph: false,
|
|
13
9
|
linkTarget: (href) => {
|
|
14
10
|
if (href.startsWith("/"))
|
|
@@ -41,8 +37,8 @@ async function convertQuillDeltaToHtml(service, delta, options) {
|
|
|
41
37
|
});
|
|
42
38
|
return await converter.convert();
|
|
43
39
|
}
|
|
44
|
-
function convertQuillDeltaToPlainText(service, delta) {
|
|
45
|
-
const converter = new
|
|
40
|
+
export function convertQuillDeltaToPlainText(service, delta) {
|
|
41
|
+
const converter = new QuillDeltaToHtmlConverter(delta.ops);
|
|
46
42
|
converter.renderCustomWith((customOp) => {
|
|
47
43
|
const { type, value } = customOp.insert;
|
|
48
44
|
if (type === "html-snippet")
|
|
@@ -57,36 +53,38 @@ function convertQuillDeltaToPlainText(service, delta) {
|
|
|
57
53
|
return "";
|
|
58
54
|
});
|
|
59
55
|
const html = converter.convert();
|
|
60
|
-
return
|
|
56
|
+
return stripHtmlTags(html, { blockSeparator: " – " });
|
|
61
57
|
}
|
|
62
58
|
async function imgBlotProcessing(service, value, options) {
|
|
63
59
|
const { themeConf, useImage, logger } = service;
|
|
64
|
-
const uid =
|
|
65
|
-
const variant =
|
|
66
|
-
const align =
|
|
67
|
-
const zoom =
|
|
60
|
+
const uid = strValOrUndef(value.uid, { varName: "uid" });
|
|
61
|
+
const variant = strValOrUndef(value.variant, { varName: "variant" });
|
|
62
|
+
const align = strValOrUndef(value.align);
|
|
63
|
+
const zoom = strValOrUndef(value.zoom);
|
|
68
64
|
const hasZoom = zoom !== "none";
|
|
65
|
+
const href = strValOrUndef(value.href, { varName: "href" });
|
|
69
66
|
let imgAttributes;
|
|
70
|
-
if (uid && variant &&
|
|
71
|
-
const realSize =
|
|
67
|
+
if (uid && variant && isImageSize(variant)) {
|
|
68
|
+
const realSize = applyRatioToImageSize(variant, themeConf.pixelRatio);
|
|
72
69
|
const image = await useImage({ size: realSize, imageUid: uid });
|
|
73
70
|
let dataZoomSrc;
|
|
74
71
|
if (hasZoom) {
|
|
75
72
|
const zoomImage = await useImage({
|
|
76
73
|
imageUid: uid,
|
|
77
|
-
size:
|
|
74
|
+
size: applyRatioToImageSize("x1900x", themeConf.pixelRatio),
|
|
78
75
|
});
|
|
79
|
-
dataZoomSrc = options?.absoluteUrls ?
|
|
76
|
+
dataZoomSrc = options?.absoluteUrls ? toAbsoluteUrl(service, zoomImage.url) : zoomImage.url;
|
|
80
77
|
}
|
|
81
78
|
imgAttributes = {
|
|
82
79
|
dataZoomSrc,
|
|
83
|
-
src: options?.absoluteUrls ?
|
|
80
|
+
src: options?.absoluteUrls ? toAbsoluteUrl(service, image.url) : image.url,
|
|
84
81
|
width: Math.round(image.width / themeConf.pixelRatio),
|
|
85
82
|
height: Math.round(image.height / themeConf.pixelRatio),
|
|
83
|
+
href,
|
|
86
84
|
};
|
|
87
85
|
}
|
|
88
86
|
else {
|
|
89
|
-
const src =
|
|
87
|
+
const src = strValOrUndef(value.src, { varName: "src" });
|
|
90
88
|
if (!src) {
|
|
91
89
|
logger.warn("missing 'uid' and 'src' in 'img' blot");
|
|
92
90
|
return "";
|
|
@@ -94,21 +92,23 @@ async function imgBlotProcessing(service, value, options) {
|
|
|
94
92
|
imgAttributes = {
|
|
95
93
|
dataZoomSrc: hasZoom ? src : undefined,
|
|
96
94
|
src,
|
|
97
|
-
width:
|
|
98
|
-
height:
|
|
95
|
+
width: nbValOrUndef(value.width),
|
|
96
|
+
height: nbValOrUndef(value.height),
|
|
97
|
+
href,
|
|
99
98
|
};
|
|
100
99
|
}
|
|
101
100
|
const attributes = [];
|
|
102
101
|
if (imgAttributes.dataZoomSrc) {
|
|
103
|
-
attributes.push(`data-zoom-src="${
|
|
102
|
+
attributes.push(`data-zoom-src="${escapeHtml(imgAttributes.dataZoomSrc)}"`);
|
|
104
103
|
}
|
|
105
|
-
attributes.push(`src="${
|
|
106
|
-
attributes.push(`class="Img${align ? ` ${
|
|
104
|
+
attributes.push(`src="${escapeHtml(imgAttributes.src)}"`);
|
|
105
|
+
attributes.push(`class="Img${align ? ` ${escapeHtml(align)}` : ""}"`);
|
|
107
106
|
attributes.push(`loading="lazy"`);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (imgAttributes.
|
|
111
|
-
|
|
107
|
+
attributes.push(`width="${imgAttributes.width}"`);
|
|
108
|
+
attributes.push(`height="${imgAttributes.height}"`);
|
|
109
|
+
if (imgAttributes.href) {
|
|
110
|
+
return `<a href="${imgAttributes.href}"><img ${attributes.join(" ")}></a>`;
|
|
111
|
+
}
|
|
112
112
|
return `<img ${attributes.join(" ")}>`;
|
|
113
113
|
}
|
|
114
114
|
function preprocessDelta(ops) {
|
|
@@ -128,16 +128,16 @@ function preprocessDelta(ops) {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
function obfuscateBlotProcessing(value, inlineAttributes) {
|
|
131
|
-
const textVal =
|
|
131
|
+
const textVal = strValOrUndef(value);
|
|
132
132
|
if (!textVal)
|
|
133
133
|
return "";
|
|
134
|
-
const asALink = formatObfuscateAsALink(
|
|
134
|
+
const asALink = formatObfuscateAsALink(strVal(inlineAttributes.obfuscate));
|
|
135
135
|
let obfuscatedVal;
|
|
136
136
|
if (asALink === "mailto" || asALink === "tel") {
|
|
137
|
-
obfuscatedVal =
|
|
137
|
+
obfuscatedVal = obfuscateAsHtmlLink(textVal);
|
|
138
138
|
}
|
|
139
139
|
else {
|
|
140
|
-
obfuscatedVal =
|
|
140
|
+
obfuscatedVal = generateObfuscatedHtml(textVal);
|
|
141
141
|
}
|
|
142
142
|
let result = obfuscatedVal;
|
|
143
143
|
if (inlineAttributes.strike) {
|
|
@@ -161,7 +161,7 @@ function formatObfuscateAsALink(val) {
|
|
|
161
161
|
throw new Error(`invalid link-type '${val}'`);
|
|
162
162
|
}
|
|
163
163
|
function videoPluginBlotProcessing(_service, value, _options) {
|
|
164
|
-
const videoId =
|
|
164
|
+
const videoId = strValOrUndef(value);
|
|
165
165
|
if (!videoId)
|
|
166
166
|
return "";
|
|
167
167
|
return `
|
|
@@ -173,12 +173,12 @@ function videoPluginBlotProcessing(_service, value, _options) {
|
|
|
173
173
|
`;
|
|
174
174
|
}
|
|
175
175
|
async function internalLinkPluginBlotProcessing(service, value, options) {
|
|
176
|
-
const documentId =
|
|
176
|
+
const documentId = strValOrUndef(value);
|
|
177
177
|
if (!documentId)
|
|
178
178
|
return "";
|
|
179
179
|
const doc = await service.getDocument(documentId);
|
|
180
180
|
if (!doc)
|
|
181
181
|
return "";
|
|
182
182
|
const url = await doc.getUrl({ absoluteUrl: !!options?.absoluteUrls });
|
|
183
|
-
return `<a class="InternalLink" href="${url}">${
|
|
183
|
+
return `<a class="InternalLink" href="${url}">${strValOrUndef(doc.title)}</a>`;
|
|
184
184
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.QpBtn{background-color:#6366f1;border:1px solid #6366f1;border-radius:6px;color:#fff;cursor:pointer;font-size:1rem;padding:.75rem 1.25rem;transition:background-color .2s,color .2s,border-color .2s,box-shadow .2s}.QpBtn.secondary{background-color:#64748b;border:1px solid #64748b}.QpBtn.danger{background-color:#ef4444;border:1px solid #ef4444}.QpBtn.outlined{background-color:transparent;color:inherit}.QpBtn.outlined:hover{background-color:#c6c7f6}.QpBtn.secondary.outlined{color:#64748b}.QpBtn.secondary.outlined:hover{background-color:#64748b0a}.QpBtn.danger.outlined{color:#ef4444}.QpBtn.danger.outlined:hover{background-color:#ef44440a}.QpInput{appearance:none;background:#fff;border:1px solid #d1d5db;border-radius:6px;color:#4b5563;font-size:10px;padding:10px;transition:background-color .2s,color .2s,border-color .2s,box-shadow .2s}.QpInput:hover{border-color:#06b6d4}.QpInput:focus{border-color:#06b6d4;box-shadow:0 0 0 .2rem #a5f3fc;outline:0 none;outline-offset:0}.QpHtmlSnippetInput{width:100%}.QpOption{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:20px;width:100%}/*!
|
|
1
|
+
.QpBtn{background-color:#6366f1;border:1px solid #6366f1;border-radius:6px;color:#fff;cursor:pointer;font-size:1rem;padding:.75rem 1.25rem;transition:background-color .2s,color .2s,border-color .2s,box-shadow .2s}.QpBtn.secondary{background-color:#64748b;border:1px solid #64748b}.QpBtn.danger{background-color:#ef4444;border:1px solid #ef4444}.QpBtn.outlined{background-color:transparent;color:inherit}.QpBtn.outlined:hover{background-color:#c6c7f6}.QpBtn.secondary.outlined{color:#64748b}.QpBtn.secondary.outlined:hover{background-color:#64748b0a}.QpBtn.danger.outlined{color:#ef4444}.QpBtn.danger.outlined:hover{background-color:#ef44440a}.QpInput{appearance:none;background:#fff;border:1px solid #d1d5db;border-radius:6px;color:#4b5563;font-size:10px;padding:10px;transition:background-color .2s,color .2s,border-color .2s,box-shadow .2s}.QpInput:hover{border-color:#06b6d4}.QpInput:focus{border-color:#06b6d4;box-shadow:0 0 0 .2rem #a5f3fc;outline:0 none;outline-offset:0}.QpHtmlSnippetInput{width:100%}.QpOption{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:20px;width:100%}.QpOption-input{background:#fff;border:1px solid #d1d5db;border-radius:6px;color:#4b5563;font-size:1rem;padding:10px;margin-left:8px;transition:background-color .2s,color .2s,border-color .2s,box-shadow .2s}/*!
|
|
2
2
|
* Quill Editor v2.0.3
|
|
3
3
|
* https://quilljs.com
|
|
4
4
|
* Copyright (c) 2017-2024, Slab
|
|
@@ -13,4 +13,4 @@
|
|
|
13
13
|
|
|
14
14
|
Outdated base version: https://github.com/primer/github-syntax-dark
|
|
15
15
|
Current colors taken from GitHub's CSS
|
|
16
|
-
*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#79c0ff}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-comment,.hljs-code,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}.QpTooltip{border-bottom:1px dotted #64748b;display:inline-block;position:relative}.QpTooltip-text{background-color:#64748b;border-radius:6px;color:#fff;left:110%;padding:5px;position:absolute;text-align:center;top:-5px;visibility:hidden;width:120px;z-index:1}.QpTooltip-text:after{border-color:transparent #64748b transparent transparent;border-style:solid;border-width:5px;content:"";margin-top:-5px;position:absolute;right:100%;top:50%}.QpTooltip:hover .QpTooltip-text{visibility:visible}.InternalLinkPlugin{border:2px dashed rgb(241,136,6);border-radius:3px;cursor:pointer;padding:3px 5px}.ObfuscateBlot{border:2px dashed #8d5151;border-radius:3px;cursor:pointer;padding:0 2px}.VideoPlugin{align-items:center;background-position:center;background-repeat:no-repeat;border:2px dotted bisque;cursor:pointer;display:flex;height:100px;justify-content:center;margin:10px;width:100%}.VideoPlugin-playButton{background-color:red;border-radius:3px;color:#fff;padding:5px 10px}
|
|
16
|
+
*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#79c0ff}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-comment,.hljs-code,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}.QpTooltip{border-bottom:1px dotted #64748b;display:inline-block;position:relative}.QpTooltip-text{background-color:#64748b;border-radius:6px;color:#fff;left:110%;padding:5px;position:absolute;text-align:center;top:-5px;visibility:hidden;width:120px;z-index:1}.QpTooltip-text:after{border-color:transparent #64748b transparent transparent;border-style:solid;border-width:5px;content:"";margin-top:-5px;position:absolute;right:100%;top:50%}.QpTooltip:hover .QpTooltip-text{visibility:visible}.Img{display:block;margin:auto;position:relative;width:fit-content}.Img:after{bottom:10px;height:20px;position:absolute;right:10px;width:20px}.Img>img{display:block;max-width:100%;height:auto}.Img.zoomable:after{content:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M3 10a7 7 0 1 0 14 0a7 7 0 1 0-14 0m18 11l-6-6'/%3E%3C/svg%3E")}.Img.asLink:after{content:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none'%3E%3Cpath d='m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z'/%3E%3Cpath fill='%23000' d='M10.232 10.231a5 5 0 0 1 6.89-.172l.181.172l2.828 2.829a5 5 0 0 1-6.89 7.243l-.18-.172l-2.122-2.122a1 1 0 0 1 1.32-1.497l.094.083l2.122 2.122a3 3 0 0 0 4.377-4.1l-.135-.143l-2.828-2.828a3 3 0 0 0-4.243 0a1 1 0 0 1-1.414-1.415M3.868 3.867a5 5 0 0 1 6.89-.172l.181.172L13.06 5.99a1 1 0 0 1-1.32 1.497l-.094-.083l-2.121-2.121A3 3 0 0 0 5.147 9.38l.135.144l2.829 2.829a3 3 0 0 0 4.242 0a1 1 0 1 1 1.415 1.414a5 5 0 0 1-6.89.172l-.182-.172l-2.828-2.829a5 5 0 0 1 0-7.07Z'/%3E%3C/g%3E%3C/svg%3E")}.InternalLinkPlugin{border:2px dashed rgb(241,136,6);border-radius:3px;cursor:pointer;padding:3px 5px}.ObfuscateBlot{border:2px dashed #8d5151;border-radius:3px;cursor:pointer;padding:0 2px}.VideoPlugin{align-items:center;background-position:center;background-repeat:no-repeat;border:2px dotted bisque;cursor:pointer;display:flex;height:100px;justify-content:center;margin:10px;width:100%}.VideoPlugin-playButton{background-color:red;border-radius:3px;color:#fff;padding:5px 10px}
|