@kookaat/strapi-plugin-tinymce 2.0.1 → 2.0.3

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.
Files changed (33) hide show
  1. package/dist/_chunks/Settings-Cht7TW_m.js +2606 -0
  2. package/dist/_chunks/Settings-Cht7TW_m.js.map +1 -0
  3. package/dist/_chunks/Settings-CqdUA2s3.mjs +2606 -0
  4. package/dist/_chunks/Settings-CqdUA2s3.mjs.map +1 -0
  5. package/dist/_chunks/Wysiwyg-Bo6uIgVq.mjs +130 -0
  6. package/dist/_chunks/Wysiwyg-Bo6uIgVq.mjs.map +1 -0
  7. package/dist/_chunks/Wysiwyg-C1NARvA-.js +130 -0
  8. package/dist/_chunks/Wysiwyg-C1NARvA-.js.map +1 -0
  9. package/dist/_chunks/cs-4ldo0hfI.js +15 -0
  10. package/dist/_chunks/cs-4ldo0hfI.js.map +1 -0
  11. package/dist/_chunks/cs-D-gwbfRH.mjs +15 -0
  12. package/dist/_chunks/cs-D-gwbfRH.mjs.map +1 -0
  13. package/dist/_chunks/en-BILT6xrd.mjs +15 -0
  14. package/dist/_chunks/en-BILT6xrd.mjs.map +1 -0
  15. package/dist/_chunks/en-usAdfkfH.js +15 -0
  16. package/dist/_chunks/en-usAdfkfH.js.map +1 -0
  17. package/dist/_chunks/index-4S82exqN.js +248 -0
  18. package/dist/_chunks/index-4S82exqN.js.map +1 -0
  19. package/dist/_chunks/index-Bc87VSN0.mjs +247 -0
  20. package/dist/_chunks/index-Bc87VSN0.mjs.map +1 -0
  21. package/dist/_chunks/sk-BcD0BjAU.js +15 -0
  22. package/dist/_chunks/sk-BcD0BjAU.js.map +1 -0
  23. package/dist/_chunks/sk-D3I3bI3P.mjs +15 -0
  24. package/dist/_chunks/sk-D3I3bI3P.mjs.map +1 -0
  25. package/dist/admin/index.js +4 -0
  26. package/dist/admin/index.js.map +1 -0
  27. package/dist/admin/index.mjs +5 -0
  28. package/dist/admin/index.mjs.map +1 -0
  29. package/dist/server/index.js +298 -0
  30. package/dist/server/index.js.map +1 -0
  31. package/dist/server/index.mjs +299 -0
  32. package/dist/server/index.mjs.map +1 -0
  33. package/package.json +4 -3
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const icons = require("@strapi/icons");
7
+ const tinymceReact = require("@tinymce/tinymce-react");
8
+ const index = require("./index-4S82exqN.js");
9
+ const admin = require("@strapi/strapi/admin");
10
+ const prefixFileUrlWithBackendUrl = (path, url = window.strapi.backendURL || "http://localhost:1337") => {
11
+ if (path?.startsWith("http")) {
12
+ return path;
13
+ }
14
+ if (url) {
15
+ return url + path;
16
+ } else {
17
+ return path;
18
+ }
19
+ };
20
+ const TinyEditor = ({ onChange, name, value, disabled }) => {
21
+ const { get, post } = admin.useFetchClient();
22
+ const [pluginConfig, setPluginConfig] = react.useState(null);
23
+ prefixFileUrlWithBackendUrl("/api/upload", pluginConfig?.data?.defaultAdminDomain || "");
24
+ react.useEffect(() => {
25
+ const getPluginConfig = async () => {
26
+ const editor = await get(`/${index.PLUGIN_ID}/config/editor`);
27
+ if (editor) {
28
+ setPluginConfig(editor);
29
+ }
30
+ };
31
+ getPluginConfig();
32
+ }, []);
33
+ const imageUploadHandler = react.useCallback(
34
+ async (blobInfo) => {
35
+ const data = new FormData();
36
+ data.append("files", blobInfo.blob(), blobInfo.filename());
37
+ try {
38
+ const res = await post(`/${index.PLUGIN_ID}/uploadImage`, data);
39
+ return res.data.location;
40
+ } catch (error) {
41
+ console.error("Image upload failed:", error);
42
+ throw error;
43
+ }
44
+ },
45
+ [post]
46
+ );
47
+ return pluginConfig?.data ? /* @__PURE__ */ jsxRuntime.jsx(
48
+ tinymceReact.Editor,
49
+ {
50
+ tinymceScriptSrc: pluginConfig?.data?.tinymceSrc || void 0,
51
+ value,
52
+ tagName: name,
53
+ onEditorChange: (editorContent) => {
54
+ onChange({ target: { name, value: editorContent } });
55
+ },
56
+ init: {
57
+ images_upload_handler: imageUploadHandler,
58
+ ...pluginConfig?.data?.editorConfig
59
+ }
60
+ }
61
+ ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
62
+ };
63
+ const MediaLib = ({ isOpen, onChange, onToggle }) => {
64
+ const mediaLibraryDialog = admin.useStrapiApp("mediaLibrary", (state) => state.components);
65
+ const MediaDialog = mediaLibraryDialog["media-library"];
66
+ const handleSelectAssets = (files) => {
67
+ const formattedFiles = files.map((f) => ({
68
+ alt: f.alternativeText || f.name,
69
+ url: prefixFileUrlWithBackendUrl(f.url),
70
+ mime: f.mime
71
+ }));
72
+ if (onChange)
73
+ onChange(formattedFiles);
74
+ };
75
+ if (!isOpen) {
76
+ return null;
77
+ }
78
+ return /* @__PURE__ */ jsxRuntime.jsx(MediaDialog, { onClose: onToggle, onSelectAssets: handleSelectAssets });
79
+ };
80
+ const Wysiwyg = ({ name, onChange, value, label, disabled, error, required, hint, attribute }) => {
81
+ const localized = Boolean(attribute?.pluginOptions?.i18n?.localized || false);
82
+ const [mediaLibVisible, setMediaLibVisible] = react.useState(false);
83
+ const handleToggleMediaLib = () => setMediaLibVisible((prev) => !prev);
84
+ const handleChangeAssets = (assets) => {
85
+ let newValue = value ? value : "";
86
+ assets.map((asset) => {
87
+ if (asset.mime.includes("image")) {
88
+ const imgTag = `<p><img src="${asset.url}" alt="${asset.alt}"></img></p>`;
89
+ newValue = `${newValue}${imgTag}`;
90
+ }
91
+ if (asset.mime.includes("video")) {
92
+ const videoTag = `<video><source src="${asset.url}" alt="${asset.alt}"</source></video>`;
93
+ newValue = `${newValue}${videoTag}`;
94
+ }
95
+ });
96
+ onChange({ target: { name, value: newValue } });
97
+ handleToggleMediaLib();
98
+ };
99
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
100
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
101
+ label && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingBottom: 1, children: [
102
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
103
+ required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "danger600", children: "*" }),
104
+ localized && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { paddingLeft: 1, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Earth, { width: 12, height: 12 }) })
105
+ ] }),
106
+ /* @__PURE__ */ jsxRuntime.jsx(
107
+ designSystem.Button,
108
+ {
109
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Image, {}),
110
+ variant: "secondary",
111
+ fullWidth: true,
112
+ onClick: handleToggleMediaLib,
113
+ children: "Media library"
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsxRuntime.jsx(TinyEditor, { disabled: Boolean(disabled), name, onChange, value }),
117
+ (error || hint) && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, children: error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", children: error }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: hint }) })
118
+ ] }),
119
+ /* @__PURE__ */ jsxRuntime.jsx(
120
+ MediaLib,
121
+ {
122
+ isOpen: mediaLibVisible,
123
+ onChange: handleChangeAssets,
124
+ onToggle: handleToggleMediaLib
125
+ }
126
+ )
127
+ ] });
128
+ };
129
+ exports.default = Wysiwyg;
130
+ //# sourceMappingURL=Wysiwyg-C1NARvA-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Wysiwyg-C1NARvA-.js","sources":["../../admin/src/utils/prefixFileUrlWithBackendUrl.ts","../../admin/src/components/Editor.tsx","../../admin/src/components/MediaLib.tsx","../../admin/src/components/Wysiwyg.tsx"],"sourcesContent":["export const prefixFileUrlWithBackendUrl = (\r\n path: string,\r\n url = window.strapi.backendURL || 'http://localhost:1337',\r\n) => {\r\n if (path?.startsWith('http')) {\r\n // Path is already a full URL. No prefix possible.\r\n return path;\r\n }\r\n\r\n if (url) {\r\n return url + path;\r\n } else {\r\n return path;\r\n }\r\n};\r\n","import { useCallback, useEffect, useState } from 'react';\r\nimport { Editor, IAllProps } from '@tinymce/tinymce-react';\r\nimport { PLUGIN_ID } from '../pluginId';\r\nimport taskRequests from '../api/settings';\r\nimport { useFetchClient } from '@strapi/strapi/admin';\r\nimport { prefixFileUrlWithBackendUrl } from '../utils/prefixFileUrlWithBackendUrl';\r\n\r\ninterface TinyEditorProps {\r\n onChange: (e: any) => void;\r\n name: string;\r\n value?: string;\r\n disabled?: boolean;\r\n}\r\n\r\ntype InitOptions = NonNullable<IAllProps['init']>;\r\n\r\nconst TinyEditor = ({ onChange, name, value, disabled }: TinyEditorProps) => {\r\n const { get, post } = useFetchClient();\r\n\r\n const [pluginConfig, setPluginConfig] = useState<any>(null);\r\n const uploadUrl = prefixFileUrlWithBackendUrl('/api/upload', pluginConfig?.data?.defaultAdminDomain || '');\r\n\r\n useEffect(() => {\r\n const getPluginConfig = async () => {\r\n const editor = await get(`/${PLUGIN_ID}/config/editor`);\r\n if (editor) {\r\n setPluginConfig(editor);\r\n }\r\n };\r\n getPluginConfig();\r\n }, []);\r\n\r\n const imageUploadHandler = useCallback<NonNullable<InitOptions['images_upload_handler']>>(\r\n async (blobInfo) => {\r\n const data = new FormData();\r\n\r\n data.append('files', blobInfo.blob(), blobInfo.filename());\r\n\r\n try {\r\n const res = await post<{ location: string }>(`/${PLUGIN_ID}/uploadImage`, data);\r\n\r\n return res.data.location;\r\n } catch (error) {\r\n console.error('Image upload failed:', error);\r\n\r\n throw error;\r\n }\r\n },\r\n [post],\r\n );\r\n\r\n return pluginConfig?.data ? (\r\n <Editor\r\n tinymceScriptSrc={pluginConfig?.data?.tinymceSrc || undefined}\r\n value={value}\r\n tagName={name}\r\n onEditorChange={(editorContent) => {\r\n onChange({ target: { name, value: editorContent } });\r\n }}\r\n init={{\r\n images_upload_handler: imageUploadHandler,\r\n ...pluginConfig?.data?.editorConfig,\r\n }}\r\n />\r\n ) : (\r\n <></>\r\n );\r\n};\r\n\r\nexport default TinyEditor;\r\n","import React from 'react';\r\nimport { prefixFileUrlWithBackendUrl } from '../utils/prefixFileUrlWithBackendUrl';\r\nimport { useStrapiApp } from '@strapi/strapi/admin';\r\n\r\ninterface MediaLibProps {\r\n isOpen?: boolean;\r\n onChange?: (e: any) => void;\r\n onToggle?: () => void;\r\n}\r\n\r\nconst MediaLib = ({ isOpen, onChange, onToggle }: MediaLibProps) => {\r\n const mediaLibraryDialog = useStrapiApp('mediaLibrary', (state: any) => state.components);\r\n const MediaDialog = mediaLibraryDialog['media-library'];\r\n\r\n\r\n const handleSelectAssets = (files: any) => {\r\n const formattedFiles = files.map((f: any) => ({\r\n alt: f.alternativeText || f.name,\r\n url: prefixFileUrlWithBackendUrl(f.url),\r\n mime: f.mime,\r\n }));\r\n\r\n if (onChange) onChange(formattedFiles);\r\n };\r\n\r\n if (!isOpen) {\r\n return null;\r\n }\r\n\r\n return <MediaDialog onClose={onToggle} onSelectAssets={handleSelectAssets} />;\r\n};\r\n\r\nexport default MediaLib;\r\n","import React, { useState } from 'react';\r\nimport { Box, Button, Flex, Typography } from '@strapi/design-system';\r\nimport { Earth, Image } from '@strapi/icons';\r\nimport TinyEditor from './Editor';\r\nimport MediaLib from './MediaLib';\r\n\r\ninterface WysiwygProps {\r\n disabled?: boolean;\r\n error?: string;\r\n name: string;\r\n onChange: (e: any) => void;\r\n required?: boolean;\r\n label?: string;\r\n placeholder?: string;\r\n hint?: string;\r\n value?: any;\r\n attribute?: any;\r\n}\r\n\r\nconst Wysiwyg = ({ name, onChange, value, label, disabled, error, required, hint, attribute }: WysiwygProps) => {\r\n const localized = Boolean(attribute?.pluginOptions?.i18n?.localized || false);\r\n const [mediaLibVisible, setMediaLibVisible] = useState(false);\r\n\r\n const handleToggleMediaLib = () => setMediaLibVisible((prev) => !prev);\r\n\r\n const handleChangeAssets = (assets: any) => {\r\n let newValue = value ? value : \"\";\r\n\r\n assets.map((asset: any) => {\r\n if (asset.mime.includes(\"image\")) {\r\n const imgTag = `<p><img src=\"${asset.url}\" alt=\"${asset.alt}\"></img></p>`;\r\n newValue = `${newValue}${imgTag}`;\r\n }\r\n if (asset.mime.includes(\"video\")) {\r\n const videoTag = `<video><source src=\"${asset.url}\" alt=\"${asset.alt}\"</source></video>`;\r\n newValue = `${newValue}${videoTag}`;\r\n }\r\n });\r\n\r\n onChange({ target: {name, value: newValue } });\r\n handleToggleMediaLib();\r\n };\r\n\r\n return (\r\n <>\r\n <Box>\r\n {label && (\r\n <Flex paddingBottom={1}>\r\n <Typography variant=\"pi\" fontWeight=\"bold\" textColor=\"neutral800\">\r\n {label}\r\n </Typography>\r\n {required && (\r\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor=\"danger600\">\r\n *\r\n </Typography>\r\n )}\r\n {localized && (\r\n <Flex paddingLeft={1}>\r\n <Earth width={12} height={12}/>\r\n </Flex>\r\n )}\r\n </Flex>\r\n )}\r\n <Button\r\n startIcon={<Image/>}\r\n variant=\"secondary\"\r\n fullWidth\r\n onClick={handleToggleMediaLib}\r\n >\r\n Media library\r\n </Button>\r\n <TinyEditor disabled={Boolean(disabled)} name={name} onChange={onChange} value={value}/>\r\n {(error || hint) && (\r\n <Box paddingTop={1}>\r\n {error ? (\r\n <Typography variant=\"pi\" textColor=\"danger600\">\r\n {error}\r\n </Typography>\r\n ) : (\r\n <Typography variant=\"pi\" textColor=\"neutral600\">\r\n {hint}\r\n </Typography>\r\n )}\r\n </Box>\r\n )}\r\n </Box>\r\n <MediaLib\r\n isOpen={mediaLibVisible}\r\n onChange={handleChangeAssets}\r\n onToggle={handleToggleMediaLib}\r\n />\r\n </>\r\n );\r\n};\r\n\r\nexport default Wysiwyg;\r\n"],"names":["useFetchClient","useState","useEffect","PLUGIN_ID","useCallback","jsx","Editor","Fragment","useStrapiApp","jsxs","Box","Flex","Typography","Earth","Button","Image"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const cs = {
4
+ "settings.title": "TinyMCE",
5
+ "settings.description": "TinyMCE rich text editor",
6
+ "settings.subtitle": "Úprava nastavení pluginu TinyMCE",
7
+ "settings.content-title": "Nastavení klíče API pro editor TinyMCE.",
8
+ "settings.save-button": "Uložit",
9
+ "settings.input-title": "API klíč",
10
+ "settings.input-placeholder": "např. eegrtg8464asnbvvvfasd46486asldaeerer45888areettzh",
11
+ "settings.success-message": "Nastavení bylo úspěšně uloženo.",
12
+ "settings.page-title": "Konfigurace"
13
+ };
14
+ exports.default = cs;
15
+ //# sourceMappingURL=cs-4ldo0hfI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-4ldo0hfI.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ const cs = {
2
+ "settings.title": "TinyMCE",
3
+ "settings.description": "TinyMCE rich text editor",
4
+ "settings.subtitle": "Úprava nastavení pluginu TinyMCE",
5
+ "settings.content-title": "Nastavení klíče API pro editor TinyMCE.",
6
+ "settings.save-button": "Uložit",
7
+ "settings.input-title": "API klíč",
8
+ "settings.input-placeholder": "např. eegrtg8464asnbvvvfasd46486asldaeerer45888areettzh",
9
+ "settings.success-message": "Nastavení bylo úspěšně uloženo.",
10
+ "settings.page-title": "Konfigurace"
11
+ };
12
+ export {
13
+ cs as default
14
+ };
15
+ //# sourceMappingURL=cs-D-gwbfRH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-D-gwbfRH.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ const en = {
2
+ "settings.title": "TinyMCE",
3
+ "settings.description": "TinyMCE rich text editor",
4
+ "settings.subtitle": "Edit settings of your TinyMCE plugin",
5
+ "settings.content-title": "Set API key for TinyMCE editor.",
6
+ "settings.save-button": "Save",
7
+ "settings.input-title": "API key",
8
+ "settings.input-placeholder": "ex. eegrtg8464asnbvvvfasd46486asldaeerer45888areettzh",
9
+ "settings.success-message": "Settings successfully updated",
10
+ "settings.page-title": "Configuration"
11
+ };
12
+ export {
13
+ en as default
14
+ };
15
+ //# sourceMappingURL=en-BILT6xrd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-BILT6xrd.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const en = {
4
+ "settings.title": "TinyMCE",
5
+ "settings.description": "TinyMCE rich text editor",
6
+ "settings.subtitle": "Edit settings of your TinyMCE plugin",
7
+ "settings.content-title": "Set API key for TinyMCE editor.",
8
+ "settings.save-button": "Save",
9
+ "settings.input-title": "API key",
10
+ "settings.input-placeholder": "ex. eegrtg8464asnbvvvfasd46486asldaeerer45888areettzh",
11
+ "settings.success-message": "Settings successfully updated",
12
+ "settings.page-title": "Configuration"
13
+ };
14
+ exports.default = en;
15
+ //# sourceMappingURL=en-usAdfkfH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-usAdfkfH.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ const react = require("react");
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const styled = require("styled-components");
5
+ const designSystem = require("@strapi/design-system");
6
+ const icons = require("@strapi/icons");
7
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
8
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
9
+ const __variableDynamicImportRuntimeHelper = (glob, path) => {
10
+ const v = glob[path];
11
+ if (v) {
12
+ return typeof v === "function" ? v() : Promise.resolve(v);
13
+ }
14
+ return new Promise((_, reject) => {
15
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
16
+ });
17
+ };
18
+ const name$1 = "@kookaat/strapi-plugin-tinymce";
19
+ const version = "2.0.3";
20
+ const description = "Strapi custom field with a customized build of TinyMCE richtext editor.";
21
+ const keywords = [
22
+ "strapi",
23
+ "tinymce",
24
+ "tinymce 7",
25
+ "wysiwyg",
26
+ "rich text",
27
+ "editor"
28
+ ];
29
+ const license = "MIT";
30
+ const author = {
31
+ name: "M.Hossein Zendehpey (forked from SKLINET s.r.o.)",
32
+ url: "https://github.com/mhzendehpey"
33
+ };
34
+ const type = "commonjs";
35
+ const exports$1 = {
36
+ "./package.json": "./package.json",
37
+ "./strapi-admin": {
38
+ types: "./dist/admin/src/index.d.ts",
39
+ source: "./admin/src/index.ts",
40
+ "import": "./dist/admin/index.mjs",
41
+ require: "./dist/admin/index.js",
42
+ "default": "./dist/admin/index.js"
43
+ },
44
+ "./strapi-server": {
45
+ types: "./dist/server/src/index.d.ts",
46
+ source: "./server/src/index.ts",
47
+ "import": "./dist/server/index.mjs",
48
+ require: "./dist/server/index.js",
49
+ "default": "./dist/server/index.js"
50
+ }
51
+ };
52
+ const files = [
53
+ "dist"
54
+ ];
55
+ const scripts = {
56
+ build: "strapi-plugin build",
57
+ "test:ts:back": "run -T tsc -p server/tsconfig.json",
58
+ "test:ts:front": "run -T tsc -p admin/tsconfig.json",
59
+ verify: "strapi-plugin verify",
60
+ watch: "strapi-plugin watch",
61
+ "watch:link": "strapi-plugin watch:link"
62
+ };
63
+ const dependencies = {
64
+ "@strapi/design-system": "^2.0.0-rc.11",
65
+ "@strapi/icons": "^2.0.0-rc.11",
66
+ "@tinymce/tinymce-react": "^5.1.1",
67
+ "react-intl": "^6.8.4",
68
+ "tinymce-i18n": "^24.10.28"
69
+ };
70
+ const devDependencies = {
71
+ "@strapi/sdk-plugin": "^5.2.7",
72
+ "@strapi/strapi": "^5.33.1",
73
+ "@strapi/typescript-utils": "5.1.1",
74
+ "@types/react": "^18.3.10",
75
+ "@types/react-dom": "^18.3.0",
76
+ prettier: "^3.3.3",
77
+ react: "^18.3.1",
78
+ "react-dom": "^18.3.1",
79
+ "react-router-dom": "^6.26.2",
80
+ "styled-components": "^6.1.13",
81
+ typescript: "^5.6.2"
82
+ };
83
+ const peerDependencies = {
84
+ "@strapi/sdk-plugin": "^5.2.7",
85
+ "@strapi/strapi": "^5.1.1",
86
+ react: "^18.3.1",
87
+ "react-dom": "^18.3.1",
88
+ "react-router-dom": "^6.27.0",
89
+ "styled-components": "^6.1.13"
90
+ };
91
+ const strapi = {
92
+ displayName: "TinyMCE",
93
+ name: "tinymce",
94
+ description: "Strapi custom field with a customized build of TinyMCE richtext editor.",
95
+ kind: "plugin"
96
+ };
97
+ const repository = {
98
+ type: "git",
99
+ url: "https://github.com/mhzendehpey/strapi-plugin-tinymce"
100
+ };
101
+ const pluginPkg = {
102
+ name: name$1,
103
+ version,
104
+ description,
105
+ keywords,
106
+ license,
107
+ author,
108
+ type,
109
+ exports: exports$1,
110
+ files,
111
+ scripts,
112
+ dependencies,
113
+ devDependencies,
114
+ peerDependencies,
115
+ strapi,
116
+ repository
117
+ };
118
+ const PLUGIN_ID = pluginPkg.name.replace(/^(@kookaat\/strapi-)plugin-/i, "");
119
+ const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
120
+ const Initializer = ({ setPlugin }) => {
121
+ const ref = react.useRef(setPlugin);
122
+ react.useEffect(() => {
123
+ ref.current(PLUGIN_ID);
124
+ }, []);
125
+ return null;
126
+ };
127
+ const prefixPluginTranslations = (trad, pluginId) => {
128
+ if (!pluginId) {
129
+ throw new TypeError("pluginId can't be empty");
130
+ }
131
+ return Object.keys(trad).reduce((acc, current) => {
132
+ acc[`${pluginId}.${current}`] = trad[current];
133
+ return acc;
134
+ }, {});
135
+ };
136
+ const pluginPermissions = {
137
+ // This permission regards the main component (App) and is used to tell
138
+ // If the plugin link should be displayed in the menu
139
+ // And also if the plugin is accessible. This use case is found when a user types the url of the
140
+ // plugin directly in the browser
141
+ "menu-link": [{ action: "plugin::tinymce.menu-link", subject: null }],
142
+ settings: [{ action: "plugin::tinymce.settings.read", subject: null }]
143
+ };
144
+ const IconBox = styled__default.default(designSystem.Flex)`
145
+ background-color: #f0f0ff; /* primary100 */
146
+ border: 1px solid #d9d8ff; /* primary200 */
147
+
148
+ svg > path {
149
+ fill: #4945ff; /* primary600 */
150
+ }
151
+ `;
152
+ const PluginIcon = () => {
153
+ return /* @__PURE__ */ jsxRuntime.jsx(IconBox, { justifyContent: "center", alignItems: "center", width: 7, height: 6, hasRadius: true, "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Paragraph, {}) });
154
+ };
155
+ const name = pluginPkg.strapi.name;
156
+ const index = {
157
+ register(app) {
158
+ app.customFields.register({
159
+ name: "tinymce",
160
+ pluginId: PLUGIN_ID,
161
+ type: "richtext",
162
+ icon: PluginIcon,
163
+ intlLabel: {
164
+ id: getTranslation("settings.title"),
165
+ defaultMessage: "TinyMCE"
166
+ },
167
+ intlDescription: {
168
+ id: getTranslation("settings.description"),
169
+ defaultMessage: "TinyMCE rich text editor"
170
+ },
171
+ isResizable: false,
172
+ default: 12,
173
+ options: {
174
+ advanced: [
175
+ {
176
+ type: "checkbox",
177
+ name: "required",
178
+ intlLabel: {
179
+ id: getTranslation("settings.required-field"),
180
+ defaultMessage: "Required field"
181
+ },
182
+ description: "You won't be able to create an entry if this field is empty"
183
+ }
184
+ ]
185
+ },
186
+ components: {
187
+ Input: async () => Promise.resolve().then(() => require(
188
+ /* webpackChunkName: "video-field-input-component" */
189
+ "./Wysiwyg-C1NARvA-.js"
190
+ ))
191
+ }
192
+ });
193
+ app.createSettingSection(
194
+ {
195
+ id: PLUGIN_ID,
196
+ intlLabel: {
197
+ id: `${PLUGIN_ID}.plugin.name`,
198
+ defaultMessage: "TinyMCE"
199
+ }
200
+ },
201
+ [
202
+ {
203
+ intlLabel: {
204
+ id: getTranslation("settings.page-title"),
205
+ defaultMessage: "Configuration"
206
+ },
207
+ id: "settings",
208
+ to: `/settings/${PLUGIN_ID}`,
209
+ Component: async () => {
210
+ return Promise.resolve().then(() => require("./Settings-Cht7TW_m.js"));
211
+ },
212
+ permissions: pluginPermissions["settings"]
213
+ }
214
+ ]
215
+ );
216
+ app.registerPlugin({
217
+ id: PLUGIN_ID,
218
+ initializer: Initializer,
219
+ isReady: false,
220
+ name
221
+ });
222
+ },
223
+ bootstrap(app) {
224
+ },
225
+ async registerTrads(app) {
226
+ const { locales } = app;
227
+ const importedTranslations = await Promise.all(
228
+ locales.map((locale) => {
229
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-4ldo0hfI.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-usAdfkfH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-BcD0BjAU.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
230
+ return {
231
+ data: prefixPluginTranslations(data, PLUGIN_ID),
232
+ locale
233
+ };
234
+ }).catch(() => {
235
+ return {
236
+ data: {},
237
+ locale
238
+ };
239
+ });
240
+ })
241
+ );
242
+ return importedTranslations;
243
+ }
244
+ };
245
+ exports.PLUGIN_ID = PLUGIN_ID;
246
+ exports.getTranslation = getTranslation;
247
+ exports.index = index;
248
+ //# sourceMappingURL=index-4S82exqN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-4S82exqN.js","sources":["../../admin/src/pluginId.ts","../../admin/src/utils/getTranslation.ts","../../admin/src/components/Initializer.tsx","../../admin/src/utils/prefixPluginTranslations.ts","../../admin/src/permissions.ts","../../admin/src/components/PluginIcon.tsx","../../admin/src/index.ts"],"sourcesContent":["import pluginPkg from '../../package.json';\r\n\r\nexport const PLUGIN_ID = pluginPkg.name.replace(/^(@kookaat\\/strapi-)plugin-/i, '');\r\n","import { PLUGIN_ID } from '../pluginId';\r\n\r\nconst getTranslation = (id: string) => `${PLUGIN_ID}.${id}`;\r\n\r\nexport { getTranslation };\r\n","import { useEffect, useRef } from 'react';\r\n\r\nimport { PLUGIN_ID } from '../pluginId';\r\n\r\ntype InitializerProps = {\r\n setPlugin: (id: string) => void;\r\n};\r\n\r\nconst Initializer = ({ setPlugin }: InitializerProps) => {\r\n const ref = useRef(setPlugin);\r\n\r\n useEffect(() => {\r\n ref.current(PLUGIN_ID);\r\n }, []);\r\n\r\n return null;\r\n};\r\n\r\nexport { Initializer };\r\n","type TradOptions = Record<string, string>;\r\n\r\nexport const prefixPluginTranslations = (trad: TradOptions, pluginId: string): TradOptions => {\r\n if (!pluginId) {\r\n throw new TypeError(\"pluginId can't be empty\");\r\n }\r\n return Object.keys(trad).reduce((acc, current) => {\r\n acc[`${pluginId}.${current}`] = trad[current];\r\n return acc;\r\n }, {} as TradOptions);\r\n};\r\n","const pluginPermissions = {\r\n // This permission regards the main component (App) and is used to tell\r\n // If the plugin link should be displayed in the menu\r\n // And also if the plugin is accessible. This use case is found when a user types the url of the\r\n // plugin directly in the browser\r\n 'menu-link': [{ action: 'plugin::tinymce.menu-link', subject: null }],\r\n settings: [{ action: 'plugin::tinymce.settings.read', subject: null }],\r\n};\r\n\r\nexport default pluginPermissions;\r\n","import React from 'react';\r\nimport styled from 'styled-components';\r\nimport { Flex } from '@strapi/design-system';\r\nimport { Paragraph } from '@strapi/icons';\r\n\r\nconst IconBox = styled(Flex)`\r\n background-color: #f0f0ff; /* primary100 */\r\n border: 1px solid #d9d8ff; /* primary200 */\r\n\r\n svg > path {\r\n fill: #4945ff; /* primary600 */\r\n }\r\n`;\r\n\r\nconst PluginIcon = () => {\r\n return (\r\n <IconBox justifyContent=\"center\" alignItems=\"center\" width={7} height={6} hasRadius aria-hidden>\r\n <Paragraph />\r\n </IconBox>\r\n );\r\n};\r\n\r\nexport { PluginIcon };\r\n","import pluginPkg from '../../package.json';\r\nimport { getTranslation } from './utils/getTranslation';\r\nimport { PLUGIN_ID } from './pluginId';\r\nimport { Initializer } from './components/Initializer';\r\nimport { prefixPluginTranslations } from './utils/prefixPluginTranslations';\r\nimport pluginPermissions from './permissions';\r\nimport { PluginIcon } from './components/PluginIcon';\r\n\r\nconst name = pluginPkg.strapi.name;\r\n\r\nexport default {\r\n register(app: any) {\r\n app.customFields.register({\r\n name: 'tinymce',\r\n pluginId: PLUGIN_ID,\r\n type: 'richtext',\r\n icon: PluginIcon,\r\n intlLabel: {\r\n id: getTranslation('settings.title'),\r\n defaultMessage: 'TinyMCE',\r\n },\r\n intlDescription: {\r\n id: getTranslation('settings.description'),\r\n defaultMessage: 'TinyMCE rich text editor',\r\n },\r\n isResizable: false,\r\n default: 12,\r\n options: {\r\n advanced: [\r\n {\r\n type: 'checkbox',\r\n name: 'required',\r\n intlLabel: {\r\n id: getTranslation('settings.required-field'),\r\n defaultMessage: 'Required field',\r\n },\r\n description: \"You won't be able to create an entry if this field is empty\",\r\n },\r\n ],\r\n },\r\n components: {\r\n Input: async () => import(/* webpackChunkName: \"video-field-input-component\" */ './components/Wysiwyg'),\r\n },\r\n });\r\n\r\n app.createSettingSection(\r\n {\r\n id: PLUGIN_ID,\r\n intlLabel: {\r\n id: `${PLUGIN_ID}.plugin.name`,\r\n defaultMessage: 'TinyMCE',\r\n },\r\n },\r\n [\r\n {\r\n intlLabel: {\r\n id: getTranslation('settings.page-title'),\r\n defaultMessage: 'Configuration',\r\n },\r\n id: 'settings',\r\n to: `/settings/${PLUGIN_ID}`,\r\n Component: async () => {\r\n return import('./pages/Settings');\r\n },\r\n permissions: pluginPermissions['settings'],\r\n },\r\n ],\r\n );\r\n\r\n app.registerPlugin({\r\n id: PLUGIN_ID,\r\n initializer: Initializer,\r\n isReady: false,\r\n name: name,\r\n });\r\n },\r\n\r\n bootstrap(app: any) {},\r\n async registerTrads(app: any) {\r\n const { locales } = app;\r\n\r\n const importedTranslations = await Promise.all(\r\n (locales as string[]).map((locale) => {\r\n return import(/* webpackChunkName: \"translation-[request]\" */ `./translations/${locale}.json`)\r\n .then(({ default: data }) => {\r\n return {\r\n data: prefixPluginTranslations(data, PLUGIN_ID),\r\n locale,\r\n };\r\n })\r\n .catch(() => {\r\n return {\r\n data: {},\r\n locale,\r\n };\r\n });\r\n }),\r\n );\r\n\r\n return importedTranslations;\r\n },\r\n};\r\n"],"names":["useRef","useEffect","styled","Flex","jsx","Paragraph"],"mappings":"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"}