@tinymce/tinymce-webcomponent 2.3.0 → 2.3.1-feature.20250811004338301.sha63e3578

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/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 2.3.1 - 2025-08-11
10
+
11
+ ### Fixed
12
+ - JS files were missing in the NPM package. # TINY-12257
13
+
9
14
  ## 2.3.0 - 2025-07-31
10
15
 
11
16
  ### Changed
@@ -0,0 +1,572 @@
1
+ (function () {
2
+ 'use strict';
3
+
4
+ const Global = typeof window !== 'undefined' ? window : Function('return this;')();
5
+
6
+ const path = (parts, scope) => {
7
+ let o = scope !== undefined && scope !== null ? scope : Global;
8
+ for (let i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
9
+ o = o[parts[i]];
10
+ }
11
+ return o;
12
+ };
13
+ const resolve = (p, scope) => {
14
+ const parts = p.split('.');
15
+ return path(parts, scope);
16
+ };
17
+
18
+ const identity = x => {
19
+ return x;
20
+ };
21
+
22
+ const keys = Object.keys;
23
+ const hasOwnProperty = Object.hasOwnProperty;
24
+ const each = (obj, f) => {
25
+ const props = keys(obj);
26
+ for (let k = 0, len = props.length; k < len; k++) {
27
+ const i = props[k];
28
+ const x = obj[i];
29
+ f(x, i);
30
+ }
31
+ };
32
+ const has = (obj, key) => hasOwnProperty.call(obj, key);
33
+
34
+ let unique = 0;
35
+ const generate = prefix => {
36
+ const date = new Date();
37
+ const time = date.getTime();
38
+ const random = Math.floor(Math.random() * 1000000000);
39
+ unique++;
40
+ return prefix + '_' + random + unique + String(time);
41
+ };
42
+
43
+ const createState = () => ({
44
+ listeners: [],
45
+ scriptId: generate('tiny-script'),
46
+ scriptLoaded: false
47
+ });
48
+ const CreateScriptLoader = () => {
49
+ let state = createState();
50
+ const injectScriptTag = (scriptId, doc, url, callback) => {
51
+ const scriptTag = doc.createElement('script');
52
+ scriptTag.referrerPolicy = 'origin';
53
+ scriptTag.type = 'application/javascript';
54
+ scriptTag.id = scriptId;
55
+ scriptTag.src = url;
56
+ const handler = () => {
57
+ scriptTag.removeEventListener('load', handler);
58
+ callback();
59
+ };
60
+ scriptTag.addEventListener('load', handler);
61
+ if (doc.head) {
62
+ doc.head.appendChild(scriptTag);
63
+ }
64
+ };
65
+ const load = (doc, url, callback) => {
66
+ if (state.scriptLoaded) {
67
+ callback();
68
+ } else {
69
+ state.listeners.push(callback);
70
+ if (!doc.getElementById(state.scriptId)) {
71
+ injectScriptTag(state.scriptId, doc, url, () => {
72
+ state.listeners.forEach(fn => fn());
73
+ state.scriptLoaded = true;
74
+ });
75
+ }
76
+ }
77
+ };
78
+ const reinitialize = () => {
79
+ state = createState();
80
+ };
81
+ return {
82
+ load,
83
+ reinitialize
84
+ };
85
+ };
86
+ const ScriptLoader = CreateScriptLoader();
87
+
88
+ const toInt = str => parseInt(str, 10);
89
+ const cmp = (a, b) => {
90
+ const delta = a - b;
91
+ if (delta === 0) {
92
+ return 0;
93
+ }
94
+ return delta > 0 ? 1 : -1;
95
+ };
96
+ const nu = (major, minor, patch) => ({
97
+ major,
98
+ minor,
99
+ patch
100
+ });
101
+ const parse = versionString => {
102
+ const parts = /([0-9]+)\.([0-9]+)\.([0-9]+)(?:(\-.+)?)/.exec(versionString);
103
+ return parts ? nu(toInt(parts[1]), toInt(parts[2]), toInt(parts[3])) : nu(0, 0, 0);
104
+ };
105
+ const compare = (version1, version2) => {
106
+ const cmp1 = cmp(version1.major, version2.major);
107
+ if (cmp1 !== 0) {
108
+ return cmp1;
109
+ }
110
+ const cmp2 = cmp(version1.minor, version2.minor);
111
+ if (cmp2 !== 0) {
112
+ return cmp2;
113
+ }
114
+ const cmp3 = cmp(version1.patch, version2.patch);
115
+ if (cmp3 !== 0) {
116
+ return cmp3;
117
+ }
118
+ return 0;
119
+ };
120
+
121
+ const createSemVer = tinymce => {
122
+ const semver = [
123
+ tinymce.majorVersion,
124
+ tinymce.minorVersion
125
+ ].join('.');
126
+ return semver.split('.').slice(0, 3).join('.');
127
+ };
128
+ const getVersion = tinymce => parse(createSemVer(tinymce));
129
+ const isLessThan = (tinymce, version) => !tinymce ? false : compare(getVersion(tinymce), parse(version)) === -1;
130
+
131
+ var Status;
132
+ (function (Status) {
133
+ Status[Status['Raw'] = 0] = 'Raw';
134
+ Status[Status['Initializing'] = 1] = 'Initializing';
135
+ Status[Status['Ready'] = 2] = 'Ready';
136
+ }(Status || (Status = {})));
137
+ const closestRecursive = (selector, element) => {
138
+ const found = element.closest(selector);
139
+ if (found !== null) {
140
+ return found;
141
+ }
142
+ const next = element.getRootNode().host;
143
+ if (next !== null && next !== undefined) {
144
+ return closestRecursive(selector, next);
145
+ }
146
+ return null;
147
+ };
148
+ const isLookupKey = (values, key) => has(values, key);
149
+ const lookup = values => key => isLookupKey(values, key) ? values[key] : key;
150
+ const parseGlobal = resolve;
151
+ const parseString = identity;
152
+ const parseFalseOrString = lookup({ 'false': false });
153
+ const parseBooleanOrString = lookup({
154
+ 'true': true,
155
+ 'false': false
156
+ });
157
+ const parseNumberOrString = value => /^\d+$/.test(value) ? Number.parseInt(value, 10) : value;
158
+ const configAttributes = {
159
+ setup: parseGlobal,
160
+ statusbar: parseBooleanOrString,
161
+ toolbar: parseFalseOrString,
162
+ menubar: parseFalseOrString,
163
+ plugins: parseString,
164
+ content_css: parseString,
165
+ content_style: parseString,
166
+ width: parseNumberOrString,
167
+ height: parseNumberOrString,
168
+ toolbar_mode: parseString,
169
+ contextmenu: parseFalseOrString,
170
+ quickbars_insert_toolbar: parseFalseOrString,
171
+ quickbars_selection_toolbar: parseFalseOrString,
172
+ powerpaste_word_import: parseString,
173
+ powerpaste_html_import: parseString,
174
+ powerpaste_allow_local_images: parseBooleanOrString,
175
+ resize: parseBooleanOrString,
176
+ skin: parseString,
177
+ skin_url: parseString,
178
+ images_upload_url: parseString,
179
+ images_upload_handler: parseGlobal,
180
+ images_upload_base_path: parseString,
181
+ images_upload_credentials: parseBooleanOrString,
182
+ images_reuse_filename: parseBooleanOrString,
183
+ icons: parseString,
184
+ icons_url: parseString,
185
+ promotion: parseBooleanOrString
186
+ };
187
+ const configRenames = {};
188
+ const isDisabledOptionSupported = tinymce => !isLessThan(tinymce, '7.6.0');
189
+ class TinyMceEditor extends HTMLElement {
190
+ static get formAssociated() {
191
+ return true;
192
+ }
193
+ static get observedAttributes() {
194
+ const nativeEvents = [
195
+ 'on-BeforePaste',
196
+ 'on-Blur',
197
+ 'on-Click',
198
+ 'on-ContextMenu',
199
+ 'on-Copy',
200
+ 'on-Cut',
201
+ 'on-Dblclick',
202
+ 'on-Drag',
203
+ 'on-DragDrop',
204
+ 'on-DragEnd',
205
+ 'on-DragGesture',
206
+ 'on-DragOver',
207
+ 'on-Drop',
208
+ 'on-Focus',
209
+ 'on-FocusIn',
210
+ 'on-FocusOut',
211
+ 'on-KeyDown',
212
+ 'on-KeyPress',
213
+ 'on-KeyUp',
214
+ 'on-MouseDown',
215
+ 'on-MouseEnter',
216
+ 'on-MouseLeave',
217
+ 'on-MouseMove',
218
+ 'on-MouseOut',
219
+ 'on-MouseOver',
220
+ 'on-MouseUp',
221
+ 'on-Paste',
222
+ 'on-SelectionChange'
223
+ ];
224
+ const tinyEvents = [
225
+ 'on-Activate',
226
+ 'on-AddUndo',
227
+ 'on-BeforeAddUndo',
228
+ 'on-BeforeExecCommand',
229
+ 'on-BeforeGetContent',
230
+ 'on-BeforeRenderUI',
231
+ 'on-BeforeSetContent',
232
+ 'on-Change',
233
+ 'on-ClearUndos',
234
+ 'on-Deactivate',
235
+ 'on-Dirty',
236
+ 'on-ExecCommand',
237
+ 'on-GetContent',
238
+ 'on-Hide',
239
+ 'on-Init',
240
+ 'on-LoadContent',
241
+ 'on-NodeChange',
242
+ 'on-PostProcess',
243
+ 'on-PostRender',
244
+ 'on-PreProcess',
245
+ 'on-ProgressState',
246
+ 'on-Redo',
247
+ 'on-Remove',
248
+ 'on-Reset',
249
+ 'on-SaveContent',
250
+ 'on-SetAttrib',
251
+ 'on-ObjectResizeStart',
252
+ 'on-ObjectResized',
253
+ 'on-ObjectSelected',
254
+ 'on-SetContent',
255
+ 'on-Show',
256
+ 'on-Submit',
257
+ 'on-Undo',
258
+ 'on-VisualAid'
259
+ ];
260
+ return [
261
+ 'form',
262
+ 'readonly',
263
+ 'autofocus',
264
+ 'placeholder',
265
+ 'disabled'
266
+ ].concat(nativeEvents).concat(tinyEvents);
267
+ }
268
+ constructor() {
269
+ super();
270
+ this._eventAttrHandler = records => {
271
+ records.forEach(record => {
272
+ var _a;
273
+ if (record.type === 'attributes' && record.target === this && ((_a = record.attributeName) === null || _a === void 0 ? void 0 : _a.toLowerCase().startsWith('on-'))) {
274
+ this._updateEventAttr(record.attributeName, this.getAttribute(record.attributeName));
275
+ }
276
+ });
277
+ };
278
+ this._formDataHandler = evt => {
279
+ const name = this.name;
280
+ if (name != null) {
281
+ const value = this.value;
282
+ if (value != null) {
283
+ const data = evt.formData;
284
+ data.append(name, value);
285
+ }
286
+ }
287
+ };
288
+ this._status = Status.Raw;
289
+ this._shadowDom = this.attachShadow({ mode: 'open' });
290
+ this._form = null;
291
+ this._eventHandlers = {};
292
+ this._mutationObserver = new MutationObserver(this._eventAttrHandler);
293
+ }
294
+ _updateEventAttr(attrKey, attrValue) {
295
+ const event = attrKey.substring('on-'.length).toLowerCase();
296
+ const resolved = attrValue !== null ? resolve(attrValue) : undefined;
297
+ const handler = typeof resolved === 'function' ? resolved : undefined;
298
+ if (this._eventHandlers[event] !== handler) {
299
+ if (this._editor && this._eventHandlers[event]) {
300
+ this._editor.off(event, this._eventHandlers[event]);
301
+ }
302
+ if (handler) {
303
+ if (this._editor) {
304
+ this._editor.on(event, handler);
305
+ }
306
+ this._eventHandlers[event] = handler;
307
+ } else {
308
+ delete this._eventHandlers[event];
309
+ }
310
+ }
311
+ }
312
+ _updateForm() {
313
+ if (this.isConnected) {
314
+ const formId = this.getAttribute('form');
315
+ const form = formId !== null ? this.ownerDocument.querySelector('form#' + formId) : closestRecursive('form', this);
316
+ if (this._form !== form) {
317
+ if (this._form !== null) {
318
+ this._form.removeEventListener('formdata', this._formDataHandler);
319
+ }
320
+ this._form = form;
321
+ if (this._form !== null) {
322
+ this._form.addEventListener('formdata', this._formDataHandler);
323
+ }
324
+ }
325
+ } else {
326
+ if (this._form !== null) {
327
+ this._form.removeEventListener('formdata', this._formDataHandler);
328
+ this._form = null;
329
+ }
330
+ }
331
+ }
332
+ _getTinymce() {
333
+ return Global.tinymce;
334
+ }
335
+ _getConfig() {
336
+ var _a, _b;
337
+ const config = (_b = parseGlobal((_a = this.getAttribute('config')) !== null && _a !== void 0 ? _a : '')) !== null && _b !== void 0 ? _b : {};
338
+ for (let i = 0; i < this.attributes.length; i++) {
339
+ const attr = this.attributes.item(i);
340
+ if (attr !== null) {
341
+ if (has(configAttributes, attr.name)) {
342
+ const prop = has(configRenames, attr.name) ? configRenames[attr.name] : attr.name;
343
+ config[prop] = configAttributes[attr.name](attr.value);
344
+ }
345
+ }
346
+ }
347
+ if (this.readonly) {
348
+ config.readonly = true;
349
+ }
350
+ if (this.disabled) {
351
+ config.disabled = true;
352
+ }
353
+ if (this.autofocus) {
354
+ config.auto_focus = true;
355
+ }
356
+ delete config.target;
357
+ delete config.selector;
358
+ return config;
359
+ }
360
+ _getEventHandlers() {
361
+ const handlers = {};
362
+ for (let i = 0; i < this.attributes.length; i++) {
363
+ const attr = this.attributes.item(i);
364
+ if (attr !== null) {
365
+ if (attr.name.toLowerCase().startsWith('on-')) {
366
+ const event = attr.name.toLowerCase().substring('on-'.length);
367
+ const handler = resolve(attr.value);
368
+ if (typeof handler === 'function') {
369
+ handlers[event] = handler;
370
+ }
371
+ }
372
+ }
373
+ }
374
+ return handlers;
375
+ }
376
+ _doInit() {
377
+ var _a, _b;
378
+ this._status = Status.Initializing;
379
+ const target = document.createElement('textarea');
380
+ target.value = (_a = this.textContent) !== null && _a !== void 0 ? _a : '';
381
+ const attrId = (_b = this.attributes.getNamedItem('id')) === null || _b === void 0 ? void 0 : _b.value;
382
+ if (attrId) {
383
+ target.id = attrId;
384
+ }
385
+ if (this.placeholder !== null) {
386
+ target.placeholder = this.placeholder;
387
+ }
388
+ this._shadowDom.appendChild(target);
389
+ const baseConfig = this._getConfig();
390
+ const conf = Object.assign(Object.assign(Object.assign({}, baseConfig), {
391
+ disabled: this.hasAttribute('disabled'),
392
+ readonly: this.hasAttribute('readonly')
393
+ }), {
394
+ target,
395
+ setup: editor => {
396
+ this._editor = editor;
397
+ editor.on('init', _e => {
398
+ this._status = Status.Ready;
399
+ });
400
+ editor.on('SwitchMode', _e => {
401
+ this.readonly = this.readonly;
402
+ });
403
+ editor.on('DisabledStateChange', _e => {
404
+ this.disabled = this.disabled;
405
+ });
406
+ each(this._eventHandlers, (handler, event) => {
407
+ if (handler !== undefined) {
408
+ editor.on(event, handler);
409
+ }
410
+ });
411
+ if (typeof baseConfig.setup === 'function') {
412
+ baseConfig.setup(editor);
413
+ }
414
+ }
415
+ });
416
+ this._getTinymce().init(conf);
417
+ }
418
+ _getTinymceSrc() {
419
+ var _a;
420
+ const src = this.getAttribute('src');
421
+ if (src) {
422
+ return src;
423
+ }
424
+ const channel = (_a = this.getAttribute('channel')) !== null && _a !== void 0 ? _a : '8';
425
+ const apiKey = this.hasAttribute('api-key') ? this.getAttribute('api-key') : 'no-api-key';
426
+ return `https://cdn.tiny.cloud/1/${ apiKey }/tinymce/${ channel }/tinymce.min.js`;
427
+ }
428
+ _loadTinyDoInit() {
429
+ if (this._getTinymce()) {
430
+ this._doInit();
431
+ } else {
432
+ ScriptLoader.load(this.ownerDocument, this._getTinymceSrc(), () => this._doInit());
433
+ }
434
+ }
435
+ attributeChangedCallback(attribute, oldValue, newValue) {
436
+ if (oldValue !== newValue) {
437
+ if (attribute === 'form') {
438
+ this._updateForm();
439
+ } else if (attribute === 'disabled') {
440
+ this.disabled = newValue !== null;
441
+ } else if (attribute === 'readonly') {
442
+ this.readonly = newValue !== null;
443
+ } else if (attribute === 'autofocus') {
444
+ this.autofocus = newValue !== null;
445
+ } else if (attribute === 'placeholder') {
446
+ this.placeholder = newValue;
447
+ } else if (attribute.toLowerCase().startsWith('on-')) {
448
+ this._updateEventAttr(attribute, newValue);
449
+ }
450
+ }
451
+ }
452
+ connectedCallback() {
453
+ this._eventHandlers = this._getEventHandlers();
454
+ this._mutationObserver.observe(this, {
455
+ attributes: true,
456
+ childList: false,
457
+ subtree: false
458
+ });
459
+ this._updateForm();
460
+ if (this._status === Status.Raw) {
461
+ this._loadTinyDoInit();
462
+ }
463
+ }
464
+ disconnectedCallback() {
465
+ this._mutationObserver.disconnect();
466
+ this._updateForm();
467
+ }
468
+ get value() {
469
+ var _a, _b;
470
+ return (_b = this._status === Status.Ready ? (_a = this._editor) === null || _a === void 0 ? void 0 : _a.getContent() : undefined) !== null && _b !== void 0 ? _b : null;
471
+ }
472
+ set value(newValue) {
473
+ var _a;
474
+ if (this._status === Status.Ready && newValue != null) {
475
+ (_a = this._editor) === null || _a === void 0 ? void 0 : _a.setContent(newValue);
476
+ }
477
+ }
478
+ get readonly() {
479
+ if (this._editor) {
480
+ return this._editor.mode.get() === 'readonly';
481
+ } else {
482
+ return this.hasAttribute('readonly');
483
+ }
484
+ }
485
+ set readonly(value) {
486
+ if (value) {
487
+ if (this._editor && this._editor.mode.get() !== 'readonly') {
488
+ this._editor.mode.set('readonly');
489
+ }
490
+ if (!this.hasAttribute('readonly')) {
491
+ this.setAttribute('readonly', '');
492
+ }
493
+ } else {
494
+ if (this._editor && this._editor.mode.get() === 'readonly') {
495
+ this._editor.mode.set('design');
496
+ }
497
+ if (this.hasAttribute('readonly')) {
498
+ this.removeAttribute('readonly');
499
+ }
500
+ }
501
+ }
502
+ get disabled() {
503
+ return this._editor ? this._editor.options.get('disabled') : this.hasAttribute('disabled');
504
+ }
505
+ set disabled(value) {
506
+ var _a;
507
+ const tinymce = (_a = this._getTinymce) === null || _a === void 0 ? void 0 : _a.call(this);
508
+ const isVersionNewer = tinymce ? isDisabledOptionSupported(tinymce) : true;
509
+ if (this._editor && this._status === Status.Ready && isVersionNewer) {
510
+ this._editor.options.set('disabled', value);
511
+ }
512
+ if (value && !this.hasAttribute('disabled')) {
513
+ this.setAttribute('disabled', '');
514
+ } else if (!value && this.hasAttribute('disabled')) {
515
+ this.removeAttribute('disabled');
516
+ }
517
+ }
518
+ get placeholder() {
519
+ return this.getAttribute('placeholder');
520
+ }
521
+ set placeholder(value) {
522
+ if (this._editor) {
523
+ const target = this._editor.getElement();
524
+ if (target !== null) {
525
+ if (value !== null) {
526
+ target.setAttribute('placeholder', value);
527
+ } else {
528
+ target.removeAttribute('placeholder');
529
+ }
530
+ }
531
+ }
532
+ if (value !== null) {
533
+ if (this.getAttribute('placeholder') !== value) {
534
+ this.setAttribute('placeholder', value);
535
+ }
536
+ } else {
537
+ if (this.hasAttribute('placeholder')) {
538
+ this.removeAttribute('placeholder');
539
+ }
540
+ }
541
+ }
542
+ get autofocus() {
543
+ return this.hasAttribute('autofocus');
544
+ }
545
+ set autofocus(value) {
546
+ if (value) {
547
+ if (!this.hasAttribute('autofocus')) {
548
+ this.setAttribute('autofocus', '');
549
+ }
550
+ } else {
551
+ if (this.hasAttribute('autofocus')) {
552
+ this.removeAttribute('autofocus');
553
+ }
554
+ }
555
+ }
556
+ get form() {
557
+ return this._form;
558
+ }
559
+ get name() {
560
+ return this.getAttribute('name');
561
+ }
562
+ get type() {
563
+ return this.localName;
564
+ }
565
+ }
566
+ var Editor = () => {
567
+ window.customElements.define('tinymce-editor', TinyMceEditor);
568
+ };
569
+
570
+ Editor();
571
+
572
+ })();
package/package.json CHANGED
@@ -51,6 +51,6 @@
51
51
  "dependencies": {
52
52
  "@tinymce/miniature": "^6.0.0"
53
53
  },
54
- "version": "2.3.0",
54
+ "version": "2.3.1-feature.20250811004338301.sha63e3578",
55
55
  "name": "@tinymce/tinymce-webcomponent"
56
56
  }