@rg-dev/tinymce-helpers 1.0.8 → 1.0.10

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 (3) hide show
  1. package/index.d.mts +5 -4
  2. package/index.mjs +120 -59
  3. package/package.json +1 -1
package/index.d.mts CHANGED
@@ -13,7 +13,7 @@ declare const skinsTable: {
13
13
  type RemoveIndexSignature<T> = {
14
14
  [K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K];
15
15
  };
16
- type Opts = {
16
+ type MyTinymceOpts = {
17
17
  skin?: keyof typeof skinsTable;
18
18
  direction?: 'rtl' | 'ltr';
19
19
  customSetup?: (editor: Editor) => void;
@@ -25,8 +25,9 @@ declare class tinymceHelpers {
25
25
  private _lockButton?;
26
26
  private originalContextMenu;
27
27
  private constructor();
28
- static initMce(el: HTMLElement, customOpts?: Opts): Promise<tinymceHelpers>;
29
- _initMce(el: HTMLElement, customOpts?: Opts): Promise<this>;
28
+ static initMce(el: HTMLElement, customOpts?: MyTinymceOpts): Promise<tinymceHelpers>;
29
+ addImg(src: string): void;
30
+ _initMce(el: HTMLElement, customOpts?: MyTinymceOpts): Promise<this>;
30
31
  private setContextMenu;
31
32
  toggleReadOnly(lock?: 'yes' | 'no'): void;
32
33
  isEditable(): boolean;
@@ -42,4 +43,4 @@ declare class tinymceHelpers {
42
43
  destroy(): void;
43
44
  }
44
45
 
45
- export { tinymceHelpers };
46
+ export { type MyTinymceOpts, tinymceHelpers };
package/index.mjs CHANGED
@@ -51,7 +51,7 @@ import "tinymce/plugins/preview";
51
51
  import "tinymce/plugins/insertdatetime";
52
52
 
53
53
  // src/client/custom-components/mce.css?raw
54
- var mce_default = ':where(.mce-content-body) {\n --editor-text: #000;\n --editor-link: #000;\n --editor-border: #aaa;\n --editor-table-header-text: #6e6e6e;\n --editor-table-row-even: #fafafa;\n --editor-hr: #bbb;\n}\n\n\nli::marker {\n color: var(--editor-link) !important;\n}\n\n::-webkit-scrollbar {\n width: 10px;\n}\n\n::-webkit-scrollbar-track {\n background: var(--editor-table-row-even);\n}\n\n::-webkit-scrollbar-thumb {\n background: var(--editor-link);\n border-radius: 35px;\n}\n\n@media print {\n .mce-content-body {\n --editor-text: #000;\n --editor-link: #000;\n --editor-border: #000;\n --editor-table-header-text: #000;\n --editor-table-row-even: #f2f2f2;\n --editor-hr: #000;\n }\n\n .mce-content-body table tr:nth-child(even) {\n background: var(--editor-table-row-even) !important;\n -webkit-print-color-adjust: exact;\n print-color-adjust: exact;\n }\n\n \n .mce-content-body blockquote {\n border-inline-start: none !important;\n background: #f9f9f9 !important;\n padding: 7px !important;\n margin: 0px !important;\n color: #000 !important;\n -webkit-print-color-adjust: exact !important;\n print-color-adjust: exact !important;\n }\n\n .mce-content-body td[data-mce-selected]::after,\n .mce-content-body th[data-mce-selected]::after {\n display: none !important;\n}\n}\n\n img {\n max-width: 100%;\n }\n\n\n\n.mce-content-body blockquote {\n margin: 25px 0;\n display: flow-root;\n padding: 15px 20px;\n border-radius: 8px;\n overflow: hidden;\n border: none !important;\n background: var(--editor-table-row-even);\n color: var(--editor-text);\n}\n\n\n\n.mce-content-body blockquote p {\n margin: 0;\n}\n\n* {\n border: 0;\n padding: 0;\n margin: 0;\n background: 0 0;\n color: inherit;\n box-sizing: border-box;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n font-weight: 400;\n}\n\n:focus {\n outline: 0;\n}\n\na {\n text-decoration: none;\n cursor: pointer;\n}\n\nb,\nb *,\nstrong,\nstrong * {\n font-weight: 700;\n}\n\nol,\nul {\n list-style: none;\n}\n\npre {\n font: inherit;\n}\n\nbutton,\ninput,\ninput:not([type]),\ninput[type="button"],\ninput[type="color"],\ninput[type="date"],\ninput[type="datetime-local"],\ninput[type="datetime"],\ninput[type="email"],\ninput[type="month"],\ninput[type="number"],\ninput[type="password"],\ninput[type="reset"],\ninput[type="search"],\ninput[type="submit"],\ninput[type="tel"],\ninput[type="text"],\ninput[type="time"],\ninput[type="url"],\ninput[type="week"],\nselect,\ntextarea {\n font: inherit;\n}\n\n.mce-container textarea {\n display: inline-block !important;\n} \n\n\n.my-custom-styles{\n direction: ltr;\n }\n\n.mce-content-body {\n font-size: 28px;\n font-family: Rubik, Helvetica, Arial, sans-serif;\n padding: 0 25px 25px;\n color: var(--editor-text);\n}\n\n.mce-content-body table {\n width: 100%;\n table-layout: fixed;\n}\n\n.mce-content-body table td,\n.mce-content-body table th {\n overflow-wrap: anywhere;\n word-break: break-word;\n \n white-space: normal;\n}\n\n.mce-content-body h1 {\n font-size: 34px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h2 {\n font-size: 30px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h3 {\n font-size: 26px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h4 {\n font-size: 22px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h5 {\n font-size: 18px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h6 {\n font-size: 14px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body p {\n margin: 25px 0;\n}\n\n.mce-content-body pre {\n font-family: monospace;\n}\n\n.mce-content-body ol,\n.mce-content-body ul {\n margin-left: 15px;\n list-style-position: outside;\n margin-bottom: 20px;\n}\n\n.mce-content-body ol li,\n.mce-content-body ul li {\n margin-left: 10px;\n margin-bottom: 10px;\n color: var(--editor-text);\n}\n\n.mce-content-body ul {\n list-style-type: disc;\n}\n\n.mce-content-body ol {\n list-style-type: decimal;\n}\n\n.mce-content-body a[href] {\n color: var(--editor-link);\n text-decoration: underline;\n}\n\n.mce-content-body table caption,\n.mce-content-body table td,\n.mce-content-body table th {\n padding: 15px 7px;\n font: inherit;\n}\n\n.mce-content-body table td,\n.mce-content-body table th {\n border: 1px solid var(--editor-border);\n border-collapse: collapse;\n}\n\n.mce-content-body table th {\n font-weight: 400;\n color: var(--editor-table-header-text);\n background-position: 100% 100%;\n background-size: 2px 10px;\n background-repeat: no-repeat;\n}\n\n.mce-content-body table {\n width: 100%;\n border-spacing: 0;\n border-collapse: separate;\n border: 1px solid var(--editor-border);\n}\n\n.mce-content-body table tr:nth-child(even) {\n background: var(--editor-table-row-even);\n}\n\n.mce-content-body hr {\n border-top: 2px solid var(--editor-hr);\n}';
54
+ var mce_default = ':where(.mce-content-body) {\n --editor-text: #000;\n --editor-link: #000;\n --editor-border: #d6d6d6c9;\n --editor-table-header-text: #6e6e6e;\n --editor-table-row-even: #fafafa;\n --editor-hr: #bbb;\n}\n\n\nli::marker {\n color: var(--editor-link) !important;\n}\n\n::-webkit-scrollbar {\n width: 10px;\n}\n\n::-webkit-scrollbar-track {\n background: var(--editor-table-row-even);\n}\n\n::-webkit-scrollbar-thumb {\n background: var(--editor-link);\n border-radius: 35px;\n}\n\n @media print {\n .mce-content-body {\n --editor-text: #000;\n --editor-link: #000;\n --editor-border: #d6d6d6c9;\n --editor-table-header-text: #000;\n --editor-table-row-even: #fafafa;\n --editor-hr: #000;\n }\n\n .mce-content-body table tr:nth-child(even) {\n background: var(--editor-table-row-even) !important;\n -webkit-print-color-adjust: exact;\n print-color-adjust: exact;\n }\n\n \n .mce-content-body blockquote {\n border-inline-start: none !important;\n background: #f9f9f9 !important;\n\n color: #000 !important;\n -webkit-print-color-adjust: exact !important;\n print-color-adjust: exact !important;\n }\n\n \n\n .mce-content-body td[data-mce-selected]::after,\n .mce-content-body th[data-mce-selected]::after {\n display: none !important;\n}\n}\n\n img {\n padding-block: 7px;\n max-width: 100%;\n }\n\n\n\n .mce-content-body blockquote {\n display: flow-root;\n padding: 15px;\n border-radius: 8px;\n margin: 0px !important;\n margin-block: 20px !important;\n overflow: hidden;\n border: none !important;\n background: var(--editor-table-row-even);\n color: var(--editor-text);\n}\n\n\n\n.mce-content-body blockquote p {\n margin: 0;\n}\n\n* {\n border: 0;\n padding: 0;\n margin: 0;\n background: 0 0;\n color: inherit;\n box-sizing: border-box;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n font-weight: 400;\n}\n\n:focus {\n outline: 0;\n}\n\na {\n text-decoration: none;\n cursor: pointer;\n}\n\nb,\nb *,\nstrong,\nstrong * {\n font-weight: 700;\n}\n\nol,\nul {\n list-style: none;\n}\n\npre {\n font: inherit;\n}\n\nbutton,\ninput,\ninput:not([type]),\ninput[type="button"],\ninput[type="color"],\ninput[type="date"],\ninput[type="datetime-local"],\ninput[type="datetime"],\ninput[type="email"],\ninput[type="month"],\ninput[type="number"],\ninput[type="password"],\ninput[type="reset"],\ninput[type="search"],\ninput[type="submit"],\ninput[type="tel"],\ninput[type="text"],\ninput[type="time"],\ninput[type="url"],\ninput[type="week"],\nselect,\ntextarea {\n font: inherit;\n}\n\n.mce-container textarea {\n display: inline-block !important;\n} \n\n\n.my-custom-styles{\n direction: ltr;\n }\n\n.mce-content-body {\n font-size: 28px;\n font-family: Rubik, Helvetica, Arial, sans-serif;\n padding: 0 25px 25px;\n color: var(--editor-text);\n}\n\n.mce-content-body table {\n width: 100%;\n table-layout: fixed;\n}\n\n\n\n.mce-content-body table td,\n.mce-content-body table th {\n overflow-wrap: anywhere;\n word-break: break-word;\n white-space: normal;\n}\n\n\n.mce-content-body h1 {\n font-size: 34px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h2 {\n font-size: 30px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h3 {\n font-size: 26px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h4 {\n font-size: 22px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h5 {\n font-size: 18px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body h6 {\n font-size: 14px;\n line-height: 1.4em;\n margin: 25px 0 15px;\n}\n\n.mce-content-body p {\n margin: 25px 0;\n}\n\n.mce-content-body pre {\n font-family: monospace;\n}\n\n.mce-content-body ol,\n.mce-content-body ul {\n margin-left: 15px;\n list-style-position: outside;\n margin-bottom: 20px;\n}\n\n.mce-content-body ol li,\n.mce-content-body ul li {\n margin-left: 10px;\n margin-bottom: 10px;\n color: var(--editor-text);\n}\n\n.mce-content-body ul {\n list-style-type: disc;\n}\n\n.mce-content-body ol {\n list-style-type: decimal;\n}\n\n.mce-content-body a[href] {\n color: var(--editor-link);\n text-decoration: underline;\n}\n\n.mce-content-body table caption,\n.mce-content-body table td,\n.mce-content-body table th {\n padding: 15px 7px;\n font: inherit;\n}\n\n.mce-content-body table td,\n.mce-content-body table th {\n border: 1px solid var(--editor-border) !important;\n border-collapse: collapse;\n}\n\n.mce-content-body table th {\n font-weight: 400;\n color: var(--editor-table-header-text);\n background-position: 100% 100%;\n background-size: 2px 10px;\n background-repeat: no-repeat;\n}\n\n.mce-content-body table {\n width: 100%;\n border-spacing: 0;\n border-collapse: separate;\n \n}\n\n.mce-content-body table tr:nth-child(even) {\n background: var(--editor-table-row-even);\n}\n\n.mce-content-body hr {\n border-top: 2px solid var(--editor-hr);\n}';
55
55
 
56
56
  // src/client/custom-components/tinymce-helpers.ts
57
57
  import { isNonEmptyString } from "@rg-dev/stdlib/lib/common-env";
@@ -91,7 +91,7 @@ async function darkSkin() {
91
91
  --editor-bg: #222f3e;
92
92
  --editor-text: #e4e8ec;
93
93
  --editor-link: #74b9ff;
94
- --editor-border: #526273;
94
+ --editor-border: #d6d6d624;
95
95
  --editor-table-header-text: #b8c2cc;
96
96
  --editor-table-header-bg: #2c3e50;
97
97
  --editor-table-row-even: #263747;
@@ -114,6 +114,9 @@ var tinymceHelpers = class _tinymceHelpers {
114
114
  static async initMce(el, customOpts = Object()) {
115
115
  return await new _tinymceHelpers()._initMce(el, customOpts);
116
116
  }
117
+ addImg(src) {
118
+ this.editor.insertContent(`<img src="${src}" alt="">`);
119
+ }
117
120
  async _initMce(el, customOpts = Object()) {
118
121
  var _a, _b;
119
122
  if (!(el instanceof HTMLElement)) {
@@ -137,6 +140,25 @@ var tinymceHelpers = class _tinymceHelpers {
137
140
  if (e.key !== "Enter" || !e.shiftKey) {
138
141
  return;
139
142
  }
143
+ const node = editor.selection.getNode();
144
+ const blockquote = editor.dom.getParent(node, "blockquote");
145
+ if (blockquote) {
146
+ const parent = blockquote.parentNode;
147
+ if (parent) {
148
+ e.preventDefault();
149
+ e.stopImmediatePropagation();
150
+ editor.undoManager.transact(
151
+ () => {
152
+ const p = editor.dom.create("p", {}, "<br>");
153
+ parent.insertBefore(p, blockquote.nextSibling);
154
+ editor.selection.select(p, true);
155
+ editor.selection.collapse(true);
156
+ }
157
+ );
158
+ editor.nodeChanged();
159
+ return;
160
+ }
161
+ }
140
162
  e.preventDefault();
141
163
  e.stopImmediatePropagation();
142
164
  editor.getDoc().execCommand("insertParagraph", false, void 0);
@@ -158,20 +180,23 @@ var tinymceHelpers = class _tinymceHelpers {
158
180
  }
159
181
  }
160
182
  );
161
- editor.ui.registry.addMenuItem("create-block-above", {
162
- text: "Create block above",
163
- icon: "plus",
164
- onAction: () => {
165
- var _a3;
166
- const node = editor.selection.getNode();
167
- const body = editor.getBody();
168
- const topBlock = editor.dom.getParent(node, (n) => n.parentNode === body) || node;
169
- const newBlock = editor.dom.create("p", {}, '<br data-mce-bogus="1">');
170
- (_a3 = topBlock.parentNode) == null ? void 0 : _a3.insertBefore(newBlock, topBlock);
171
- editor.selection.setCursorLocation(newBlock, 0);
172
- editor.focus();
183
+ editor.ui.registry.addMenuItem(
184
+ "create-block-above",
185
+ {
186
+ text: "Create block above",
187
+ icon: "plus",
188
+ onAction: () => {
189
+ var _a3;
190
+ const node = editor.selection.getNode();
191
+ const body = editor.getBody();
192
+ const topBlock = editor.dom.getParent(node, (n) => n.parentNode === body) || node;
193
+ const newBlock = editor.dom.create("p", {}, '<br data-mce-bogus="1">');
194
+ (_a3 = topBlock.parentNode) == null ? void 0 : _a3.insertBefore(newBlock, topBlock);
195
+ editor.selection.setCursorLocation(newBlock, 0);
196
+ editor.focus();
197
+ }
173
198
  }
174
- });
199
+ );
175
200
  editor.ui.registry.addMenuItem(
176
201
  "change-dir",
177
202
  {
@@ -203,37 +228,41 @@ var tinymceHelpers = class _tinymceHelpers {
203
228
  }
204
229
  }
205
230
  }
206
- ), editor.ui.registry.addMenuItem("clearTextStyle", {
207
- text: "Clear formatting",
208
- icon: "removeformat",
209
- onAction: () => {
210
- editor.execCommand("RemoveFormat");
231
+ ), editor.ui.registry.addMenuItem(
232
+ "clearTextStyle",
233
+ {
234
+ text: "Clear formatting",
235
+ icon: "removeformat",
236
+ onAction: () => {
237
+ editor.execCommand("RemoveFormat");
238
+ }
211
239
  }
212
- });
213
- editor.ui.registry.addMenuItem("insert-image", {
214
- text: "Insert image",
215
- icon: "image",
216
- onAction: () => {
217
- const input = document.createElement("input");
218
- input.type = "file";
219
- input.accept = "image/*";
220
- input.onchange = () => {
221
- var _a3;
222
- const file = (_a3 = input.files) == null ? void 0 : _a3[0];
223
- if (!file) {
224
- return;
225
- }
226
- const reader = new FileReader();
227
- reader.onload = () => {
228
- editor.insertContent(
229
- `<img src="${reader.result}" alt="">`
230
- );
240
+ );
241
+ editor.ui.registry.addMenuItem(
242
+ "insert-image",
243
+ {
244
+ text: "Insert image",
245
+ icon: "image",
246
+ onAction: () => {
247
+ const input = document.createElement("input");
248
+ input.type = "file";
249
+ input.accept = "image/*";
250
+ input.onchange = () => {
251
+ var _a3;
252
+ const file = (_a3 = input.files) == null ? void 0 : _a3[0];
253
+ if (!file) {
254
+ return;
255
+ }
256
+ const reader = new FileReader();
257
+ reader.onload = () => {
258
+ editor.insertContent(`<img src="${reader.result}" alt="">`);
259
+ };
260
+ reader.readAsDataURL(file);
231
261
  };
232
- reader.readAsDataURL(file);
233
- };
234
- input.click();
262
+ input.click();
263
+ }
235
264
  }
236
- });
265
+ );
237
266
  editor.ui.registry.addButton(
238
267
  "decreaseFontSize",
239
268
  {
@@ -252,6 +281,38 @@ var tinymceHelpers = class _tinymceHelpers {
252
281
  }
253
282
  }
254
283
  );
284
+ editor.ui.registry.addButton(
285
+ "myBlockquote",
286
+ {
287
+ icon: "quote",
288
+ tooltip: "Blockquote",
289
+ onAction: () => {
290
+ const node = editor.selection.getNode();
291
+ const blockquote = editor.dom.getParent(node, "blockquote");
292
+ editor.undoManager.transact(
293
+ () => {
294
+ if (blockquote) {
295
+ const parent = blockquote.parentNode;
296
+ if (!parent) return;
297
+ while (blockquote.firstChild) {
298
+ parent.insertBefore(blockquote.firstChild, blockquote);
299
+ }
300
+ parent.removeChild(blockquote);
301
+ } else {
302
+ const body = editor.getBody();
303
+ const block = editor.dom.getParent(node, (n) => n.parentNode === body) || node;
304
+ if (!block || block === body || !block.parentNode) return;
305
+ const quote = editor.dom.create("blockquote");
306
+ block.parentNode.insertBefore(quote, block);
307
+ quote.appendChild(block);
308
+ editor.selection.select(quote, true);
309
+ }
310
+ }
311
+ );
312
+ editor.nodeChanged();
313
+ }
314
+ }
315
+ );
255
316
  editor.ui.registry.addButton(
256
317
  "increaseFontSize",
257
318
  {
@@ -282,7 +343,7 @@ var tinymceHelpers = class _tinymceHelpers {
282
343
  content_style: theSkin.css,
283
344
  body_class: "my-custom-styles",
284
345
  target: el,
285
- toolbar: "lockContent | undo redo | increaseFontSize decreaseFontSize bold italic underline strikethrough | fontfamily fontsize | ltr rtl alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | charmap emoticons | fullscreen preview print | image media link anchor codesample",
346
+ toolbar: "myBlockquote lockContent | undo redo | increaseFontSize decreaseFontSize bold italic underline strikethrough | fontfamily fontsize | ltr rtl alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | charmap emoticons | fullscreen preview print | image media link anchor codesample",
286
347
  toolbar_sticky: true,
287
348
  promotion: false,
288
349
  image_advtab: true,
@@ -456,21 +517,21 @@ var tinymceHelpers = class _tinymceHelpers {
456
517
  btn.innerHTML = `<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 17a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm6-9h-1V6a5 5 0 0 0-10 0v2H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2zM9 6a3 3 0 0 1 6 0v2H9V6zm9 14H6V10h12v10z"/></svg>`;
457
518
  const content = this._editor.getBody();
458
519
  btn.style.cssText = `
459
- position:absolute;
460
- top:8px;
461
- right:8px;
462
- z-index:1000;
463
- display:none;
464
- align-items:center;
465
- justify-content:center;
466
- width:32px;
467
- height:32px;
468
- padding:0;
469
- border-radius:6px;
470
- border:1px solid rgba(0,0,0,0.15);
471
- color:rgb(255,255,255);
472
- cursor:pointer;
473
- box-shadow:0 1px 3px rgba(0,0,0,0.2);
520
+ position:absolute;
521
+ top:8px;
522
+ right:8px;
523
+ z-index:1000;
524
+ display:none;
525
+ align-items:center;
526
+ justify-content:center;
527
+ width:32px;
528
+ height:32px;
529
+ padding:0;
530
+ border-radius:6px;
531
+ border:1px solid rgba(0,0,0,0.15);
532
+ color:rgb(255,255,255);
533
+ cursor:pointer;
534
+ box-shadow:0 1px 3px rgba(0,0,0,0.2);
474
535
  `;
475
536
  btn.style.backgroundColor = getComputedStyle(content).getPropertyValue("--editor-linke").trim() || "black";
476
537
  btn.addEventListener("click", () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rg-dev/tinymce-helpers",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {