@techie_doubts/editor-plugin-export 3.0.1

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.
@@ -0,0 +1,800 @@
1
+ /*!
2
+ * TOAST UI Editor : Export Plugin
3
+ * @version 3.0.1 | Fri Feb 20 2026
4
+ * @author NHN Cloud FE Development Lab <dl_javascript@nhn.com>
5
+ * @license MIT
6
+ */
7
+ (function webpackUniversalModuleDefinition(root, factory) {
8
+ if(typeof exports === 'object' && typeof module === 'object')
9
+ module.exports = factory();
10
+ else if(typeof define === 'function' && define.amd)
11
+ define([], factory);
12
+ else if(typeof exports === 'object')
13
+ exports["toastui"] = factory();
14
+ else
15
+ root["toastui"] = root["toastui"] || {}, root["toastui"]["Editor"] = root["toastui"]["Editor"] || {}, root["toastui"]["Editor"]["plugin"] = root["toastui"]["Editor"]["plugin"] || {}, root["toastui"]["Editor"]["plugin"]["export"] = factory();
16
+ })(self, function() {
17
+ return /******/ (function() { // webpackBootstrap
18
+ /******/ "use strict";
19
+ /******/ // The require scope
20
+ /******/ var __webpack_require__ = {};
21
+ /******/
22
+ /************************************************************************/
23
+ /******/ /* webpack/runtime/define property getters */
24
+ /******/ !function() {
25
+ /******/ // define getter functions for harmony exports
26
+ /******/ __webpack_require__.d = function(exports, definition) {
27
+ /******/ for(var key in definition) {
28
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
29
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
30
+ /******/ }
31
+ /******/ }
32
+ /******/ };
33
+ /******/ }();
34
+ /******/
35
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
36
+ /******/ !function() {
37
+ /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
38
+ /******/ }();
39
+ /******/
40
+ /************************************************************************/
41
+ var __webpack_exports__ = {};
42
+
43
+ // EXPORTS
44
+ __webpack_require__.d(__webpack_exports__, {
45
+ "default": function() { return /* binding */ exportPlugin; }
46
+ });
47
+
48
+ ;// ./src/theme.ts
49
+ function detectEditorDarkClass(instance) {
50
+ var _a, _b, _c;
51
+ if (typeof document === 'undefined') {
52
+ return null;
53
+ }
54
+ var elements = null;
55
+ try {
56
+ elements = (_a = instance.getEditorElements) === null || _a === void 0 ? void 0 : _a.call(instance);
57
+ }
58
+ catch (e) {
59
+ elements = null;
60
+ }
61
+ var root = ((_b = elements === null || elements === void 0 ? void 0 : elements.mdPreview) === null || _b === void 0 ? void 0 : _b.closest('.toastui-editor-defaultUI')) ||
62
+ ((_c = elements === null || elements === void 0 ? void 0 : elements.wwEditor) === null || _c === void 0 ? void 0 : _c.closest('.toastui-editor-defaultUI')) ||
63
+ document.querySelector('.toastui-editor-defaultUI');
64
+ if (!root) {
65
+ return null;
66
+ }
67
+ return root.classList.contains('toastui-editor-dark');
68
+ }
69
+ function resolveExportTheme(instance) {
70
+ var _a;
71
+ var darkFromDom = detectEditorDarkClass(instance);
72
+ if (typeof darkFromDom === 'boolean') {
73
+ return darkFromDom ? 'dark' : 'default';
74
+ }
75
+ try {
76
+ return ((_a = instance.getTheme) === null || _a === void 0 ? void 0 : _a.call(instance)) === 'dark' ? 'dark' : 'default';
77
+ }
78
+ catch (e) {
79
+ return 'default';
80
+ }
81
+ }
82
+
83
+ ;// ./src/index.ts
84
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
85
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
86
+ return new (P || (P = Promise))(function (resolve, reject) {
87
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
88
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
89
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
90
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
91
+ });
92
+ };
93
+ var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
94
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
95
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
96
+ function verb(n) { return function (v) { return step([n, v]); }; }
97
+ function step(op) {
98
+ if (f) throw new TypeError("Generator is already executing.");
99
+ while (_) try {
100
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
101
+ if (y = 0, t) op = [op[0] & 2, t.value];
102
+ switch (op[0]) {
103
+ case 0: case 1: t = op; break;
104
+ case 4: _.label++; return { value: op[1], done: false };
105
+ case 5: _.label++; y = op[1]; op = [0]; continue;
106
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
107
+ default:
108
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
109
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
110
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
111
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
112
+ if (t[2]) _.ops.pop();
113
+ _.trys.pop(); continue;
114
+ }
115
+ op = body.call(thisArg, _);
116
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
117
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
118
+ }
119
+ };
120
+
121
+
122
+ function getMenuState() {
123
+ var win = window;
124
+ if (!win.__toastuiToolbarMenuState) {
125
+ win.__toastuiToolbarMenuState = { openId: null };
126
+ }
127
+ return win.__toastuiToolbarMenuState;
128
+ }
129
+ function ensureMenuStateListener(state) {
130
+ if (state.listenerAttached || typeof document === 'undefined')
131
+ return;
132
+ document.addEventListener('mousedown', function (event) {
133
+ var target = event.target;
134
+ if (target.closest('.toastui-editor-popup') ||
135
+ target.closest('.toastui-editor-toolbar-item-wrapper')) {
136
+ return;
137
+ }
138
+ state.openId = null;
139
+ });
140
+ state.listenerAttached = true;
141
+ }
142
+ function createMenuItem(label, iconClassName, onSelect, closePopup) {
143
+ var item = document.createElement('li');
144
+ var icon = document.createElement('span');
145
+ var text = document.createElement('span');
146
+ item.className = 'menu-item';
147
+ item.setAttribute('role', 'menuitem');
148
+ item.tabIndex = 0;
149
+ icon.className = "export-menu-icon " + iconClassName;
150
+ text.textContent = label;
151
+ item.appendChild(icon);
152
+ item.appendChild(text);
153
+ var handleSelect = function () {
154
+ onSelect();
155
+ closePopup();
156
+ };
157
+ item.addEventListener('click', function (event) {
158
+ event.preventDefault();
159
+ handleSelect();
160
+ });
161
+ item.addEventListener('keydown', function (event) {
162
+ if (event.key === 'Enter' || event.key === ' ') {
163
+ event.preventDefault();
164
+ handleSelect();
165
+ }
166
+ else if (event.key === 'Escape') {
167
+ event.preventDefault();
168
+ closePopup();
169
+ }
170
+ });
171
+ return item;
172
+ }
173
+ function createMenuBody(items) {
174
+ var list = document.createElement('ul');
175
+ list.className = 'menu-group';
176
+ list.setAttribute('role', 'menu');
177
+ items.forEach(function (item) { return list.appendChild(item); });
178
+ return list;
179
+ }
180
+ function createExportSplitButton(onMainClick) {
181
+ var container = document.createElement('div');
182
+ var mainButton = document.createElement('button');
183
+ var caretButton = document.createElement('button');
184
+ var icon = document.createElement('span');
185
+ container.className = 'export-split';
186
+ container.setAttribute('role', 'group');
187
+ mainButton.type = 'button';
188
+ mainButton.className = 'toastui-editor-toolbar-icons export-split-main';
189
+ mainButton.setAttribute('aria-label', 'Download HTML');
190
+ icon.className = 'export-split-icon';
191
+ mainButton.appendChild(icon);
192
+ caretButton.type = 'button';
193
+ caretButton.className = 'toastui-editor-toolbar-icons export-split-caret';
194
+ caretButton.setAttribute('aria-label', 'Export options');
195
+ caretButton.setAttribute('aria-haspopup', 'menu');
196
+ caretButton.textContent = '▾';
197
+ mainButton.addEventListener('click', function (event) {
198
+ event.preventDefault();
199
+ event.stopPropagation();
200
+ onMainClick();
201
+ });
202
+ mainButton.addEventListener('keydown', function (event) {
203
+ if (event.key === 'Enter' || event.key === ' ') {
204
+ event.preventDefault();
205
+ event.stopPropagation();
206
+ onMainClick();
207
+ }
208
+ });
209
+ container.appendChild(mainButton);
210
+ container.appendChild(caretButton);
211
+ return container;
212
+ }
213
+ function downloadText(filename, content, type) {
214
+ if (type === void 0) { type = 'text/plain'; }
215
+ var blob = new Blob([content], { type: type });
216
+ var url = URL.createObjectURL(blob);
217
+ var a = document.createElement('a');
218
+ a.href = url;
219
+ a.download = filename;
220
+ document.body.appendChild(a);
221
+ a.click();
222
+ a.remove();
223
+ URL.revokeObjectURL(url);
224
+ }
225
+ function blobToDataUrl(blob) {
226
+ return new Promise(function (resolve, reject) {
227
+ var reader = new FileReader();
228
+ reader.onload = function () { return resolve(reader.result); };
229
+ reader.onerror = function () { return reject(reader.error); };
230
+ reader.readAsDataURL(blob);
231
+ });
232
+ }
233
+ function inlineImagesIn(rootEl) {
234
+ return __awaiter(this, void 0, void 0, function () {
235
+ var imgs;
236
+ var _this = this;
237
+ return __generator(this, function (_a) {
238
+ switch (_a.label) {
239
+ case 0:
240
+ imgs = Array.from(rootEl.querySelectorAll('img'));
241
+ return [4 /*yield*/, Promise.all(imgs.map(function (img) { return __awaiter(_this, void 0, void 0, function () {
242
+ var src, url, res, blob, dataUrl, e_1;
243
+ return __generator(this, function (_a) {
244
+ switch (_a.label) {
245
+ case 0:
246
+ src = img.getAttribute('src');
247
+ if (!src || src.startsWith('data:'))
248
+ return [2 /*return*/];
249
+ url = src;
250
+ if (url.startsWith('//')) {
251
+ url = "https:" + url;
252
+ }
253
+ else if (!/^https?:\/\//i.test(url)) {
254
+ url = new URL(url, window.location.href).href;
255
+ }
256
+ _a.label = 1;
257
+ case 1:
258
+ _a.trys.push([1, 5, , 6]);
259
+ return [4 /*yield*/, fetch(url)];
260
+ case 2:
261
+ res = _a.sent();
262
+ if (!res.ok)
263
+ throw new Error("HTTP " + res.status);
264
+ return [4 /*yield*/, res.blob()];
265
+ case 3:
266
+ blob = _a.sent();
267
+ return [4 /*yield*/, blobToDataUrl(blob)];
268
+ case 4:
269
+ dataUrl = _a.sent();
270
+ img.setAttribute('src', dataUrl);
271
+ return [3 /*break*/, 6];
272
+ case 5:
273
+ e_1 = _a.sent();
274
+ // eslint-disable-next-line no-console
275
+ console.warn('Failed to inline image (likely CORS):', url, e_1);
276
+ return [3 /*break*/, 6];
277
+ case 6: return [2 /*return*/];
278
+ }
279
+ });
280
+ }); }))];
281
+ case 1:
282
+ _a.sent();
283
+ return [2 /*return*/];
284
+ }
285
+ });
286
+ });
287
+ }
288
+ function inlineCanvases(fromRoot, toRoot) {
289
+ var srcCanvases = Array.from(fromRoot.querySelectorAll('canvas'));
290
+ var dstCanvases = Array.from(toRoot.querySelectorAll('canvas'));
291
+ srcCanvases.forEach(function (canvas, idx) {
292
+ var target = dstCanvases[idx];
293
+ if (!target)
294
+ return;
295
+ try {
296
+ var dataUrl = canvas.toDataURL('image/png');
297
+ var img = document.createElement('img');
298
+ img.src = dataUrl;
299
+ img.width = canvas.width;
300
+ img.height = canvas.height;
301
+ img.style.width = canvas.style.width;
302
+ img.style.height = canvas.style.height;
303
+ target.replaceWith(img);
304
+ }
305
+ catch (e) {
306
+ // eslint-disable-next-line no-console
307
+ console.warn('Inline canvas failed:', e);
308
+ }
309
+ });
310
+ }
311
+ function collectInlineStyles() {
312
+ var cssText = '';
313
+ for (var _i = 0, _a = Array.from(document.styleSheets); _i < _a.length; _i++) {
314
+ var sheet = _a[_i];
315
+ try {
316
+ var rules = sheet.cssRules;
317
+ if (!rules)
318
+ continue;
319
+ for (var _b = 0, _c = Array.from(rules); _b < _c.length; _b++) {
320
+ var rule = _c[_b];
321
+ cssText += rule.cssText + "\n";
322
+ }
323
+ }
324
+ catch (e) {
325
+ // ignore cross-origin styles
326
+ }
327
+ }
328
+ return cssText;
329
+ }
330
+ function inlineTokenStyles(original, clone) {
331
+ var origTokens = Array.from(original.querySelectorAll('[class*="token"]'));
332
+ var cloneTokens = Array.from(clone.querySelectorAll('[class*="token"]'));
333
+ origTokens.forEach(function (origEl, idx) {
334
+ var cloneEl = cloneTokens[idx];
335
+ if (!cloneEl)
336
+ return;
337
+ var cs = getComputedStyle(origEl);
338
+ if (cs.color) {
339
+ cloneEl.style.color = cs.color;
340
+ }
341
+ if (cs.fontWeight && cs.fontWeight !== 'normal' && cs.fontWeight !== '400') {
342
+ cloneEl.style.fontWeight = cs.fontWeight;
343
+ }
344
+ if (cs.fontStyle && cs.fontStyle !== 'normal') {
345
+ cloneEl.style.fontStyle = cs.fontStyle;
346
+ }
347
+ });
348
+ }
349
+ function fixLineNumberInputs(original, clone) {
350
+ var origInputs = Array.from(original.querySelectorAll('.toastui-editor-line-number-input'));
351
+ var cloneInputs = Array.from(clone.querySelectorAll('.toastui-editor-line-number-input'));
352
+ origInputs.forEach(function (origEl, idx) {
353
+ var cloneEl = cloneInputs[idx];
354
+ if (!cloneEl)
355
+ return;
356
+ var val = origEl.value || 'off';
357
+ var span = document.createElement('span');
358
+ span.className = cloneEl.className;
359
+ span.textContent = val;
360
+ span.style.display = 'inline-block';
361
+ span.style.textAlign = 'center';
362
+ span.style.minWidth = '42px';
363
+ cloneEl.replaceWith(span);
364
+ });
365
+ }
366
+ function normalizeFragmentId(text) {
367
+ return text.trim().replace(/\\s+/g, '_');
368
+ }
369
+ function normalizeFragmentHref(text) {
370
+ return "#" + normalizeFragmentId(text);
371
+ }
372
+ function slugify(text) {
373
+ return normalizeFragmentId(text).replace(/_+/g, '_');
374
+ }
375
+ function toHashHref(id) {
376
+ return normalizeFragmentHref(id);
377
+ }
378
+ function safeDecodeURIComponent(value) {
379
+ try {
380
+ return decodeURIComponent(value);
381
+ }
382
+ catch (e) {
383
+ return value;
384
+ }
385
+ }
386
+ function normalizeText(text) {
387
+ return text.replace(/\s+/g, ' ').trim();
388
+ }
389
+ function createUniqueId(baseId, usedIds) {
390
+ var id = baseId || 'heading';
391
+ var suffix = 1;
392
+ while (usedIds.has(id)) {
393
+ id = baseId + "-" + suffix;
394
+ suffix += 1;
395
+ }
396
+ usedIds.add(id);
397
+ return id;
398
+ }
399
+ function ensureHeadingIds(root) {
400
+ var usedIds = new Set();
401
+ var headings = Array.from(root.querySelectorAll('h1, h2, h3, h4, h5, h6'));
402
+ headings.forEach(function (heading) {
403
+ var _a;
404
+ var existingId = (_a = heading.getAttribute('id')) === null || _a === void 0 ? void 0 : _a.trim();
405
+ var baseId = existingId || slugify(heading.textContent || '') || 'heading';
406
+ var uniqueId = createUniqueId(baseId, usedIds);
407
+ heading.setAttribute('id', uniqueId);
408
+ heading.setAttribute('data-export-anchor-target', 'true');
409
+ });
410
+ }
411
+ function extractMarkdownAnchors(markdown) {
412
+ var anchors = [];
413
+ var reAnchor = /<a\s+[^>]*id\s*=\s*(?:"([^"]+)"|'([^']+)')[^>]*>([\s\S]*?)<\/a>/gi;
414
+ var match = reAnchor.exec(markdown);
415
+ while (match) {
416
+ var id = (match[1] || match[2] || '').trim();
417
+ var rawText = (match[3] || '').replace(/<[^>]+>/g, '');
418
+ var text = rawText.trim();
419
+ if (id && text) {
420
+ anchors.push({ id: id, text: text });
421
+ }
422
+ match = reAnchor.exec(markdown);
423
+ }
424
+ return anchors;
425
+ }
426
+ function addCustomAnchorTargets(root, markdownAnchors) {
427
+ var usedIds = new Set(Array.from(root.querySelectorAll('[id]'))
428
+ .map(function (el) { return el.id; })
429
+ .filter(Boolean));
430
+ var candidates = Array.from(root.querySelectorAll('span, a, mark, strong, em, code'));
431
+ markdownAnchors.forEach(function (_a) {
432
+ var id = _a.id, text = _a.text;
433
+ id = normalizeFragmentId(id);
434
+ var existing = root.querySelector("[id=\"" + CSS.escape(id) + "\"]");
435
+ if (existing) {
436
+ existing.setAttribute('data-export-anchor-target', 'true');
437
+ if (existing.tagName === 'A') {
438
+ var anchor = existing;
439
+ anchor.setAttribute('href', toHashHref(existing.id));
440
+ anchor.removeAttribute('target');
441
+ anchor.removeAttribute('rel');
442
+ }
443
+ return;
444
+ }
445
+ var normalizedAnchorText = normalizeText(text);
446
+ var anchorNodeTarget = candidates.find(function (candidate) {
447
+ if (candidate.tagName !== 'A') {
448
+ return false;
449
+ }
450
+ var href = candidate.getAttribute('href') || '';
451
+ if (href && href !== '#') {
452
+ return false;
453
+ }
454
+ return normalizeText(candidate.textContent || '') === normalizedAnchorText;
455
+ });
456
+ var target = anchorNodeTarget
457
+ ? anchorNodeTarget
458
+ : candidates.find(function (candidate) {
459
+ if (candidate.hasAttribute('id')) {
460
+ return false;
461
+ }
462
+ if (candidate.closest('a[href]')) {
463
+ return false;
464
+ }
465
+ return normalizeText(candidate.textContent || '') === normalizedAnchorText;
466
+ });
467
+ if (!target) {
468
+ return;
469
+ }
470
+ var uniqueId = createUniqueId(id, usedIds);
471
+ target.setAttribute('id', uniqueId);
472
+ target.setAttribute('data-export-anchor-target', 'true');
473
+ if (target.tagName === 'A') {
474
+ var anchor = target;
475
+ anchor.setAttribute('href', toHashHref(uniqueId));
476
+ anchor.removeAttribute('target');
477
+ anchor.removeAttribute('rel');
478
+ }
479
+ });
480
+ }
481
+ function extractFragmentDestinations(markdown) {
482
+ var destinations = [];
483
+ for (var i = 0; i < markdown.length; i += 1) {
484
+ if (markdown[i] !== '[' || markdown[i - 1] === '!') {
485
+ continue;
486
+ }
487
+ var labelEnd = i + 1;
488
+ while (labelEnd < markdown.length && markdown[labelEnd] !== ']') {
489
+ if (markdown[labelEnd] === '\\') {
490
+ labelEnd += 2;
491
+ }
492
+ else {
493
+ labelEnd += 1;
494
+ }
495
+ }
496
+ if (markdown[labelEnd] !== ']' || markdown[labelEnd + 1] !== '(') {
497
+ continue;
498
+ }
499
+ var cursor = labelEnd + 2;
500
+ while (cursor < markdown.length && /\s/.test(markdown[cursor])) {
501
+ cursor += 1;
502
+ }
503
+ if (markdown[cursor] !== '#') {
504
+ continue;
505
+ }
506
+ cursor += 1;
507
+ var start = cursor;
508
+ var depth = 1;
509
+ while (cursor < markdown.length) {
510
+ var ch = markdown[cursor];
511
+ if (ch === '\\') {
512
+ cursor += 2;
513
+ continue;
514
+ }
515
+ if (ch === '(') {
516
+ depth += 1;
517
+ }
518
+ else if (ch === ')') {
519
+ depth -= 1;
520
+ if (depth === 0) {
521
+ break;
522
+ }
523
+ }
524
+ cursor += 1;
525
+ }
526
+ if (depth === 0) {
527
+ var destination = markdown.slice(start, cursor).trim();
528
+ if (destination) {
529
+ destinations.push(destination);
530
+ }
531
+ i = cursor;
532
+ }
533
+ }
534
+ return destinations;
535
+ }
536
+ function resolveTargetId(rawDestination, root) {
537
+ var raw = rawDestination.trim();
538
+ var decoded = safeDecodeURIComponent(raw);
539
+ var normalizedRaw = normalizeFragmentId(raw);
540
+ var normalizedDecoded = normalizeFragmentId(decoded);
541
+ var slug = slugify(decoded);
542
+ var candidates = [raw, decoded, normalizedRaw, normalizedDecoded, slug].filter(Boolean);
543
+ for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
544
+ var candidate = candidates_1[_i];
545
+ if (root.querySelector("[id=\"" + CSS.escape(candidate) + "\"]")) {
546
+ return candidate;
547
+ }
548
+ }
549
+ var headingByText = Array.from(root.querySelectorAll('h1, h2, h3, h4, h5, h6')).find(function (heading) { return normalizeText(heading.textContent || '') === normalizeText(decoded); });
550
+ if (headingByText === null || headingByText === void 0 ? void 0 : headingByText.id) {
551
+ return headingByText.id;
552
+ }
553
+ return normalizedDecoded || slug || decoded || raw;
554
+ }
555
+ function restoreFragmentLinks(root, markdown) {
556
+ var destinations = extractFragmentDestinations(markdown);
557
+ var links = Array.from(root.querySelectorAll('a[href]')).filter(function (link) {
558
+ var href = link.getAttribute('href') || '';
559
+ return ((href === '' || href.startsWith('#')) &&
560
+ link.getAttribute('data-export-anchor-target') !== 'true');
561
+ });
562
+ var count = Math.min(destinations.length, links.length);
563
+ for (var i = 0; i < count; i += 1) {
564
+ var resolvedId = resolveTargetId(destinations[i], root);
565
+ if (!resolvedId) {
566
+ continue;
567
+ }
568
+ links[i].setAttribute('href', toHashHref(resolvedId));
569
+ links[i].removeAttribute('target');
570
+ links[i].removeAttribute('rel');
571
+ }
572
+ }
573
+ function markSelfAnchors(root) {
574
+ Array.from(root.querySelectorAll('[id]')).forEach(function (el) {
575
+ if (el.matches('h1, h2, h3, h4, h5, h6') ||
576
+ el.getAttribute('data-export-anchor-target') === 'true') {
577
+ el.setAttribute('data-export-self-anchor', 'true');
578
+ }
579
+ });
580
+ }
581
+ function buildStandaloneHtml(bodyHtml, isDark) {
582
+ var styles = collectInlineStyles();
583
+ var darkClass = isDark ? ' toastui-editor-dark' : '';
584
+ var bgStyle = isDark ? 'background:#121212;' : '';
585
+ return "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\"/>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n <title>Toast UI Export</title>\n <style>\n" + styles + "\n </style>\n </head>\n <body style=\"margin:0;" + bgStyle + "\">\n <div class=\"" + darkClass.trim() + "\" style=\"max-width:960px;margin:0 auto;padding:24px 32px\">\n <div class=\"toastui-editor-contents\">" + bodyHtml + "</div>\n </div>\n <script>\n document.querySelectorAll('.toastui-editor-code-block-copy').forEach(function(b){\n b.addEventListener('click',function(){\n var w=b.closest('.toastui-editor-ww-code-block-highlighting');\n var c=w&&w.querySelector('code');\n if(c){navigator.clipboard.writeText(c.textContent).then(function(){\n b.classList.add('copied');setTimeout(function(){b.classList.remove('copied')},1500);\n })}\n });\n });\n function safeDecode(value){\n try{return decodeURIComponent(value);}catch(e){return value;}\n }\n function resolveAnchorTarget(rawId){\n var decoded = safeDecode(rawId);\n var normalizedRaw = String(rawId).trim().replace(/\\s+/g, '_');\n var normalizedDecoded = String(decoded).trim().replace(/\\s+/g, '_');\n var candidates = [rawId, decoded, normalizedRaw, normalizedDecoded].filter(Boolean);\n for(var i=0;i<candidates.length;i+=1){\n var id = candidates[i];\n var byId = document.getElementById(id);\n if(byId){return { id: id, el: byId };}\n try {\n var escaped = CSS && CSS.escape ? CSS.escape(id) : id.replace(/([\"'\\.#:[,=])/g,'\\$1');\n var byQuery = document.querySelector('[id=\"' + escaped + '\"]');\n if(byQuery){return { id: id, el: byQuery };}\n } catch(err) {}\n }\n return null;\n }\n function navigateToHash(rawHash){\n var hash = rawHash || '';\n if(!hash || hash[0] !== '#'){return;}\n var rawId = hash.slice(1);\n var resolved = resolveAnchorTarget(rawId);\n if(!resolved){return;}\n var nextHash = '#' + resolved.id;\n if(window.location.hash !== nextHash){\n history.replaceState(null,'', nextHash);\n }\n resolved.el.scrollIntoView({ block: 'start' });\n }\n document.querySelectorAll('a[href^=\"#\"]').forEach(function(link){\n link.removeAttribute('target');\n link.removeAttribute('rel');\n link.addEventListener('click', function(event){\n var href = link.getAttribute('href') || '';\n if(!href || href === '#'){return;}\n event.preventDefault();\n navigateToHash(href);\n });\n });\n document.querySelectorAll('[data-export-self-anchor=\"true\"]').forEach(function(target){\n target.style.cursor='pointer';\n target.addEventListener('click', function(event){\n var id = target.getAttribute('id');\n if(!id){return;}\n if(target.tagName === 'A'){event.preventDefault();}\n navigateToHash('#' + id);\n });\n });\n " + '<' + "/script>\n </body>\n</html>\n";
586
+ }
587
+ function getWysiwygRoot(instance) {
588
+ var _a;
589
+ var elements = (_a = instance.getEditorElements) === null || _a === void 0 ? void 0 : _a.call(instance);
590
+ var wysiwygRoot = (elements === null || elements === void 0 ? void 0 : elements.wwEditor) || null;
591
+ if (!wysiwygRoot)
592
+ return null;
593
+ return (wysiwygRoot.querySelector('.toastui-editor-contents') || wysiwygRoot);
594
+ }
595
+ function nextFrame() {
596
+ return new Promise(function (resolve) {
597
+ requestAnimationFrame(function () { return resolve(); });
598
+ });
599
+ }
600
+ function nextTick() {
601
+ return new Promise(function (resolve) {
602
+ setTimeout(function () { return resolve(); }, 0);
603
+ });
604
+ }
605
+ function waitForWysiwygRender() {
606
+ return __awaiter(this, void 0, void 0, function () {
607
+ return __generator(this, function (_a) {
608
+ switch (_a.label) {
609
+ case 0: return [4 /*yield*/, Promise.resolve()];
610
+ case 1:
611
+ _a.sent();
612
+ return [4 /*yield*/, nextFrame()];
613
+ case 2:
614
+ _a.sent();
615
+ return [4 /*yield*/, nextFrame()];
616
+ case 3:
617
+ _a.sent();
618
+ return [4 /*yield*/, nextTick()];
619
+ case 4:
620
+ _a.sent();
621
+ return [2 /*return*/];
622
+ }
623
+ });
624
+ });
625
+ }
626
+ /**
627
+ * Export plugin
628
+ * @param {Object} context - plugin context for communicating with editor
629
+ * @param {Object} options - options for plugin
630
+ */
631
+ function exportPlugin(context, options) {
632
+ var _this = this;
633
+ var _a, _b;
634
+ if (options === void 0) { options = {}; }
635
+ var markdownFileName = options.markdownFileName || 'document.md';
636
+ var htmlFileName = options.htmlFileName || 'document.html';
637
+ var toolbarGroupIndex = (_a = options.toolbarGroupIndex) !== null && _a !== void 0 ? _a : 2;
638
+ var toolbarItemIndex = (_b = options.toolbarItemIndex) !== null && _b !== void 0 ? _b : 0;
639
+ var instance = context.instance;
640
+ var menuState = getMenuState();
641
+ ensureMenuStateListener(menuState);
642
+ var downloadMarkdown = function () {
643
+ if (!instance.getMarkdown)
644
+ return;
645
+ var md = instance.getMarkdown();
646
+ downloadText(markdownFileName, md, 'text/markdown');
647
+ };
648
+ var downloadHtml = function () { return __awaiter(_this, void 0, void 0, function () {
649
+ var wasMarkdownMode, exportTheme, isDark, markdownSource, htmlBody, exportOpts, promises, wysiwygRoot, clone, html;
650
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
651
+ return __generator(this, function (_l) {
652
+ switch (_l.label) {
653
+ case 0:
654
+ wasMarkdownMode = (_b = (_a = instance.isMarkdownMode) === null || _a === void 0 ? void 0 : _a.call(instance)) !== null && _b !== void 0 ? _b : false;
655
+ exportTheme = resolveExportTheme(instance);
656
+ isDark = exportTheme === 'dark';
657
+ markdownSource = (_d = (_c = instance.getMarkdown) === null || _c === void 0 ? void 0 : _c.call(instance)) !== null && _d !== void 0 ? _d : '';
658
+ htmlBody = '';
659
+ _l.label = 1;
660
+ case 1:
661
+ _l.trys.push([1, , 8, 9]);
662
+ if (wasMarkdownMode) {
663
+ (_e = instance.changeMode) === null || _e === void 0 ? void 0 : _e.call(instance, 'wysiwyg', true);
664
+ }
665
+ return [4 /*yield*/, waitForWysiwygRender()];
666
+ case 2:
667
+ _l.sent();
668
+ exportOpts = {
669
+ promises: [],
670
+ theme: exportTheme,
671
+ };
672
+ (_g = (_f = instance.eventEmitter) === null || _f === void 0 ? void 0 : _f.emit) === null || _g === void 0 ? void 0 : _g.call(_f, 'beforeExportHtml', exportOpts);
673
+ promises = exportOpts.promises;
674
+ if (!promises.length) return [3 /*break*/, 4];
675
+ return [4 /*yield*/, Promise.all(promises)];
676
+ case 3:
677
+ _l.sent();
678
+ _l.label = 4;
679
+ case 4: return [4 /*yield*/, nextFrame()];
680
+ case 5:
681
+ _l.sent();
682
+ wysiwygRoot = getWysiwygRoot(instance);
683
+ if (!(wysiwygRoot && wysiwygRoot.innerHTML.trim())) return [3 /*break*/, 7];
684
+ clone = wysiwygRoot.cloneNode(true);
685
+ inlineCanvases(wysiwygRoot, clone);
686
+ inlineTokenStyles(wysiwygRoot, clone);
687
+ fixLineNumberInputs(wysiwygRoot, clone);
688
+ ensureHeadingIds(clone);
689
+ addCustomAnchorTargets(clone, extractMarkdownAnchors(markdownSource));
690
+ restoreFragmentLinks(clone, markdownSource);
691
+ markSelfAnchors(clone);
692
+ return [4 /*yield*/, inlineImagesIn(clone)];
693
+ case 6:
694
+ _l.sent();
695
+ htmlBody = clone.innerHTML;
696
+ _l.label = 7;
697
+ case 7: return [3 /*break*/, 9];
698
+ case 8:
699
+ (_j = (_h = instance.eventEmitter) === null || _h === void 0 ? void 0 : _h.emit) === null || _j === void 0 ? void 0 : _j.call(_h, 'afterExportHtml');
700
+ if (wasMarkdownMode) {
701
+ (_k = instance.changeMode) === null || _k === void 0 ? void 0 : _k.call(instance, 'markdown', true);
702
+ }
703
+ return [7 /*endfinally*/];
704
+ case 9:
705
+ if (!htmlBody)
706
+ return [2 /*return*/];
707
+ html = buildStandaloneHtml(htmlBody, isDark);
708
+ downloadText(htmlFileName, html, 'text/html');
709
+ return [2 /*return*/];
710
+ }
711
+ });
712
+ }); };
713
+ var closePopup = function () {
714
+ context.eventEmitter.emit('closePopup');
715
+ menuState.openId = null;
716
+ };
717
+ var exportMenu = createMenuBody([
718
+ createMenuItem('Download HTML', 'export-menu-icon-html', downloadHtml, closePopup),
719
+ createMenuItem('Download Markdown', 'export-menu-icon-markdown', downloadMarkdown, closePopup),
720
+ ]);
721
+ var exportSplit = createExportSplitButton(downloadHtml);
722
+ var caretButton = exportSplit.querySelector('.export-split-caret');
723
+ var openExportMenu = function () {
724
+ var wrapper = exportSplit.closest('.toastui-editor-toolbar-item-wrapper');
725
+ if (wrapper) {
726
+ wrapper.dispatchEvent(new MouseEvent('click', { bubbles: true }));
727
+ }
728
+ };
729
+ if (caretButton) {
730
+ var toggleMenu_1 = function () {
731
+ if (menuState.openId === 'export') {
732
+ closePopup();
733
+ return;
734
+ }
735
+ closePopup();
736
+ menuState.openId = 'export';
737
+ openExportMenu();
738
+ };
739
+ caretButton.addEventListener('click', function (event) {
740
+ event.preventDefault();
741
+ event.stopPropagation();
742
+ toggleMenu_1();
743
+ });
744
+ caretButton.addEventListener('keydown', function (event) {
745
+ if (event.key === 'Enter' || event.key === ' ') {
746
+ event.preventDefault();
747
+ event.stopPropagation();
748
+ toggleMenu_1();
749
+ }
750
+ else if (event.key === 'Escape') {
751
+ event.preventDefault();
752
+ closePopup();
753
+ }
754
+ });
755
+ }
756
+ var toolbarItems = [
757
+ {
758
+ groupIndex: toolbarGroupIndex,
759
+ itemIndex: toolbarItemIndex,
760
+ item: {
761
+ name: 'exportSplit',
762
+ tooltip: 'Export',
763
+ el: exportSplit,
764
+ popup: {
765
+ body: exportMenu,
766
+ className: 'toastui-editor-popup-add-heading export-split-menu',
767
+ },
768
+ },
769
+ },
770
+ ];
771
+ return {
772
+ toolbarItems: toolbarItems,
773
+ markdownCommands: {
774
+ downloadMarkdown: function () {
775
+ downloadMarkdown();
776
+ return true;
777
+ },
778
+ downloadHtml: function () {
779
+ downloadHtml();
780
+ return true;
781
+ },
782
+ },
783
+ wysiwygCommands: {
784
+ downloadMarkdown: function () {
785
+ downloadMarkdown();
786
+ return true;
787
+ },
788
+ downloadHtml: function () {
789
+ downloadHtml();
790
+ return true;
791
+ },
792
+ },
793
+ };
794
+ }
795
+
796
+ __webpack_exports__ = __webpack_exports__["default"];
797
+ /******/ return __webpack_exports__;
798
+ /******/ })()
799
+ ;
800
+ });