@youcan/celeste 0.6.30 → 0.6.31
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/dist/celeste.css +293 -74
- package/dist/cjs/alert.js +2 -2
- package/dist/cjs/chunks/index.js +229 -2
- package/dist/cjs/chunks/index2.js +1457 -0
- package/dist/cjs/chunks/index3.js +16457 -0
- package/dist/cjs/chunks/sonner.js +1153 -0
- package/dist/cjs/config.js +136 -0
- package/dist/cjs/extra-settings.js +155 -0
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/label.js +2 -2
- package/dist/cjs/link-bubble.js +228 -0
- package/dist/cjs/link-button.js +2 -2
- package/dist/cjs/rich-editor.js +4996 -0
- package/dist/cjs/select-icon.js +2 -2
- package/dist/cjs/sonner-alert.js +41 -0
- package/dist/cjs/sonner.js +3 -0
- package/dist/cjs/text-input-affix.js +2 -2
- package/dist/cjs/types.js +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/rich-editor/config.d.ts +33 -0
- package/dist/components/rich-editor/extra-settings.d.ts +6 -0
- package/dist/components/rich-editor/index.d.ts +2 -0
- package/dist/components/rich-editor/link-bubble.d.ts +11 -0
- package/dist/components/rich-editor/rich-editor.d.ts +55 -0
- package/dist/components/rich-editor/types.d.ts +19 -0
- package/dist/components/sonner/index.d.ts +4 -0
- package/dist/components/sonner/sonner-alert.d.ts +13 -0
- package/dist/components/sonner/sonner.d.ts +5 -0
- package/dist/es/alert.js +2 -2
- package/dist/es/checkbox-label.js +1 -1
- package/dist/es/chunks/index.js +277 -50
- package/dist/es/chunks/index2.js +1457 -0
- package/dist/es/chunks/index3.js +16458 -0
- package/dist/es/chunks/sonner.js +1154 -0
- package/dist/es/combobox-group.js +1 -1
- package/dist/es/combobox-input.js +1 -1
- package/dist/es/combobox-item.js +1 -1
- package/dist/es/combobox-list.js +1 -1
- package/dist/es/combobox-root.js +1 -1
- package/dist/es/combobox-separator.js +1 -1
- package/dist/es/combobox-trigger.js +1 -1
- package/dist/es/command-group.js +1 -1
- package/dist/es/command-input.js +1 -1
- package/dist/es/command-item.js +1 -1
- package/dist/es/command-list.js +1 -1
- package/dist/es/command-root.js +1 -1
- package/dist/es/command-separator.js +1 -1
- package/dist/es/config.js +136 -0
- package/dist/es/dropdown-menu-group.js +1 -1
- package/dist/es/dropdown-menu-item.js +1 -1
- package/dist/es/dropdown-menu-label.js +1 -1
- package/dist/es/dropdown-menu-separator.js +1 -1
- package/dist/es/dropdown-menu-trigger.js +1 -1
- package/dist/es/dropdown-menu.js +1 -1
- package/dist/es/dropdown.js +1 -1
- package/dist/es/extra-settings.js +156 -0
- package/dist/es/index.js +27 -18
- package/dist/es/label.js +3 -3
- package/dist/es/link-bubble.js +229 -0
- package/dist/es/link-button.js +2 -2
- package/dist/es/modal-content.js +1 -1
- package/dist/es/modal-header.js +1 -1
- package/dist/es/popover-content.js +1 -1
- package/dist/es/popover-trigger.js +1 -1
- package/dist/es/rich-editor.js +4997 -0
- package/dist/es/scroll-bar.js +1 -1
- package/dist/es/segmented-control-item.js +1 -1
- package/dist/es/segmented-control.js +1 -1
- package/dist/es/select-content.js +1 -1
- package/dist/es/select-icon.js +2 -2
- package/dist/es/select-item.js +1 -1
- package/dist/es/select-trigger.js +1 -1
- package/dist/es/select-value.js +1 -1
- package/dist/es/sonner-alert.js +42 -0
- package/dist/es/sonner.js +4 -0
- package/dist/es/tab-menu-content.js +1 -1
- package/dist/es/tab-menu-item.js +1 -1
- package/dist/es/tab-menu-list.js +1 -1
- package/dist/es/tab-menu.js +1 -1
- package/dist/es/text-input-affix.js +2 -2
- package/dist/es/tooltip.js +1 -1
- package/dist/es/types.js +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/sonner.d.ts +19 -0
- package/package.json +15 -4
- package/src/components/index.ts +2 -0
- package/src/components/rich-editor/config.ts +150 -0
- package/src/components/rich-editor/extra-settings.vue +151 -0
- package/src/components/rich-editor/index.ts +2 -0
- package/src/components/rich-editor/link-bubble.vue +288 -0
- package/src/components/rich-editor/rich-editor.vue +428 -0
- package/src/components/rich-editor/stories/rich-editor.stories.ts +87 -0
- package/src/components/rich-editor/types.ts +21 -0
- package/src/components/sonner/index.ts +5 -0
- package/src/components/sonner/sonner-alert.vue +54 -0
- package/src/components/sonner/sonner.vue +13 -0
- package/src/components/sonner/stories/sonner.stories.ts +194 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/sonner.ts +72 -0
|
@@ -0,0 +1,4996 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const Mo = require("vue");
|
|
3
|
+
const compactButton = require("./compact-button.js");
|
|
4
|
+
const selectContent = require("./select-content.js");
|
|
5
|
+
const selectIcon = require("./select-icon.js");
|
|
6
|
+
const selectItem = require("./select-item.js");
|
|
7
|
+
const selectTrigger = require("./select-trigger.js");
|
|
8
|
+
const selectValue = require("./select-value.js");
|
|
9
|
+
const select_vue_vue_type_script_setup_true_lang = require("./chunks/select.js");
|
|
10
|
+
const tooltip = require("./tooltip.js");
|
|
11
|
+
const index = require("./chunks/index3.js");
|
|
12
|
+
const config = require("./config.js");
|
|
13
|
+
const extraSettings = require("./extra-settings.js");
|
|
14
|
+
const linkBubble = require("./link-bubble.js");
|
|
15
|
+
const _pluginVue_exportHelper = require("./chunks/_plugin-vue_export-helper.js");
|
|
16
|
+
const encodedTlds = "aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0america6xi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2";
|
|
17
|
+
const encodedUtlds = "ελ1υ2бг1ел3дети4ею2католик6ом3мкд2он1сква6онлайн5рг3рус2ф2сайт3рб3укр3қаз3հայ3ישראל5קום3ابوظبي5رامكو5لاردن4بحرين5جزائر5سعودية6عليان5مغرب5مارات5یران5بارت2زار4يتك3ھارت5تونس4سودان3رية5شبكة4عراق2ب2مان4فلسطين6قطر3كاثوليك6وم3مصر2ليسيا5وريتانيا7قع4همراه5پاکستان7ڀارت4कॉम3नेट3भारत0म्3ोत5संगठन5বাংলা5ভারত2ৰত4ਭਾਰਤ4ભારત4ଭାରତ4இந்தியா6லங்கை6சிங்கப்பூர்11భారత్5ಭಾರತ4ഭാരതം5ලංකා4คอม3ไทย3ລາວ3გე2みんな3アマゾン4クラウド4グーグル4コム2ストア3セール3ファッション6ポイント4世界2中信1国1國1文网3亚马逊3企业2佛山2信息2健康2八卦2公司1益2台湾1灣2商城1店1标2嘉里0大酒店5在线2大拿2天主教3娱乐2家電2广东2微博2慈善2我爱你3手机2招聘2政务1府2新加坡2闻2时尚2書籍2机构2淡马锡3游戏2澳門2点看2移动2组织机构4网址1店1站1络2联通2谷歌2购物2通販2集团2電訊盈科4飞利浦3食品2餐厅2香格里拉3港2닷넷1컴2삼성2한국2";
|
|
18
|
+
const assign = (target, properties) => {
|
|
19
|
+
for (const key in properties) {
|
|
20
|
+
target[key] = properties[key];
|
|
21
|
+
}
|
|
22
|
+
return target;
|
|
23
|
+
};
|
|
24
|
+
const numeric = "numeric";
|
|
25
|
+
const ascii = "ascii";
|
|
26
|
+
const alpha = "alpha";
|
|
27
|
+
const asciinumeric = "asciinumeric";
|
|
28
|
+
const alphanumeric = "alphanumeric";
|
|
29
|
+
const domain = "domain";
|
|
30
|
+
const emoji = "emoji";
|
|
31
|
+
const scheme = "scheme";
|
|
32
|
+
const slashscheme = "slashscheme";
|
|
33
|
+
const whitespace = "whitespace";
|
|
34
|
+
function registerGroup(name, groups) {
|
|
35
|
+
if (!(name in groups)) {
|
|
36
|
+
groups[name] = [];
|
|
37
|
+
}
|
|
38
|
+
return groups[name];
|
|
39
|
+
}
|
|
40
|
+
function addToGroups(t, flags, groups) {
|
|
41
|
+
if (flags[numeric]) {
|
|
42
|
+
flags[asciinumeric] = true;
|
|
43
|
+
flags[alphanumeric] = true;
|
|
44
|
+
}
|
|
45
|
+
if (flags[ascii]) {
|
|
46
|
+
flags[asciinumeric] = true;
|
|
47
|
+
flags[alpha] = true;
|
|
48
|
+
}
|
|
49
|
+
if (flags[asciinumeric]) {
|
|
50
|
+
flags[alphanumeric] = true;
|
|
51
|
+
}
|
|
52
|
+
if (flags[alpha]) {
|
|
53
|
+
flags[alphanumeric] = true;
|
|
54
|
+
}
|
|
55
|
+
if (flags[alphanumeric]) {
|
|
56
|
+
flags[domain] = true;
|
|
57
|
+
}
|
|
58
|
+
if (flags[emoji]) {
|
|
59
|
+
flags[domain] = true;
|
|
60
|
+
}
|
|
61
|
+
for (const k in flags) {
|
|
62
|
+
const group = registerGroup(k, groups);
|
|
63
|
+
if (group.indexOf(t) < 0) {
|
|
64
|
+
group.push(t);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function flagsForToken(t, groups) {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const c in groups) {
|
|
71
|
+
if (groups[c].indexOf(t) >= 0) {
|
|
72
|
+
result[c] = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
function State(token = null) {
|
|
78
|
+
this.j = {};
|
|
79
|
+
this.jr = [];
|
|
80
|
+
this.jd = null;
|
|
81
|
+
this.t = token;
|
|
82
|
+
}
|
|
83
|
+
State.groups = {};
|
|
84
|
+
State.prototype = {
|
|
85
|
+
accepts() {
|
|
86
|
+
return !!this.t;
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Follow an existing transition from the given input to the next state.
|
|
90
|
+
* Does not mutate.
|
|
91
|
+
* @param {string} input character or token type to transition on
|
|
92
|
+
* @returns {?State<T>} the next state, if any
|
|
93
|
+
*/
|
|
94
|
+
go(input) {
|
|
95
|
+
const state = this;
|
|
96
|
+
const nextState = state.j[input];
|
|
97
|
+
if (nextState) {
|
|
98
|
+
return nextState;
|
|
99
|
+
}
|
|
100
|
+
for (let i = 0; i < state.jr.length; i++) {
|
|
101
|
+
const regex = state.jr[i][0];
|
|
102
|
+
const nextState2 = state.jr[i][1];
|
|
103
|
+
if (nextState2 && regex.test(input)) {
|
|
104
|
+
return nextState2;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return state.jd;
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Whether the state has a transition for the given input. Set the second
|
|
111
|
+
* argument to true to only look for an exact match (and not a default or
|
|
112
|
+
* regular-expression-based transition)
|
|
113
|
+
* @param {string} input
|
|
114
|
+
* @param {boolean} exactOnly
|
|
115
|
+
*/
|
|
116
|
+
has(input, exactOnly = false) {
|
|
117
|
+
return exactOnly ? input in this.j : !!this.go(input);
|
|
118
|
+
},
|
|
119
|
+
/**
|
|
120
|
+
* Short for "transition all"; create a transition from the array of items
|
|
121
|
+
* in the given list to the same final resulting state.
|
|
122
|
+
* @param {string | string[]} inputs Group of inputs to transition on
|
|
123
|
+
* @param {Transition<T> | State<T>} [next] Transition options
|
|
124
|
+
* @param {Flags} [flags] Collections flags to add token to
|
|
125
|
+
* @param {Collections<T>} [groups] Master list of token groups
|
|
126
|
+
*/
|
|
127
|
+
ta(inputs, next, flags, groups) {
|
|
128
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
129
|
+
this.tt(inputs[i], next, flags, groups);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
/**
|
|
133
|
+
* Short for "take regexp transition"; defines a transition for this state
|
|
134
|
+
* when it encounters a token which matches the given regular expression
|
|
135
|
+
* @param {RegExp} regexp Regular expression transition (populate first)
|
|
136
|
+
* @param {T | State<T>} [next] Transition options
|
|
137
|
+
* @param {Flags} [flags] Collections flags to add token to
|
|
138
|
+
* @param {Collections<T>} [groups] Master list of token groups
|
|
139
|
+
* @returns {State<T>} taken after the given input
|
|
140
|
+
*/
|
|
141
|
+
tr(regexp, next, flags, groups) {
|
|
142
|
+
groups = groups || State.groups;
|
|
143
|
+
let nextState;
|
|
144
|
+
if (next && next.j) {
|
|
145
|
+
nextState = next;
|
|
146
|
+
} else {
|
|
147
|
+
nextState = new State(next);
|
|
148
|
+
if (flags && groups) {
|
|
149
|
+
addToGroups(next, flags, groups);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
this.jr.push([regexp, nextState]);
|
|
153
|
+
return nextState;
|
|
154
|
+
},
|
|
155
|
+
/**
|
|
156
|
+
* Short for "take transitions", will take as many sequential transitions as
|
|
157
|
+
* the length of the given input and returns the
|
|
158
|
+
* resulting final state.
|
|
159
|
+
* @param {string | string[]} input
|
|
160
|
+
* @param {T | State<T>} [next] Transition options
|
|
161
|
+
* @param {Flags} [flags] Collections flags to add token to
|
|
162
|
+
* @param {Collections<T>} [groups] Master list of token groups
|
|
163
|
+
* @returns {State<T>} taken after the given input
|
|
164
|
+
*/
|
|
165
|
+
ts(input, next, flags, groups) {
|
|
166
|
+
let state = this;
|
|
167
|
+
const len = input.length;
|
|
168
|
+
if (!len) {
|
|
169
|
+
return state;
|
|
170
|
+
}
|
|
171
|
+
for (let i = 0; i < len - 1; i++) {
|
|
172
|
+
state = state.tt(input[i]);
|
|
173
|
+
}
|
|
174
|
+
return state.tt(input[len - 1], next, flags, groups);
|
|
175
|
+
},
|
|
176
|
+
/**
|
|
177
|
+
* Short for "take transition", this is a method for building/working with
|
|
178
|
+
* state machines.
|
|
179
|
+
*
|
|
180
|
+
* If a state already exists for the given input, returns it.
|
|
181
|
+
*
|
|
182
|
+
* If a token is specified, that state will emit that token when reached by
|
|
183
|
+
* the linkify engine.
|
|
184
|
+
*
|
|
185
|
+
* If no state exists, it will be initialized with some default transitions
|
|
186
|
+
* that resemble existing default transitions.
|
|
187
|
+
*
|
|
188
|
+
* If a state is given for the second argument, that state will be
|
|
189
|
+
* transitioned to on the given input regardless of what that input
|
|
190
|
+
* previously did.
|
|
191
|
+
*
|
|
192
|
+
* Specify a token group flags to define groups that this token belongs to.
|
|
193
|
+
* The token will be added to corresponding entires in the given groups
|
|
194
|
+
* object.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} input character, token type to transition on
|
|
197
|
+
* @param {T | State<T>} [next] Transition options
|
|
198
|
+
* @param {Flags} [flags] Collections flags to add token to
|
|
199
|
+
* @param {Collections<T>} [groups] Master list of groups
|
|
200
|
+
* @returns {State<T>} taken after the given input
|
|
201
|
+
*/
|
|
202
|
+
tt(input, next, flags, groups) {
|
|
203
|
+
groups = groups || State.groups;
|
|
204
|
+
const state = this;
|
|
205
|
+
if (next && next.j) {
|
|
206
|
+
state.j[input] = next;
|
|
207
|
+
return next;
|
|
208
|
+
}
|
|
209
|
+
const t = next;
|
|
210
|
+
let nextState, templateState = state.go(input);
|
|
211
|
+
if (templateState) {
|
|
212
|
+
nextState = new State();
|
|
213
|
+
assign(nextState.j, templateState.j);
|
|
214
|
+
nextState.jr.push.apply(nextState.jr, templateState.jr);
|
|
215
|
+
nextState.jd = templateState.jd;
|
|
216
|
+
nextState.t = templateState.t;
|
|
217
|
+
} else {
|
|
218
|
+
nextState = new State();
|
|
219
|
+
}
|
|
220
|
+
if (t) {
|
|
221
|
+
if (groups) {
|
|
222
|
+
if (nextState.t && typeof nextState.t === "string") {
|
|
223
|
+
const allFlags = assign(flagsForToken(nextState.t, groups), flags);
|
|
224
|
+
addToGroups(t, allFlags, groups);
|
|
225
|
+
} else if (flags) {
|
|
226
|
+
addToGroups(t, flags, groups);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
nextState.t = t;
|
|
230
|
+
}
|
|
231
|
+
state.j[input] = nextState;
|
|
232
|
+
return nextState;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
const ta = (state, input, next, flags, groups) => state.ta(input, next, flags, groups);
|
|
236
|
+
const tr = (state, regexp, next, flags, groups) => state.tr(regexp, next, flags, groups);
|
|
237
|
+
const ts = (state, input, next, flags, groups) => state.ts(input, next, flags, groups);
|
|
238
|
+
const tt = (state, input, next, flags, groups) => state.tt(input, next, flags, groups);
|
|
239
|
+
const WORD = "WORD";
|
|
240
|
+
const UWORD = "UWORD";
|
|
241
|
+
const ASCIINUMERICAL = "ASCIINUMERICAL";
|
|
242
|
+
const ALPHANUMERICAL = "ALPHANUMERICAL";
|
|
243
|
+
const LOCALHOST = "LOCALHOST";
|
|
244
|
+
const TLD = "TLD";
|
|
245
|
+
const UTLD = "UTLD";
|
|
246
|
+
const SCHEME = "SCHEME";
|
|
247
|
+
const SLASH_SCHEME = "SLASH_SCHEME";
|
|
248
|
+
const NUM = "NUM";
|
|
249
|
+
const WS = "WS";
|
|
250
|
+
const NL = "NL";
|
|
251
|
+
const OPENBRACE = "OPENBRACE";
|
|
252
|
+
const CLOSEBRACE = "CLOSEBRACE";
|
|
253
|
+
const OPENBRACKET = "OPENBRACKET";
|
|
254
|
+
const CLOSEBRACKET = "CLOSEBRACKET";
|
|
255
|
+
const OPENPAREN = "OPENPAREN";
|
|
256
|
+
const CLOSEPAREN = "CLOSEPAREN";
|
|
257
|
+
const OPENANGLEBRACKET = "OPENANGLEBRACKET";
|
|
258
|
+
const CLOSEANGLEBRACKET = "CLOSEANGLEBRACKET";
|
|
259
|
+
const FULLWIDTHLEFTPAREN = "FULLWIDTHLEFTPAREN";
|
|
260
|
+
const FULLWIDTHRIGHTPAREN = "FULLWIDTHRIGHTPAREN";
|
|
261
|
+
const LEFTCORNERBRACKET = "LEFTCORNERBRACKET";
|
|
262
|
+
const RIGHTCORNERBRACKET = "RIGHTCORNERBRACKET";
|
|
263
|
+
const LEFTWHITECORNERBRACKET = "LEFTWHITECORNERBRACKET";
|
|
264
|
+
const RIGHTWHITECORNERBRACKET = "RIGHTWHITECORNERBRACKET";
|
|
265
|
+
const FULLWIDTHLESSTHAN = "FULLWIDTHLESSTHAN";
|
|
266
|
+
const FULLWIDTHGREATERTHAN = "FULLWIDTHGREATERTHAN";
|
|
267
|
+
const AMPERSAND = "AMPERSAND";
|
|
268
|
+
const APOSTROPHE = "APOSTROPHE";
|
|
269
|
+
const ASTERISK = "ASTERISK";
|
|
270
|
+
const AT = "AT";
|
|
271
|
+
const BACKSLASH = "BACKSLASH";
|
|
272
|
+
const BACKTICK = "BACKTICK";
|
|
273
|
+
const CARET = "CARET";
|
|
274
|
+
const COLON = "COLON";
|
|
275
|
+
const COMMA = "COMMA";
|
|
276
|
+
const DOLLAR = "DOLLAR";
|
|
277
|
+
const DOT = "DOT";
|
|
278
|
+
const EQUALS = "EQUALS";
|
|
279
|
+
const EXCLAMATION = "EXCLAMATION";
|
|
280
|
+
const HYPHEN = "HYPHEN";
|
|
281
|
+
const PERCENT = "PERCENT";
|
|
282
|
+
const PIPE = "PIPE";
|
|
283
|
+
const PLUS = "PLUS";
|
|
284
|
+
const POUND = "POUND";
|
|
285
|
+
const QUERY = "QUERY";
|
|
286
|
+
const QUOTE = "QUOTE";
|
|
287
|
+
const FULLWIDTHMIDDLEDOT = "FULLWIDTHMIDDLEDOT";
|
|
288
|
+
const SEMI = "SEMI";
|
|
289
|
+
const SLASH = "SLASH";
|
|
290
|
+
const TILDE = "TILDE";
|
|
291
|
+
const UNDERSCORE = "UNDERSCORE";
|
|
292
|
+
const EMOJI$1 = "EMOJI";
|
|
293
|
+
const SYM = "SYM";
|
|
294
|
+
var tk = /* @__PURE__ */ Object.freeze({
|
|
295
|
+
__proto__: null,
|
|
296
|
+
ALPHANUMERICAL,
|
|
297
|
+
AMPERSAND,
|
|
298
|
+
APOSTROPHE,
|
|
299
|
+
ASCIINUMERICAL,
|
|
300
|
+
ASTERISK,
|
|
301
|
+
AT,
|
|
302
|
+
BACKSLASH,
|
|
303
|
+
BACKTICK,
|
|
304
|
+
CARET,
|
|
305
|
+
CLOSEANGLEBRACKET,
|
|
306
|
+
CLOSEBRACE,
|
|
307
|
+
CLOSEBRACKET,
|
|
308
|
+
CLOSEPAREN,
|
|
309
|
+
COLON,
|
|
310
|
+
COMMA,
|
|
311
|
+
DOLLAR,
|
|
312
|
+
DOT,
|
|
313
|
+
EMOJI: EMOJI$1,
|
|
314
|
+
EQUALS,
|
|
315
|
+
EXCLAMATION,
|
|
316
|
+
FULLWIDTHGREATERTHAN,
|
|
317
|
+
FULLWIDTHLEFTPAREN,
|
|
318
|
+
FULLWIDTHLESSTHAN,
|
|
319
|
+
FULLWIDTHMIDDLEDOT,
|
|
320
|
+
FULLWIDTHRIGHTPAREN,
|
|
321
|
+
HYPHEN,
|
|
322
|
+
LEFTCORNERBRACKET,
|
|
323
|
+
LEFTWHITECORNERBRACKET,
|
|
324
|
+
LOCALHOST,
|
|
325
|
+
NL,
|
|
326
|
+
NUM,
|
|
327
|
+
OPENANGLEBRACKET,
|
|
328
|
+
OPENBRACE,
|
|
329
|
+
OPENBRACKET,
|
|
330
|
+
OPENPAREN,
|
|
331
|
+
PERCENT,
|
|
332
|
+
PIPE,
|
|
333
|
+
PLUS,
|
|
334
|
+
POUND,
|
|
335
|
+
QUERY,
|
|
336
|
+
QUOTE,
|
|
337
|
+
RIGHTCORNERBRACKET,
|
|
338
|
+
RIGHTWHITECORNERBRACKET,
|
|
339
|
+
SCHEME,
|
|
340
|
+
SEMI,
|
|
341
|
+
SLASH,
|
|
342
|
+
SLASH_SCHEME,
|
|
343
|
+
SYM,
|
|
344
|
+
TILDE,
|
|
345
|
+
TLD,
|
|
346
|
+
UNDERSCORE,
|
|
347
|
+
UTLD,
|
|
348
|
+
UWORD,
|
|
349
|
+
WORD,
|
|
350
|
+
WS
|
|
351
|
+
});
|
|
352
|
+
const ASCII_LETTER = /[a-z]/;
|
|
353
|
+
const LETTER = new RegExp("\\p{L}", "u");
|
|
354
|
+
const EMOJI = new RegExp("\\p{Emoji}", "u");
|
|
355
|
+
const DIGIT = /\d/;
|
|
356
|
+
const SPACE = /\s/;
|
|
357
|
+
const CR = "\r";
|
|
358
|
+
const LF = "\n";
|
|
359
|
+
const EMOJI_VARIATION = "️";
|
|
360
|
+
const EMOJI_JOINER = "";
|
|
361
|
+
const OBJECT_REPLACEMENT = "";
|
|
362
|
+
let tlds = null, utlds = null;
|
|
363
|
+
function init$2(customSchemes = []) {
|
|
364
|
+
const groups = {};
|
|
365
|
+
State.groups = groups;
|
|
366
|
+
const Start = new State();
|
|
367
|
+
if (tlds == null) {
|
|
368
|
+
tlds = decodeTlds(encodedTlds);
|
|
369
|
+
}
|
|
370
|
+
if (utlds == null) {
|
|
371
|
+
utlds = decodeTlds(encodedUtlds);
|
|
372
|
+
}
|
|
373
|
+
tt(Start, "'", APOSTROPHE);
|
|
374
|
+
tt(Start, "{", OPENBRACE);
|
|
375
|
+
tt(Start, "}", CLOSEBRACE);
|
|
376
|
+
tt(Start, "[", OPENBRACKET);
|
|
377
|
+
tt(Start, "]", CLOSEBRACKET);
|
|
378
|
+
tt(Start, "(", OPENPAREN);
|
|
379
|
+
tt(Start, ")", CLOSEPAREN);
|
|
380
|
+
tt(Start, "<", OPENANGLEBRACKET);
|
|
381
|
+
tt(Start, ">", CLOSEANGLEBRACKET);
|
|
382
|
+
tt(Start, "(", FULLWIDTHLEFTPAREN);
|
|
383
|
+
tt(Start, ")", FULLWIDTHRIGHTPAREN);
|
|
384
|
+
tt(Start, "「", LEFTCORNERBRACKET);
|
|
385
|
+
tt(Start, "」", RIGHTCORNERBRACKET);
|
|
386
|
+
tt(Start, "『", LEFTWHITECORNERBRACKET);
|
|
387
|
+
tt(Start, "』", RIGHTWHITECORNERBRACKET);
|
|
388
|
+
tt(Start, "<", FULLWIDTHLESSTHAN);
|
|
389
|
+
tt(Start, ">", FULLWIDTHGREATERTHAN);
|
|
390
|
+
tt(Start, "&", AMPERSAND);
|
|
391
|
+
tt(Start, "*", ASTERISK);
|
|
392
|
+
tt(Start, "@", AT);
|
|
393
|
+
tt(Start, "`", BACKTICK);
|
|
394
|
+
tt(Start, "^", CARET);
|
|
395
|
+
tt(Start, ":", COLON);
|
|
396
|
+
tt(Start, ",", COMMA);
|
|
397
|
+
tt(Start, "$", DOLLAR);
|
|
398
|
+
tt(Start, ".", DOT);
|
|
399
|
+
tt(Start, "=", EQUALS);
|
|
400
|
+
tt(Start, "!", EXCLAMATION);
|
|
401
|
+
tt(Start, "-", HYPHEN);
|
|
402
|
+
tt(Start, "%", PERCENT);
|
|
403
|
+
tt(Start, "|", PIPE);
|
|
404
|
+
tt(Start, "+", PLUS);
|
|
405
|
+
tt(Start, "#", POUND);
|
|
406
|
+
tt(Start, "?", QUERY);
|
|
407
|
+
tt(Start, '"', QUOTE);
|
|
408
|
+
tt(Start, "/", SLASH);
|
|
409
|
+
tt(Start, ";", SEMI);
|
|
410
|
+
tt(Start, "~", TILDE);
|
|
411
|
+
tt(Start, "_", UNDERSCORE);
|
|
412
|
+
tt(Start, "\\", BACKSLASH);
|
|
413
|
+
tt(Start, "・", FULLWIDTHMIDDLEDOT);
|
|
414
|
+
const Num = tr(Start, DIGIT, NUM, {
|
|
415
|
+
[numeric]: true
|
|
416
|
+
});
|
|
417
|
+
tr(Num, DIGIT, Num);
|
|
418
|
+
const Asciinumeric = tr(Num, ASCII_LETTER, ASCIINUMERICAL, {
|
|
419
|
+
[asciinumeric]: true
|
|
420
|
+
});
|
|
421
|
+
const Alphanumeric = tr(Num, LETTER, ALPHANUMERICAL, {
|
|
422
|
+
[alphanumeric]: true
|
|
423
|
+
});
|
|
424
|
+
const Word = tr(Start, ASCII_LETTER, WORD, {
|
|
425
|
+
[ascii]: true
|
|
426
|
+
});
|
|
427
|
+
tr(Word, DIGIT, Asciinumeric);
|
|
428
|
+
tr(Word, ASCII_LETTER, Word);
|
|
429
|
+
tr(Asciinumeric, DIGIT, Asciinumeric);
|
|
430
|
+
tr(Asciinumeric, ASCII_LETTER, Asciinumeric);
|
|
431
|
+
const UWord = tr(Start, LETTER, UWORD, {
|
|
432
|
+
[alpha]: true
|
|
433
|
+
});
|
|
434
|
+
tr(UWord, ASCII_LETTER);
|
|
435
|
+
tr(UWord, DIGIT, Alphanumeric);
|
|
436
|
+
tr(UWord, LETTER, UWord);
|
|
437
|
+
tr(Alphanumeric, DIGIT, Alphanumeric);
|
|
438
|
+
tr(Alphanumeric, ASCII_LETTER);
|
|
439
|
+
tr(Alphanumeric, LETTER, Alphanumeric);
|
|
440
|
+
const Nl2 = tt(Start, LF, NL, {
|
|
441
|
+
[whitespace]: true
|
|
442
|
+
});
|
|
443
|
+
const Cr = tt(Start, CR, WS, {
|
|
444
|
+
[whitespace]: true
|
|
445
|
+
});
|
|
446
|
+
const Ws = tr(Start, SPACE, WS, {
|
|
447
|
+
[whitespace]: true
|
|
448
|
+
});
|
|
449
|
+
tt(Start, OBJECT_REPLACEMENT, Ws);
|
|
450
|
+
tt(Cr, LF, Nl2);
|
|
451
|
+
tt(Cr, OBJECT_REPLACEMENT, Ws);
|
|
452
|
+
tr(Cr, SPACE, Ws);
|
|
453
|
+
tt(Ws, CR);
|
|
454
|
+
tt(Ws, LF);
|
|
455
|
+
tr(Ws, SPACE, Ws);
|
|
456
|
+
tt(Ws, OBJECT_REPLACEMENT, Ws);
|
|
457
|
+
const Emoji = tr(Start, EMOJI, EMOJI$1, {
|
|
458
|
+
[emoji]: true
|
|
459
|
+
});
|
|
460
|
+
tt(Emoji, "#");
|
|
461
|
+
tr(Emoji, EMOJI, Emoji);
|
|
462
|
+
tt(Emoji, EMOJI_VARIATION, Emoji);
|
|
463
|
+
const EmojiJoiner = tt(Emoji, EMOJI_JOINER);
|
|
464
|
+
tt(EmojiJoiner, "#");
|
|
465
|
+
tr(EmojiJoiner, EMOJI, Emoji);
|
|
466
|
+
const wordjr = [[ASCII_LETTER, Word], [DIGIT, Asciinumeric]];
|
|
467
|
+
const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord], [DIGIT, Alphanumeric]];
|
|
468
|
+
for (let i = 0; i < tlds.length; i++) {
|
|
469
|
+
fastts(Start, tlds[i], TLD, WORD, wordjr);
|
|
470
|
+
}
|
|
471
|
+
for (let i = 0; i < utlds.length; i++) {
|
|
472
|
+
fastts(Start, utlds[i], UTLD, UWORD, uwordjr);
|
|
473
|
+
}
|
|
474
|
+
addToGroups(TLD, {
|
|
475
|
+
tld: true,
|
|
476
|
+
ascii: true
|
|
477
|
+
}, groups);
|
|
478
|
+
addToGroups(UTLD, {
|
|
479
|
+
utld: true,
|
|
480
|
+
alpha: true
|
|
481
|
+
}, groups);
|
|
482
|
+
fastts(Start, "file", SCHEME, WORD, wordjr);
|
|
483
|
+
fastts(Start, "mailto", SCHEME, WORD, wordjr);
|
|
484
|
+
fastts(Start, "http", SLASH_SCHEME, WORD, wordjr);
|
|
485
|
+
fastts(Start, "https", SLASH_SCHEME, WORD, wordjr);
|
|
486
|
+
fastts(Start, "ftp", SLASH_SCHEME, WORD, wordjr);
|
|
487
|
+
fastts(Start, "ftps", SLASH_SCHEME, WORD, wordjr);
|
|
488
|
+
addToGroups(SCHEME, {
|
|
489
|
+
scheme: true,
|
|
490
|
+
ascii: true
|
|
491
|
+
}, groups);
|
|
492
|
+
addToGroups(SLASH_SCHEME, {
|
|
493
|
+
slashscheme: true,
|
|
494
|
+
ascii: true
|
|
495
|
+
}, groups);
|
|
496
|
+
customSchemes = customSchemes.sort((a, b) => a[0] > b[0] ? 1 : -1);
|
|
497
|
+
for (let i = 0; i < customSchemes.length; i++) {
|
|
498
|
+
const sch = customSchemes[i][0];
|
|
499
|
+
const optionalSlashSlash = customSchemes[i][1];
|
|
500
|
+
const flags = optionalSlashSlash ? {
|
|
501
|
+
[scheme]: true
|
|
502
|
+
} : {
|
|
503
|
+
[slashscheme]: true
|
|
504
|
+
};
|
|
505
|
+
if (sch.indexOf("-") >= 0) {
|
|
506
|
+
flags[domain] = true;
|
|
507
|
+
} else if (!ASCII_LETTER.test(sch)) {
|
|
508
|
+
flags[numeric] = true;
|
|
509
|
+
} else if (DIGIT.test(sch)) {
|
|
510
|
+
flags[asciinumeric] = true;
|
|
511
|
+
} else {
|
|
512
|
+
flags[ascii] = true;
|
|
513
|
+
}
|
|
514
|
+
ts(Start, sch, sch, flags);
|
|
515
|
+
}
|
|
516
|
+
ts(Start, "localhost", LOCALHOST, {
|
|
517
|
+
ascii: true
|
|
518
|
+
});
|
|
519
|
+
Start.jd = new State(SYM);
|
|
520
|
+
return {
|
|
521
|
+
start: Start,
|
|
522
|
+
tokens: assign({
|
|
523
|
+
groups
|
|
524
|
+
}, tk)
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function run$1(start, str) {
|
|
528
|
+
const iterable = stringToArray(str.replace(/[A-Z]/g, (c) => c.toLowerCase()));
|
|
529
|
+
const charCount = iterable.length;
|
|
530
|
+
const tokens = [];
|
|
531
|
+
let cursor = 0;
|
|
532
|
+
let charCursor = 0;
|
|
533
|
+
while (charCursor < charCount) {
|
|
534
|
+
let state = start;
|
|
535
|
+
let nextState = null;
|
|
536
|
+
let tokenLength = 0;
|
|
537
|
+
let latestAccepting = null;
|
|
538
|
+
let sinceAccepts = -1;
|
|
539
|
+
let charsSinceAccepts = -1;
|
|
540
|
+
while (charCursor < charCount && (nextState = state.go(iterable[charCursor]))) {
|
|
541
|
+
state = nextState;
|
|
542
|
+
if (state.accepts()) {
|
|
543
|
+
sinceAccepts = 0;
|
|
544
|
+
charsSinceAccepts = 0;
|
|
545
|
+
latestAccepting = state;
|
|
546
|
+
} else if (sinceAccepts >= 0) {
|
|
547
|
+
sinceAccepts += iterable[charCursor].length;
|
|
548
|
+
charsSinceAccepts++;
|
|
549
|
+
}
|
|
550
|
+
tokenLength += iterable[charCursor].length;
|
|
551
|
+
cursor += iterable[charCursor].length;
|
|
552
|
+
charCursor++;
|
|
553
|
+
}
|
|
554
|
+
cursor -= sinceAccepts;
|
|
555
|
+
charCursor -= charsSinceAccepts;
|
|
556
|
+
tokenLength -= sinceAccepts;
|
|
557
|
+
tokens.push({
|
|
558
|
+
t: latestAccepting.t,
|
|
559
|
+
// token type/name
|
|
560
|
+
v: str.slice(cursor - tokenLength, cursor),
|
|
561
|
+
// string value
|
|
562
|
+
s: cursor - tokenLength,
|
|
563
|
+
// start index
|
|
564
|
+
e: cursor
|
|
565
|
+
// end index (excluding)
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
return tokens;
|
|
569
|
+
}
|
|
570
|
+
function stringToArray(str) {
|
|
571
|
+
const result = [];
|
|
572
|
+
const len = str.length;
|
|
573
|
+
let index2 = 0;
|
|
574
|
+
while (index2 < len) {
|
|
575
|
+
let first = str.charCodeAt(index2);
|
|
576
|
+
let second;
|
|
577
|
+
let char = first < 55296 || first > 56319 || index2 + 1 === len || (second = str.charCodeAt(index2 + 1)) < 56320 || second > 57343 ? str[index2] : str.slice(index2, index2 + 2);
|
|
578
|
+
result.push(char);
|
|
579
|
+
index2 += char.length;
|
|
580
|
+
}
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
function fastts(state, input, t, defaultt, jr) {
|
|
584
|
+
let next;
|
|
585
|
+
const len = input.length;
|
|
586
|
+
for (let i = 0; i < len - 1; i++) {
|
|
587
|
+
const char = input[i];
|
|
588
|
+
if (state.j[char]) {
|
|
589
|
+
next = state.j[char];
|
|
590
|
+
} else {
|
|
591
|
+
next = new State(defaultt);
|
|
592
|
+
next.jr = jr.slice();
|
|
593
|
+
state.j[char] = next;
|
|
594
|
+
}
|
|
595
|
+
state = next;
|
|
596
|
+
}
|
|
597
|
+
next = new State(t);
|
|
598
|
+
next.jr = jr.slice();
|
|
599
|
+
state.j[input[len - 1]] = next;
|
|
600
|
+
return next;
|
|
601
|
+
}
|
|
602
|
+
function decodeTlds(encoded) {
|
|
603
|
+
const words = [];
|
|
604
|
+
const stack = [];
|
|
605
|
+
let i = 0;
|
|
606
|
+
let digits = "0123456789";
|
|
607
|
+
while (i < encoded.length) {
|
|
608
|
+
let popDigitCount = 0;
|
|
609
|
+
while (digits.indexOf(encoded[i + popDigitCount]) >= 0) {
|
|
610
|
+
popDigitCount++;
|
|
611
|
+
}
|
|
612
|
+
if (popDigitCount > 0) {
|
|
613
|
+
words.push(stack.join(""));
|
|
614
|
+
for (let popCount = parseInt(encoded.substring(i, i + popDigitCount), 10); popCount > 0; popCount--) {
|
|
615
|
+
stack.pop();
|
|
616
|
+
}
|
|
617
|
+
i += popDigitCount;
|
|
618
|
+
} else {
|
|
619
|
+
stack.push(encoded[i]);
|
|
620
|
+
i++;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return words;
|
|
624
|
+
}
|
|
625
|
+
const defaults = {
|
|
626
|
+
defaultProtocol: "http",
|
|
627
|
+
events: null,
|
|
628
|
+
format: noop,
|
|
629
|
+
formatHref: noop,
|
|
630
|
+
nl2br: false,
|
|
631
|
+
tagName: "a",
|
|
632
|
+
target: null,
|
|
633
|
+
rel: null,
|
|
634
|
+
validate: true,
|
|
635
|
+
truncate: Infinity,
|
|
636
|
+
className: null,
|
|
637
|
+
attributes: null,
|
|
638
|
+
ignoreTags: [],
|
|
639
|
+
render: null
|
|
640
|
+
};
|
|
641
|
+
function Options(opts, defaultRender = null) {
|
|
642
|
+
let o = assign({}, defaults);
|
|
643
|
+
if (opts) {
|
|
644
|
+
o = assign(o, opts instanceof Options ? opts.o : opts);
|
|
645
|
+
}
|
|
646
|
+
const ignoredTags = o.ignoreTags;
|
|
647
|
+
const uppercaseIgnoredTags = [];
|
|
648
|
+
for (let i = 0; i < ignoredTags.length; i++) {
|
|
649
|
+
uppercaseIgnoredTags.push(ignoredTags[i].toUpperCase());
|
|
650
|
+
}
|
|
651
|
+
this.o = o;
|
|
652
|
+
if (defaultRender) {
|
|
653
|
+
this.defaultRender = defaultRender;
|
|
654
|
+
}
|
|
655
|
+
this.ignoreTags = uppercaseIgnoredTags;
|
|
656
|
+
}
|
|
657
|
+
Options.prototype = {
|
|
658
|
+
o: defaults,
|
|
659
|
+
/**
|
|
660
|
+
* @type string[]
|
|
661
|
+
*/
|
|
662
|
+
ignoreTags: [],
|
|
663
|
+
/**
|
|
664
|
+
* @param {IntermediateRepresentation} ir
|
|
665
|
+
* @returns {any}
|
|
666
|
+
*/
|
|
667
|
+
defaultRender(ir) {
|
|
668
|
+
return ir;
|
|
669
|
+
},
|
|
670
|
+
/**
|
|
671
|
+
* Returns true or false based on whether a token should be displayed as a
|
|
672
|
+
* link based on the user options.
|
|
673
|
+
* @param {MultiToken} token
|
|
674
|
+
* @returns {boolean}
|
|
675
|
+
*/
|
|
676
|
+
check(token) {
|
|
677
|
+
return this.get("validate", token.toString(), token);
|
|
678
|
+
},
|
|
679
|
+
// Private methods
|
|
680
|
+
/**
|
|
681
|
+
* Resolve an option's value based on the value of the option and the given
|
|
682
|
+
* params. If operator and token are specified and the target option is
|
|
683
|
+
* callable, automatically calls the function with the given argument.
|
|
684
|
+
* @template {keyof Opts} K
|
|
685
|
+
* @param {K} key Name of option to use
|
|
686
|
+
* @param {string} [operator] will be passed to the target option if it's a
|
|
687
|
+
* function. If not specified, RAW function value gets returned
|
|
688
|
+
* @param {MultiToken} [token] The token from linkify.tokenize
|
|
689
|
+
* @returns {Opts[K] | any}
|
|
690
|
+
*/
|
|
691
|
+
get(key, operator, token) {
|
|
692
|
+
const isCallable = operator != null;
|
|
693
|
+
let option = this.o[key];
|
|
694
|
+
if (!option) {
|
|
695
|
+
return option;
|
|
696
|
+
}
|
|
697
|
+
if (typeof option === "object") {
|
|
698
|
+
option = token.t in option ? option[token.t] : defaults[key];
|
|
699
|
+
if (typeof option === "function" && isCallable) {
|
|
700
|
+
option = option(operator, token);
|
|
701
|
+
}
|
|
702
|
+
} else if (typeof option === "function" && isCallable) {
|
|
703
|
+
option = option(operator, token.t, token);
|
|
704
|
+
}
|
|
705
|
+
return option;
|
|
706
|
+
},
|
|
707
|
+
/**
|
|
708
|
+
* @template {keyof Opts} L
|
|
709
|
+
* @param {L} key Name of options object to use
|
|
710
|
+
* @param {string} [operator]
|
|
711
|
+
* @param {MultiToken} [token]
|
|
712
|
+
* @returns {Opts[L] | any}
|
|
713
|
+
*/
|
|
714
|
+
getObj(key, operator, token) {
|
|
715
|
+
let obj = this.o[key];
|
|
716
|
+
if (typeof obj === "function" && operator != null) {
|
|
717
|
+
obj = obj(operator, token.t, token);
|
|
718
|
+
}
|
|
719
|
+
return obj;
|
|
720
|
+
},
|
|
721
|
+
/**
|
|
722
|
+
* Convert the given token to a rendered element that may be added to the
|
|
723
|
+
* calling-interface's DOM
|
|
724
|
+
* @param {MultiToken} token Token to render to an HTML element
|
|
725
|
+
* @returns {any} Render result; e.g., HTML string, DOM element, React
|
|
726
|
+
* Component, etc.
|
|
727
|
+
*/
|
|
728
|
+
render(token) {
|
|
729
|
+
const ir = token.render(this);
|
|
730
|
+
const renderFn = this.get("render", null, token) || this.defaultRender;
|
|
731
|
+
return renderFn(ir, token.t, token);
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
function noop(val) {
|
|
735
|
+
return val;
|
|
736
|
+
}
|
|
737
|
+
function MultiToken(value, tokens) {
|
|
738
|
+
this.t = "token";
|
|
739
|
+
this.v = value;
|
|
740
|
+
this.tk = tokens;
|
|
741
|
+
}
|
|
742
|
+
MultiToken.prototype = {
|
|
743
|
+
isLink: false,
|
|
744
|
+
/**
|
|
745
|
+
* Return the string this token represents.
|
|
746
|
+
* @return {string}
|
|
747
|
+
*/
|
|
748
|
+
toString() {
|
|
749
|
+
return this.v;
|
|
750
|
+
},
|
|
751
|
+
/**
|
|
752
|
+
* What should the value for this token be in the `href` HTML attribute?
|
|
753
|
+
* Returns the `.toString` value by default.
|
|
754
|
+
* @param {string} [scheme]
|
|
755
|
+
* @return {string}
|
|
756
|
+
*/
|
|
757
|
+
toHref(scheme2) {
|
|
758
|
+
return this.toString();
|
|
759
|
+
},
|
|
760
|
+
/**
|
|
761
|
+
* @param {Options} options Formatting options
|
|
762
|
+
* @returns {string}
|
|
763
|
+
*/
|
|
764
|
+
toFormattedString(options) {
|
|
765
|
+
const val = this.toString();
|
|
766
|
+
const truncate = options.get("truncate", val, this);
|
|
767
|
+
const formatted = options.get("format", val, this);
|
|
768
|
+
return truncate && formatted.length > truncate ? formatted.substring(0, truncate) + "…" : formatted;
|
|
769
|
+
},
|
|
770
|
+
/**
|
|
771
|
+
*
|
|
772
|
+
* @param {Options} options
|
|
773
|
+
* @returns {string}
|
|
774
|
+
*/
|
|
775
|
+
toFormattedHref(options) {
|
|
776
|
+
return options.get("formatHref", this.toHref(options.get("defaultProtocol")), this);
|
|
777
|
+
},
|
|
778
|
+
/**
|
|
779
|
+
* The start index of this token in the original input string
|
|
780
|
+
* @returns {number}
|
|
781
|
+
*/
|
|
782
|
+
startIndex() {
|
|
783
|
+
return this.tk[0].s;
|
|
784
|
+
},
|
|
785
|
+
/**
|
|
786
|
+
* The end index of this token in the original input string (up to this
|
|
787
|
+
* index but not including it)
|
|
788
|
+
* @returns {number}
|
|
789
|
+
*/
|
|
790
|
+
endIndex() {
|
|
791
|
+
return this.tk[this.tk.length - 1].e;
|
|
792
|
+
},
|
|
793
|
+
/**
|
|
794
|
+
Returns an object of relevant values for this token, which includes keys
|
|
795
|
+
* type - Kind of token ('url', 'email', etc.)
|
|
796
|
+
* value - Original text
|
|
797
|
+
* href - The value that should be added to the anchor tag's href
|
|
798
|
+
attribute
|
|
799
|
+
@method toObject
|
|
800
|
+
@param {string} [protocol] `'http'` by default
|
|
801
|
+
*/
|
|
802
|
+
toObject(protocol = defaults.defaultProtocol) {
|
|
803
|
+
return {
|
|
804
|
+
type: this.t,
|
|
805
|
+
value: this.toString(),
|
|
806
|
+
isLink: this.isLink,
|
|
807
|
+
href: this.toHref(protocol),
|
|
808
|
+
start: this.startIndex(),
|
|
809
|
+
end: this.endIndex()
|
|
810
|
+
};
|
|
811
|
+
},
|
|
812
|
+
/**
|
|
813
|
+
*
|
|
814
|
+
* @param {Options} options Formatting option
|
|
815
|
+
*/
|
|
816
|
+
toFormattedObject(options) {
|
|
817
|
+
return {
|
|
818
|
+
type: this.t,
|
|
819
|
+
value: this.toFormattedString(options),
|
|
820
|
+
isLink: this.isLink,
|
|
821
|
+
href: this.toFormattedHref(options),
|
|
822
|
+
start: this.startIndex(),
|
|
823
|
+
end: this.endIndex()
|
|
824
|
+
};
|
|
825
|
+
},
|
|
826
|
+
/**
|
|
827
|
+
* Whether this token should be rendered as a link according to the given options
|
|
828
|
+
* @param {Options} options
|
|
829
|
+
* @returns {boolean}
|
|
830
|
+
*/
|
|
831
|
+
validate(options) {
|
|
832
|
+
return options.get("validate", this.toString(), this);
|
|
833
|
+
},
|
|
834
|
+
/**
|
|
835
|
+
* Return an object that represents how this link should be rendered.
|
|
836
|
+
* @param {Options} options Formattinng options
|
|
837
|
+
*/
|
|
838
|
+
render(options) {
|
|
839
|
+
const token = this;
|
|
840
|
+
const href = this.toHref(options.get("defaultProtocol"));
|
|
841
|
+
const formattedHref = options.get("formatHref", href, this);
|
|
842
|
+
const tagName = options.get("tagName", href, token);
|
|
843
|
+
const content = this.toFormattedString(options);
|
|
844
|
+
const attributes = {};
|
|
845
|
+
const className = options.get("className", href, token);
|
|
846
|
+
const target = options.get("target", href, token);
|
|
847
|
+
const rel = options.get("rel", href, token);
|
|
848
|
+
const attrs = options.getObj("attributes", href, token);
|
|
849
|
+
const eventListeners = options.getObj("events", href, token);
|
|
850
|
+
attributes.href = formattedHref;
|
|
851
|
+
if (className) {
|
|
852
|
+
attributes.class = className;
|
|
853
|
+
}
|
|
854
|
+
if (target) {
|
|
855
|
+
attributes.target = target;
|
|
856
|
+
}
|
|
857
|
+
if (rel) {
|
|
858
|
+
attributes.rel = rel;
|
|
859
|
+
}
|
|
860
|
+
if (attrs) {
|
|
861
|
+
assign(attributes, attrs);
|
|
862
|
+
}
|
|
863
|
+
return {
|
|
864
|
+
tagName,
|
|
865
|
+
attributes,
|
|
866
|
+
content,
|
|
867
|
+
eventListeners
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
function createTokenClass(type, props) {
|
|
872
|
+
class Token extends MultiToken {
|
|
873
|
+
constructor(value, tokens) {
|
|
874
|
+
super(value, tokens);
|
|
875
|
+
this.t = type;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
for (const p in props) {
|
|
879
|
+
Token.prototype[p] = props[p];
|
|
880
|
+
}
|
|
881
|
+
Token.t = type;
|
|
882
|
+
return Token;
|
|
883
|
+
}
|
|
884
|
+
const Email = createTokenClass("email", {
|
|
885
|
+
isLink: true,
|
|
886
|
+
toHref() {
|
|
887
|
+
return "mailto:" + this.toString();
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
const Text$1 = createTokenClass("text");
|
|
891
|
+
const Nl = createTokenClass("nl");
|
|
892
|
+
const Url = createTokenClass("url", {
|
|
893
|
+
isLink: true,
|
|
894
|
+
/**
|
|
895
|
+
Lowercases relevant parts of the domain and adds the protocol if
|
|
896
|
+
required. Note that this will not escape unsafe HTML characters in the
|
|
897
|
+
URL.
|
|
898
|
+
@param {string} [scheme] default scheme (e.g., 'https')
|
|
899
|
+
@return {string} the full href
|
|
900
|
+
*/
|
|
901
|
+
toHref(scheme2 = defaults.defaultProtocol) {
|
|
902
|
+
return this.hasProtocol() ? this.v : `${scheme2}://${this.v}`;
|
|
903
|
+
},
|
|
904
|
+
/**
|
|
905
|
+
* Check whether this URL token has a protocol
|
|
906
|
+
* @return {boolean}
|
|
907
|
+
*/
|
|
908
|
+
hasProtocol() {
|
|
909
|
+
const tokens = this.tk;
|
|
910
|
+
return tokens.length >= 2 && tokens[0].t !== LOCALHOST && tokens[1].t === COLON;
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
const makeState = (arg) => new State(arg);
|
|
914
|
+
function init$1({
|
|
915
|
+
groups
|
|
916
|
+
}) {
|
|
917
|
+
const qsAccepting = groups.domain.concat([AMPERSAND, ASTERISK, AT, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, NUM, PERCENT, PIPE, PLUS, POUND, SLASH, SYM, TILDE, UNDERSCORE]);
|
|
918
|
+
const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, PERCENT, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN];
|
|
919
|
+
const localpartAccepting = [AMPERSAND, APOSTROPHE, ASTERISK, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, OPENBRACE, CLOSEBRACE, PERCENT, PIPE, PLUS, POUND, QUERY, SLASH, SYM, TILDE, UNDERSCORE];
|
|
920
|
+
const Start = makeState();
|
|
921
|
+
const Localpart = tt(Start, TILDE);
|
|
922
|
+
ta(Localpart, localpartAccepting, Localpart);
|
|
923
|
+
ta(Localpart, groups.domain, Localpart);
|
|
924
|
+
const Domain = makeState(), Scheme = makeState(), SlashScheme = makeState();
|
|
925
|
+
ta(Start, groups.domain, Domain);
|
|
926
|
+
ta(Start, groups.scheme, Scheme);
|
|
927
|
+
ta(Start, groups.slashscheme, SlashScheme);
|
|
928
|
+
ta(Domain, localpartAccepting, Localpart);
|
|
929
|
+
ta(Domain, groups.domain, Domain);
|
|
930
|
+
const LocalpartAt = tt(Domain, AT);
|
|
931
|
+
tt(Localpart, AT, LocalpartAt);
|
|
932
|
+
tt(Scheme, AT, LocalpartAt);
|
|
933
|
+
tt(SlashScheme, AT, LocalpartAt);
|
|
934
|
+
const LocalpartDot = tt(Localpart, DOT);
|
|
935
|
+
ta(LocalpartDot, localpartAccepting, Localpart);
|
|
936
|
+
ta(LocalpartDot, groups.domain, Localpart);
|
|
937
|
+
const EmailDomain = makeState();
|
|
938
|
+
ta(LocalpartAt, groups.domain, EmailDomain);
|
|
939
|
+
ta(EmailDomain, groups.domain, EmailDomain);
|
|
940
|
+
const EmailDomainDot = tt(EmailDomain, DOT);
|
|
941
|
+
ta(EmailDomainDot, groups.domain, EmailDomain);
|
|
942
|
+
const Email$1 = makeState(Email);
|
|
943
|
+
ta(EmailDomainDot, groups.tld, Email$1);
|
|
944
|
+
ta(EmailDomainDot, groups.utld, Email$1);
|
|
945
|
+
tt(LocalpartAt, LOCALHOST, Email$1);
|
|
946
|
+
const EmailDomainHyphen = tt(EmailDomain, HYPHEN);
|
|
947
|
+
tt(EmailDomainHyphen, HYPHEN, EmailDomainHyphen);
|
|
948
|
+
ta(EmailDomainHyphen, groups.domain, EmailDomain);
|
|
949
|
+
ta(Email$1, groups.domain, EmailDomain);
|
|
950
|
+
tt(Email$1, DOT, EmailDomainDot);
|
|
951
|
+
tt(Email$1, HYPHEN, EmailDomainHyphen);
|
|
952
|
+
const EmailColon = tt(Email$1, COLON);
|
|
953
|
+
ta(EmailColon, groups.numeric, Email);
|
|
954
|
+
const DomainHyphen = tt(Domain, HYPHEN);
|
|
955
|
+
const DomainDot = tt(Domain, DOT);
|
|
956
|
+
tt(DomainHyphen, HYPHEN, DomainHyphen);
|
|
957
|
+
ta(DomainHyphen, groups.domain, Domain);
|
|
958
|
+
ta(DomainDot, localpartAccepting, Localpart);
|
|
959
|
+
ta(DomainDot, groups.domain, Domain);
|
|
960
|
+
const DomainDotTld = makeState(Url);
|
|
961
|
+
ta(DomainDot, groups.tld, DomainDotTld);
|
|
962
|
+
ta(DomainDot, groups.utld, DomainDotTld);
|
|
963
|
+
ta(DomainDotTld, groups.domain, Domain);
|
|
964
|
+
ta(DomainDotTld, localpartAccepting, Localpart);
|
|
965
|
+
tt(DomainDotTld, DOT, DomainDot);
|
|
966
|
+
tt(DomainDotTld, HYPHEN, DomainHyphen);
|
|
967
|
+
tt(DomainDotTld, AT, LocalpartAt);
|
|
968
|
+
const DomainDotTldColon = tt(DomainDotTld, COLON);
|
|
969
|
+
const DomainDotTldColonPort = makeState(Url);
|
|
970
|
+
ta(DomainDotTldColon, groups.numeric, DomainDotTldColonPort);
|
|
971
|
+
const Url$1 = makeState(Url);
|
|
972
|
+
const UrlNonaccept = makeState();
|
|
973
|
+
ta(Url$1, qsAccepting, Url$1);
|
|
974
|
+
ta(Url$1, qsNonAccepting, UrlNonaccept);
|
|
975
|
+
ta(UrlNonaccept, qsAccepting, Url$1);
|
|
976
|
+
ta(UrlNonaccept, qsNonAccepting, UrlNonaccept);
|
|
977
|
+
tt(DomainDotTld, SLASH, Url$1);
|
|
978
|
+
tt(DomainDotTldColonPort, SLASH, Url$1);
|
|
979
|
+
const SchemeColon = tt(Scheme, COLON);
|
|
980
|
+
const SlashSchemeColon = tt(SlashScheme, COLON);
|
|
981
|
+
const SlashSchemeColonSlash = tt(SlashSchemeColon, SLASH);
|
|
982
|
+
const UriPrefix = tt(SlashSchemeColonSlash, SLASH);
|
|
983
|
+
ta(Scheme, groups.domain, Domain);
|
|
984
|
+
tt(Scheme, DOT, DomainDot);
|
|
985
|
+
tt(Scheme, HYPHEN, DomainHyphen);
|
|
986
|
+
ta(SlashScheme, groups.domain, Domain);
|
|
987
|
+
tt(SlashScheme, DOT, DomainDot);
|
|
988
|
+
tt(SlashScheme, HYPHEN, DomainHyphen);
|
|
989
|
+
ta(SchemeColon, groups.domain, Url$1);
|
|
990
|
+
tt(SchemeColon, SLASH, Url$1);
|
|
991
|
+
tt(SchemeColon, QUERY, Url$1);
|
|
992
|
+
ta(UriPrefix, groups.domain, Url$1);
|
|
993
|
+
ta(UriPrefix, qsAccepting, Url$1);
|
|
994
|
+
tt(UriPrefix, SLASH, Url$1);
|
|
995
|
+
const bracketPairs = [
|
|
996
|
+
[OPENBRACE, CLOSEBRACE],
|
|
997
|
+
// {}
|
|
998
|
+
[OPENBRACKET, CLOSEBRACKET],
|
|
999
|
+
// []
|
|
1000
|
+
[OPENPAREN, CLOSEPAREN],
|
|
1001
|
+
// ()
|
|
1002
|
+
[OPENANGLEBRACKET, CLOSEANGLEBRACKET],
|
|
1003
|
+
// <>
|
|
1004
|
+
[FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN],
|
|
1005
|
+
// ()
|
|
1006
|
+
[LEFTCORNERBRACKET, RIGHTCORNERBRACKET],
|
|
1007
|
+
// 「」
|
|
1008
|
+
[LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET],
|
|
1009
|
+
// 『』
|
|
1010
|
+
[FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN]
|
|
1011
|
+
// <>
|
|
1012
|
+
];
|
|
1013
|
+
for (let i = 0; i < bracketPairs.length; i++) {
|
|
1014
|
+
const [OPEN, CLOSE] = bracketPairs[i];
|
|
1015
|
+
const UrlOpen = tt(Url$1, OPEN);
|
|
1016
|
+
tt(UrlNonaccept, OPEN, UrlOpen);
|
|
1017
|
+
tt(UrlOpen, CLOSE, Url$1);
|
|
1018
|
+
const UrlOpenQ = makeState(Url);
|
|
1019
|
+
ta(UrlOpen, qsAccepting, UrlOpenQ);
|
|
1020
|
+
const UrlOpenSyms = makeState();
|
|
1021
|
+
ta(UrlOpen, qsNonAccepting);
|
|
1022
|
+
ta(UrlOpenQ, qsAccepting, UrlOpenQ);
|
|
1023
|
+
ta(UrlOpenQ, qsNonAccepting, UrlOpenSyms);
|
|
1024
|
+
ta(UrlOpenSyms, qsAccepting, UrlOpenQ);
|
|
1025
|
+
ta(UrlOpenSyms, qsNonAccepting, UrlOpenSyms);
|
|
1026
|
+
tt(UrlOpenQ, CLOSE, Url$1);
|
|
1027
|
+
tt(UrlOpenSyms, CLOSE, Url$1);
|
|
1028
|
+
}
|
|
1029
|
+
tt(Start, LOCALHOST, DomainDotTld);
|
|
1030
|
+
tt(Start, NL, Nl);
|
|
1031
|
+
return {
|
|
1032
|
+
start: Start,
|
|
1033
|
+
tokens: tk
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
function run(start, input, tokens) {
|
|
1037
|
+
let len = tokens.length;
|
|
1038
|
+
let cursor = 0;
|
|
1039
|
+
let multis = [];
|
|
1040
|
+
let textTokens = [];
|
|
1041
|
+
while (cursor < len) {
|
|
1042
|
+
let state = start;
|
|
1043
|
+
let secondState = null;
|
|
1044
|
+
let nextState = null;
|
|
1045
|
+
let multiLength = 0;
|
|
1046
|
+
let latestAccepting = null;
|
|
1047
|
+
let sinceAccepts = -1;
|
|
1048
|
+
while (cursor < len && !(secondState = state.go(tokens[cursor].t))) {
|
|
1049
|
+
textTokens.push(tokens[cursor++]);
|
|
1050
|
+
}
|
|
1051
|
+
while (cursor < len && (nextState = secondState || state.go(tokens[cursor].t))) {
|
|
1052
|
+
secondState = null;
|
|
1053
|
+
state = nextState;
|
|
1054
|
+
if (state.accepts()) {
|
|
1055
|
+
sinceAccepts = 0;
|
|
1056
|
+
latestAccepting = state;
|
|
1057
|
+
} else if (sinceAccepts >= 0) {
|
|
1058
|
+
sinceAccepts++;
|
|
1059
|
+
}
|
|
1060
|
+
cursor++;
|
|
1061
|
+
multiLength++;
|
|
1062
|
+
}
|
|
1063
|
+
if (sinceAccepts < 0) {
|
|
1064
|
+
cursor -= multiLength;
|
|
1065
|
+
if (cursor < len) {
|
|
1066
|
+
textTokens.push(tokens[cursor]);
|
|
1067
|
+
cursor++;
|
|
1068
|
+
}
|
|
1069
|
+
} else {
|
|
1070
|
+
if (textTokens.length > 0) {
|
|
1071
|
+
multis.push(initMultiToken(Text$1, input, textTokens));
|
|
1072
|
+
textTokens = [];
|
|
1073
|
+
}
|
|
1074
|
+
cursor -= sinceAccepts;
|
|
1075
|
+
multiLength -= sinceAccepts;
|
|
1076
|
+
const Multi = latestAccepting.t;
|
|
1077
|
+
const subtokens = tokens.slice(cursor - multiLength, cursor);
|
|
1078
|
+
multis.push(initMultiToken(Multi, input, subtokens));
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
if (textTokens.length > 0) {
|
|
1082
|
+
multis.push(initMultiToken(Text$1, input, textTokens));
|
|
1083
|
+
}
|
|
1084
|
+
return multis;
|
|
1085
|
+
}
|
|
1086
|
+
function initMultiToken(Multi, input, tokens) {
|
|
1087
|
+
const startIdx = tokens[0].s;
|
|
1088
|
+
const endIdx = tokens[tokens.length - 1].e;
|
|
1089
|
+
const value = input.slice(startIdx, endIdx);
|
|
1090
|
+
return new Multi(value, tokens);
|
|
1091
|
+
}
|
|
1092
|
+
const warn = typeof console !== "undefined" && console && console.warn || (() => {
|
|
1093
|
+
});
|
|
1094
|
+
const warnAdvice = "until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time.";
|
|
1095
|
+
const INIT = {
|
|
1096
|
+
scanner: null,
|
|
1097
|
+
parser: null,
|
|
1098
|
+
tokenQueue: [],
|
|
1099
|
+
pluginQueue: [],
|
|
1100
|
+
customSchemes: [],
|
|
1101
|
+
initialized: false
|
|
1102
|
+
};
|
|
1103
|
+
function reset() {
|
|
1104
|
+
State.groups = {};
|
|
1105
|
+
INIT.scanner = null;
|
|
1106
|
+
INIT.parser = null;
|
|
1107
|
+
INIT.tokenQueue = [];
|
|
1108
|
+
INIT.pluginQueue = [];
|
|
1109
|
+
INIT.customSchemes = [];
|
|
1110
|
+
INIT.initialized = false;
|
|
1111
|
+
return INIT;
|
|
1112
|
+
}
|
|
1113
|
+
function registerCustomProtocol(scheme2, optionalSlashSlash = false) {
|
|
1114
|
+
if (INIT.initialized) {
|
|
1115
|
+
warn(`linkifyjs: already initialized - will not register custom scheme "${scheme2}" ${warnAdvice}`);
|
|
1116
|
+
}
|
|
1117
|
+
if (!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(scheme2)) {
|
|
1118
|
+
throw new Error(`linkifyjs: incorrect scheme format.
|
|
1119
|
+
1. Must only contain digits, lowercase ASCII letters or "-"
|
|
1120
|
+
2. Cannot start or end with "-"
|
|
1121
|
+
3. "-" cannot repeat`);
|
|
1122
|
+
}
|
|
1123
|
+
INIT.customSchemes.push([scheme2, optionalSlashSlash]);
|
|
1124
|
+
}
|
|
1125
|
+
function init() {
|
|
1126
|
+
INIT.scanner = init$2(INIT.customSchemes);
|
|
1127
|
+
for (let i = 0; i < INIT.tokenQueue.length; i++) {
|
|
1128
|
+
INIT.tokenQueue[i][1]({
|
|
1129
|
+
scanner: INIT.scanner
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
INIT.parser = init$1(INIT.scanner.tokens);
|
|
1133
|
+
for (let i = 0; i < INIT.pluginQueue.length; i++) {
|
|
1134
|
+
INIT.pluginQueue[i][1]({
|
|
1135
|
+
scanner: INIT.scanner,
|
|
1136
|
+
parser: INIT.parser
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
INIT.initialized = true;
|
|
1140
|
+
return INIT;
|
|
1141
|
+
}
|
|
1142
|
+
function tokenize(str) {
|
|
1143
|
+
if (!INIT.initialized) {
|
|
1144
|
+
init();
|
|
1145
|
+
}
|
|
1146
|
+
return run(INIT.parser.start, str, run$1(INIT.scanner.start, str));
|
|
1147
|
+
}
|
|
1148
|
+
tokenize.scan = run$1;
|
|
1149
|
+
function find(str, type = null, opts = null) {
|
|
1150
|
+
if (type && typeof type === "object") {
|
|
1151
|
+
if (opts) {
|
|
1152
|
+
throw Error(`linkifyjs: Invalid link type ${type}; must be a string`);
|
|
1153
|
+
}
|
|
1154
|
+
opts = type;
|
|
1155
|
+
type = null;
|
|
1156
|
+
}
|
|
1157
|
+
const options = new Options(opts);
|
|
1158
|
+
const tokens = tokenize(str);
|
|
1159
|
+
const filtered = [];
|
|
1160
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
1161
|
+
const token = tokens[i];
|
|
1162
|
+
if (token.isLink && (!type || token.t === type) && options.check(token)) {
|
|
1163
|
+
filtered.push(token.toFormattedObject(options));
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return filtered;
|
|
1167
|
+
}
|
|
1168
|
+
var UNICODE_WHITESPACE_PATTERN = "[\0- -\u2029 ]";
|
|
1169
|
+
var UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
|
|
1170
|
+
var UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
|
|
1171
|
+
var UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, "g");
|
|
1172
|
+
function isValidLinkStructure(tokens) {
|
|
1173
|
+
if (tokens.length === 1) {
|
|
1174
|
+
return tokens[0].isLink;
|
|
1175
|
+
}
|
|
1176
|
+
if (tokens.length === 3 && tokens[1].isLink) {
|
|
1177
|
+
return ["()", "[]"].includes(tokens[0].value + tokens[2].value);
|
|
1178
|
+
}
|
|
1179
|
+
return false;
|
|
1180
|
+
}
|
|
1181
|
+
function autolink(options) {
|
|
1182
|
+
return new index.Plugin({
|
|
1183
|
+
key: new index.PluginKey("autolink"),
|
|
1184
|
+
appendTransaction: (transactions, oldState, newState) => {
|
|
1185
|
+
const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
|
|
1186
|
+
const preventAutolink = transactions.some((transaction) => transaction.getMeta("preventAutolink"));
|
|
1187
|
+
if (!docChanges || preventAutolink) {
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
const { tr: tr2 } = newState;
|
|
1191
|
+
const transform = index.combineTransactionSteps(oldState.doc, [...transactions]);
|
|
1192
|
+
const changes = index.getChangedRanges(transform);
|
|
1193
|
+
changes.forEach(({ newRange }) => {
|
|
1194
|
+
const nodesInChangedRanges = index.findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
|
|
1195
|
+
let textBlock;
|
|
1196
|
+
let textBeforeWhitespace;
|
|
1197
|
+
if (nodesInChangedRanges.length > 1) {
|
|
1198
|
+
textBlock = nodesInChangedRanges[0];
|
|
1199
|
+
textBeforeWhitespace = newState.doc.textBetween(
|
|
1200
|
+
textBlock.pos,
|
|
1201
|
+
textBlock.pos + textBlock.node.nodeSize,
|
|
1202
|
+
void 0,
|
|
1203
|
+
" "
|
|
1204
|
+
);
|
|
1205
|
+
} else if (nodesInChangedRanges.length) {
|
|
1206
|
+
const endText = newState.doc.textBetween(newRange.from, newRange.to, " ", " ");
|
|
1207
|
+
if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) {
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
textBlock = nodesInChangedRanges[0];
|
|
1211
|
+
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, void 0, " ");
|
|
1212
|
+
}
|
|
1213
|
+
if (textBlock && textBeforeWhitespace) {
|
|
1214
|
+
const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean);
|
|
1215
|
+
if (wordsBeforeWhitespace.length <= 0) {
|
|
1216
|
+
return false;
|
|
1217
|
+
}
|
|
1218
|
+
const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1];
|
|
1219
|
+
const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace);
|
|
1220
|
+
if (!lastWordBeforeSpace) {
|
|
1221
|
+
return false;
|
|
1222
|
+
}
|
|
1223
|
+
const linksBeforeSpace = tokenize(lastWordBeforeSpace).map((t) => t.toObject(options.defaultProtocol));
|
|
1224
|
+
if (!isValidLinkStructure(linksBeforeSpace)) {
|
|
1225
|
+
return false;
|
|
1226
|
+
}
|
|
1227
|
+
linksBeforeSpace.filter((link) => link.isLink).map((link) => ({
|
|
1228
|
+
...link,
|
|
1229
|
+
from: lastWordAndBlockOffset + link.start + 1,
|
|
1230
|
+
to: lastWordAndBlockOffset + link.end + 1
|
|
1231
|
+
})).filter((link) => {
|
|
1232
|
+
if (!newState.schema.marks.code) {
|
|
1233
|
+
return true;
|
|
1234
|
+
}
|
|
1235
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
1236
|
+
}).filter((link) => options.validate(link.value)).filter((link) => options.shouldAutoLink(link.value)).forEach((link) => {
|
|
1237
|
+
if (index.getMarksBetween(link.from, link.to, newState.doc).some((item) => item.mark.type === options.type)) {
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
tr2.addMark(
|
|
1241
|
+
link.from,
|
|
1242
|
+
link.to,
|
|
1243
|
+
options.type.create({
|
|
1244
|
+
href: link.href
|
|
1245
|
+
})
|
|
1246
|
+
);
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
});
|
|
1250
|
+
if (!tr2.steps.length) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
return tr2;
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
function clickHandler(options) {
|
|
1258
|
+
return new index.Plugin({
|
|
1259
|
+
key: new index.PluginKey("handleClickLink"),
|
|
1260
|
+
props: {
|
|
1261
|
+
handleClick: (view, pos, event) => {
|
|
1262
|
+
var _a, _b;
|
|
1263
|
+
if (event.button !== 0) {
|
|
1264
|
+
return false;
|
|
1265
|
+
}
|
|
1266
|
+
if (!view.editable) {
|
|
1267
|
+
return false;
|
|
1268
|
+
}
|
|
1269
|
+
let link = null;
|
|
1270
|
+
if (event.target instanceof HTMLAnchorElement) {
|
|
1271
|
+
link = event.target;
|
|
1272
|
+
} else {
|
|
1273
|
+
let a = event.target;
|
|
1274
|
+
const els = [];
|
|
1275
|
+
while (a.nodeName !== "DIV") {
|
|
1276
|
+
els.push(a);
|
|
1277
|
+
a = a.parentNode;
|
|
1278
|
+
}
|
|
1279
|
+
link = els.find((value) => value.nodeName === "A");
|
|
1280
|
+
}
|
|
1281
|
+
if (!link) {
|
|
1282
|
+
return false;
|
|
1283
|
+
}
|
|
1284
|
+
const attrs = index.getAttributes(view.state, options.type.name);
|
|
1285
|
+
const href = (_a = link == null ? void 0 : link.href) != null ? _a : attrs.href;
|
|
1286
|
+
const target = (_b = link == null ? void 0 : link.target) != null ? _b : attrs.target;
|
|
1287
|
+
if (options.enableClickSelection) {
|
|
1288
|
+
options.editor.commands.extendMarkRange(options.type.name);
|
|
1289
|
+
}
|
|
1290
|
+
if (link && href) {
|
|
1291
|
+
window.open(href, target);
|
|
1292
|
+
return true;
|
|
1293
|
+
}
|
|
1294
|
+
return false;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
function pasteHandler(options) {
|
|
1300
|
+
return new index.Plugin({
|
|
1301
|
+
key: new index.PluginKey("handlePasteLink"),
|
|
1302
|
+
props: {
|
|
1303
|
+
handlePaste: (view, event, slice2) => {
|
|
1304
|
+
const { state } = view;
|
|
1305
|
+
const { selection } = state;
|
|
1306
|
+
const { empty } = selection;
|
|
1307
|
+
if (empty) {
|
|
1308
|
+
return false;
|
|
1309
|
+
}
|
|
1310
|
+
let textContent = "";
|
|
1311
|
+
slice2.content.forEach((node) => {
|
|
1312
|
+
textContent += node.textContent;
|
|
1313
|
+
});
|
|
1314
|
+
const link = find(textContent, { defaultProtocol: options.defaultProtocol }).find(
|
|
1315
|
+
(item) => item.isLink && item.value === textContent
|
|
1316
|
+
);
|
|
1317
|
+
if (!textContent || !link) {
|
|
1318
|
+
return false;
|
|
1319
|
+
}
|
|
1320
|
+
return options.editor.commands.setMark(options.type, {
|
|
1321
|
+
href: link.href
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
function isAllowedUri(uri, protocols) {
|
|
1328
|
+
const allowedProtocols = ["http", "https", "ftp", "ftps", "mailto", "tel", "callto", "sms", "cid", "xmpp"];
|
|
1329
|
+
if (protocols) {
|
|
1330
|
+
protocols.forEach((protocol) => {
|
|
1331
|
+
const nextProtocol = typeof protocol === "string" ? protocol : protocol.scheme;
|
|
1332
|
+
if (nextProtocol) {
|
|
1333
|
+
allowedProtocols.push(nextProtocol);
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
return !uri || uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, "").match(
|
|
1338
|
+
new RegExp(
|
|
1339
|
+
// eslint-disable-next-line no-useless-escape
|
|
1340
|
+
`^(?:(?:${allowedProtocols.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,
|
|
1341
|
+
"i"
|
|
1342
|
+
)
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
var Link = index.Mark.create({
|
|
1346
|
+
name: "link",
|
|
1347
|
+
priority: 1e3,
|
|
1348
|
+
keepOnSplit: false,
|
|
1349
|
+
exitable: true,
|
|
1350
|
+
onCreate() {
|
|
1351
|
+
if (this.options.validate && !this.options.shouldAutoLink) {
|
|
1352
|
+
this.options.shouldAutoLink = this.options.validate;
|
|
1353
|
+
console.warn("The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.");
|
|
1354
|
+
}
|
|
1355
|
+
this.options.protocols.forEach((protocol) => {
|
|
1356
|
+
if (typeof protocol === "string") {
|
|
1357
|
+
registerCustomProtocol(protocol);
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
registerCustomProtocol(protocol.scheme, protocol.optionalSlashes);
|
|
1361
|
+
});
|
|
1362
|
+
},
|
|
1363
|
+
onDestroy() {
|
|
1364
|
+
reset();
|
|
1365
|
+
},
|
|
1366
|
+
inclusive() {
|
|
1367
|
+
return this.options.autolink;
|
|
1368
|
+
},
|
|
1369
|
+
addOptions() {
|
|
1370
|
+
return {
|
|
1371
|
+
openOnClick: true,
|
|
1372
|
+
enableClickSelection: false,
|
|
1373
|
+
linkOnPaste: true,
|
|
1374
|
+
autolink: true,
|
|
1375
|
+
protocols: [],
|
|
1376
|
+
defaultProtocol: "http",
|
|
1377
|
+
HTMLAttributes: {
|
|
1378
|
+
target: "_blank",
|
|
1379
|
+
rel: "noopener noreferrer nofollow",
|
|
1380
|
+
class: null
|
|
1381
|
+
},
|
|
1382
|
+
isAllowedUri: (url, ctx) => !!isAllowedUri(url, ctx.protocols),
|
|
1383
|
+
validate: (url) => !!url,
|
|
1384
|
+
shouldAutoLink: (url) => !!url
|
|
1385
|
+
};
|
|
1386
|
+
},
|
|
1387
|
+
addAttributes() {
|
|
1388
|
+
return {
|
|
1389
|
+
href: {
|
|
1390
|
+
default: null,
|
|
1391
|
+
parseHTML(element) {
|
|
1392
|
+
return element.getAttribute("href");
|
|
1393
|
+
}
|
|
1394
|
+
},
|
|
1395
|
+
target: {
|
|
1396
|
+
default: this.options.HTMLAttributes.target
|
|
1397
|
+
},
|
|
1398
|
+
rel: {
|
|
1399
|
+
default: this.options.HTMLAttributes.rel
|
|
1400
|
+
},
|
|
1401
|
+
class: {
|
|
1402
|
+
default: this.options.HTMLAttributes.class
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
},
|
|
1406
|
+
parseHTML() {
|
|
1407
|
+
return [
|
|
1408
|
+
{
|
|
1409
|
+
tag: "a[href]",
|
|
1410
|
+
getAttrs: (dom) => {
|
|
1411
|
+
const href = dom.getAttribute("href");
|
|
1412
|
+
if (!href || !this.options.isAllowedUri(href, {
|
|
1413
|
+
defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols),
|
|
1414
|
+
protocols: this.options.protocols,
|
|
1415
|
+
defaultProtocol: this.options.defaultProtocol
|
|
1416
|
+
})) {
|
|
1417
|
+
return false;
|
|
1418
|
+
}
|
|
1419
|
+
return null;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
];
|
|
1423
|
+
},
|
|
1424
|
+
renderHTML({ HTMLAttributes }) {
|
|
1425
|
+
if (!this.options.isAllowedUri(HTMLAttributes.href, {
|
|
1426
|
+
defaultValidate: (href) => !!isAllowedUri(href, this.options.protocols),
|
|
1427
|
+
protocols: this.options.protocols,
|
|
1428
|
+
defaultProtocol: this.options.defaultProtocol
|
|
1429
|
+
})) {
|
|
1430
|
+
return ["a", index.mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: "" }), 0];
|
|
1431
|
+
}
|
|
1432
|
+
return ["a", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
1433
|
+
},
|
|
1434
|
+
addCommands() {
|
|
1435
|
+
return {
|
|
1436
|
+
setLink: (attributes) => ({ chain }) => {
|
|
1437
|
+
const { href } = attributes;
|
|
1438
|
+
if (!this.options.isAllowedUri(href, {
|
|
1439
|
+
defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols),
|
|
1440
|
+
protocols: this.options.protocols,
|
|
1441
|
+
defaultProtocol: this.options.defaultProtocol
|
|
1442
|
+
})) {
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
return chain().setMark(this.name, attributes).setMeta("preventAutolink", true).run();
|
|
1446
|
+
},
|
|
1447
|
+
toggleLink: (attributes) => ({ chain }) => {
|
|
1448
|
+
const { href } = attributes || {};
|
|
1449
|
+
if (href && !this.options.isAllowedUri(href, {
|
|
1450
|
+
defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols),
|
|
1451
|
+
protocols: this.options.protocols,
|
|
1452
|
+
defaultProtocol: this.options.defaultProtocol
|
|
1453
|
+
})) {
|
|
1454
|
+
return false;
|
|
1455
|
+
}
|
|
1456
|
+
return chain().toggleMark(this.name, attributes, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run();
|
|
1457
|
+
},
|
|
1458
|
+
unsetLink: () => ({ chain }) => {
|
|
1459
|
+
return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run();
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
},
|
|
1463
|
+
addPasteRules() {
|
|
1464
|
+
return [
|
|
1465
|
+
index.markPasteRule({
|
|
1466
|
+
find: (text) => {
|
|
1467
|
+
const foundLinks = [];
|
|
1468
|
+
if (text) {
|
|
1469
|
+
const { protocols, defaultProtocol } = this.options;
|
|
1470
|
+
const links = find(text).filter(
|
|
1471
|
+
(item) => item.isLink && this.options.isAllowedUri(item.value, {
|
|
1472
|
+
defaultValidate: (href) => !!isAllowedUri(href, protocols),
|
|
1473
|
+
protocols,
|
|
1474
|
+
defaultProtocol
|
|
1475
|
+
})
|
|
1476
|
+
);
|
|
1477
|
+
if (links.length) {
|
|
1478
|
+
links.forEach(
|
|
1479
|
+
(link) => foundLinks.push({
|
|
1480
|
+
text: link.value,
|
|
1481
|
+
data: {
|
|
1482
|
+
href: link.href
|
|
1483
|
+
},
|
|
1484
|
+
index: link.start
|
|
1485
|
+
})
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
return foundLinks;
|
|
1490
|
+
},
|
|
1491
|
+
type: this.type,
|
|
1492
|
+
getAttributes: (match) => {
|
|
1493
|
+
var _a;
|
|
1494
|
+
return {
|
|
1495
|
+
href: (_a = match.data) == null ? void 0 : _a.href
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
})
|
|
1499
|
+
];
|
|
1500
|
+
},
|
|
1501
|
+
addProseMirrorPlugins() {
|
|
1502
|
+
const plugins = [];
|
|
1503
|
+
const { protocols, defaultProtocol } = this.options;
|
|
1504
|
+
if (this.options.autolink) {
|
|
1505
|
+
plugins.push(
|
|
1506
|
+
autolink({
|
|
1507
|
+
type: this.type,
|
|
1508
|
+
defaultProtocol: this.options.defaultProtocol,
|
|
1509
|
+
validate: (url) => this.options.isAllowedUri(url, {
|
|
1510
|
+
defaultValidate: (href) => !!isAllowedUri(href, protocols),
|
|
1511
|
+
protocols,
|
|
1512
|
+
defaultProtocol
|
|
1513
|
+
}),
|
|
1514
|
+
shouldAutoLink: this.options.shouldAutoLink
|
|
1515
|
+
})
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
if (this.options.openOnClick === true) {
|
|
1519
|
+
plugins.push(
|
|
1520
|
+
clickHandler({
|
|
1521
|
+
type: this.type,
|
|
1522
|
+
editor: this.editor,
|
|
1523
|
+
enableClickSelection: this.options.enableClickSelection
|
|
1524
|
+
})
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
if (this.options.linkOnPaste) {
|
|
1528
|
+
plugins.push(
|
|
1529
|
+
pasteHandler({
|
|
1530
|
+
editor: this.editor,
|
|
1531
|
+
defaultProtocol: this.options.defaultProtocol,
|
|
1532
|
+
type: this.type
|
|
1533
|
+
})
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
return plugins;
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
var index_default$2 = Link;
|
|
1540
|
+
var TextAlign = index.Extension.create({
|
|
1541
|
+
name: "textAlign",
|
|
1542
|
+
addOptions() {
|
|
1543
|
+
return {
|
|
1544
|
+
types: [],
|
|
1545
|
+
alignments: ["left", "center", "right", "justify"],
|
|
1546
|
+
defaultAlignment: null
|
|
1547
|
+
};
|
|
1548
|
+
},
|
|
1549
|
+
addGlobalAttributes() {
|
|
1550
|
+
return [
|
|
1551
|
+
{
|
|
1552
|
+
types: this.options.types,
|
|
1553
|
+
attributes: {
|
|
1554
|
+
textAlign: {
|
|
1555
|
+
default: this.options.defaultAlignment,
|
|
1556
|
+
parseHTML: (element) => {
|
|
1557
|
+
const alignment = element.style.textAlign;
|
|
1558
|
+
return this.options.alignments.includes(alignment) ? alignment : this.options.defaultAlignment;
|
|
1559
|
+
},
|
|
1560
|
+
renderHTML: (attributes) => {
|
|
1561
|
+
if (!attributes.textAlign) {
|
|
1562
|
+
return {};
|
|
1563
|
+
}
|
|
1564
|
+
return { style: `text-align: ${attributes.textAlign}` };
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
];
|
|
1570
|
+
},
|
|
1571
|
+
addCommands() {
|
|
1572
|
+
return {
|
|
1573
|
+
setTextAlign: (alignment) => ({ commands }) => {
|
|
1574
|
+
if (!this.options.alignments.includes(alignment)) {
|
|
1575
|
+
return false;
|
|
1576
|
+
}
|
|
1577
|
+
return this.options.types.map((type) => commands.updateAttributes(type, { textAlign: alignment })).every((response) => response);
|
|
1578
|
+
},
|
|
1579
|
+
unsetTextAlign: () => ({ commands }) => {
|
|
1580
|
+
return this.options.types.map((type) => commands.resetAttributes(type, "textAlign")).every((response) => response);
|
|
1581
|
+
},
|
|
1582
|
+
toggleTextAlign: (alignment) => ({ editor, commands }) => {
|
|
1583
|
+
if (!this.options.alignments.includes(alignment)) {
|
|
1584
|
+
return false;
|
|
1585
|
+
}
|
|
1586
|
+
if (editor.isActive({ textAlign: alignment })) {
|
|
1587
|
+
return commands.unsetTextAlign();
|
|
1588
|
+
}
|
|
1589
|
+
return commands.setTextAlign(alignment);
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
},
|
|
1593
|
+
addKeyboardShortcuts() {
|
|
1594
|
+
return {
|
|
1595
|
+
"Mod-Shift-l": () => this.editor.commands.setTextAlign("left"),
|
|
1596
|
+
"Mod-Shift-e": () => this.editor.commands.setTextAlign("center"),
|
|
1597
|
+
"Mod-Shift-r": () => this.editor.commands.setTextAlign("right"),
|
|
1598
|
+
"Mod-Shift-j": () => this.editor.commands.setTextAlign("justify")
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
var index_default$1 = TextAlign;
|
|
1603
|
+
var mergeNestedSpanStyles = (element) => {
|
|
1604
|
+
if (!element.children.length) {
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
const childSpans = element.querySelectorAll("span");
|
|
1608
|
+
if (!childSpans) {
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
childSpans.forEach((childSpan) => {
|
|
1612
|
+
var _a, _b;
|
|
1613
|
+
const childStyle = childSpan.getAttribute("style");
|
|
1614
|
+
const closestParentSpanStyleOfChild = (_b = (_a = childSpan.parentElement) == null ? void 0 : _a.closest("span")) == null ? void 0 : _b.getAttribute("style");
|
|
1615
|
+
childSpan.setAttribute("style", `${closestParentSpanStyleOfChild};${childStyle}`);
|
|
1616
|
+
});
|
|
1617
|
+
};
|
|
1618
|
+
var TextStyle = index.Mark.create({
|
|
1619
|
+
name: "textStyle",
|
|
1620
|
+
priority: 101,
|
|
1621
|
+
addOptions() {
|
|
1622
|
+
return {
|
|
1623
|
+
HTMLAttributes: {},
|
|
1624
|
+
mergeNestedSpanStyles: true
|
|
1625
|
+
};
|
|
1626
|
+
},
|
|
1627
|
+
parseHTML() {
|
|
1628
|
+
return [
|
|
1629
|
+
{
|
|
1630
|
+
tag: "span",
|
|
1631
|
+
consuming: false,
|
|
1632
|
+
getAttrs: (element) => {
|
|
1633
|
+
const hasStyles = element.hasAttribute("style");
|
|
1634
|
+
if (!hasStyles) {
|
|
1635
|
+
return false;
|
|
1636
|
+
}
|
|
1637
|
+
if (this.options.mergeNestedSpanStyles) {
|
|
1638
|
+
mergeNestedSpanStyles(element);
|
|
1639
|
+
}
|
|
1640
|
+
return {};
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
];
|
|
1644
|
+
},
|
|
1645
|
+
renderHTML({ HTMLAttributes }) {
|
|
1646
|
+
return ["span", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
1647
|
+
},
|
|
1648
|
+
addCommands() {
|
|
1649
|
+
return {
|
|
1650
|
+
toggleTextStyle: (attributes) => ({ commands }) => {
|
|
1651
|
+
return commands.toggleMark(this.name, attributes);
|
|
1652
|
+
},
|
|
1653
|
+
removeEmptyTextStyle: () => ({ tr: tr2 }) => {
|
|
1654
|
+
const { selection } = tr2;
|
|
1655
|
+
tr2.doc.nodesBetween(selection.from, selection.to, (node, pos) => {
|
|
1656
|
+
if (node.isTextblock) {
|
|
1657
|
+
return true;
|
|
1658
|
+
}
|
|
1659
|
+
if (!node.marks.filter((mark) => mark.type === this.type).some((mark) => Object.values(mark.attrs).some((value) => !!value))) {
|
|
1660
|
+
tr2.removeMark(pos, pos + node.nodeSize, this.type);
|
|
1661
|
+
}
|
|
1662
|
+
});
|
|
1663
|
+
return true;
|
|
1664
|
+
}
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
});
|
|
1668
|
+
var BackgroundColor = index.Extension.create({
|
|
1669
|
+
name: "backgroundColor",
|
|
1670
|
+
addOptions() {
|
|
1671
|
+
return {
|
|
1672
|
+
types: ["textStyle"]
|
|
1673
|
+
};
|
|
1674
|
+
},
|
|
1675
|
+
addGlobalAttributes() {
|
|
1676
|
+
return [
|
|
1677
|
+
{
|
|
1678
|
+
types: this.options.types,
|
|
1679
|
+
attributes: {
|
|
1680
|
+
backgroundColor: {
|
|
1681
|
+
default: null,
|
|
1682
|
+
parseHTML: (element) => {
|
|
1683
|
+
var _a;
|
|
1684
|
+
return (_a = element.style.backgroundColor) == null ? void 0 : _a.replace(/['"]+/g, "");
|
|
1685
|
+
},
|
|
1686
|
+
renderHTML: (attributes) => {
|
|
1687
|
+
if (!attributes.backgroundColor) {
|
|
1688
|
+
return {};
|
|
1689
|
+
}
|
|
1690
|
+
return {
|
|
1691
|
+
style: `background-color: ${attributes.backgroundColor}`
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
];
|
|
1698
|
+
},
|
|
1699
|
+
addCommands() {
|
|
1700
|
+
return {
|
|
1701
|
+
setBackgroundColor: (backgroundColor) => ({ chain }) => {
|
|
1702
|
+
return chain().setMark("textStyle", { backgroundColor }).run();
|
|
1703
|
+
},
|
|
1704
|
+
unsetBackgroundColor: () => ({ chain }) => {
|
|
1705
|
+
return chain().setMark("textStyle", { backgroundColor: null }).removeEmptyTextStyle().run();
|
|
1706
|
+
}
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
});
|
|
1710
|
+
var Color = index.Extension.create({
|
|
1711
|
+
name: "color",
|
|
1712
|
+
addOptions() {
|
|
1713
|
+
return {
|
|
1714
|
+
types: ["textStyle"]
|
|
1715
|
+
};
|
|
1716
|
+
},
|
|
1717
|
+
addGlobalAttributes() {
|
|
1718
|
+
return [
|
|
1719
|
+
{
|
|
1720
|
+
types: this.options.types,
|
|
1721
|
+
attributes: {
|
|
1722
|
+
color: {
|
|
1723
|
+
default: null,
|
|
1724
|
+
parseHTML: (element) => {
|
|
1725
|
+
var _a;
|
|
1726
|
+
return (_a = element.style.color) == null ? void 0 : _a.replace(/['"]+/g, "");
|
|
1727
|
+
},
|
|
1728
|
+
renderHTML: (attributes) => {
|
|
1729
|
+
if (!attributes.color) {
|
|
1730
|
+
return {};
|
|
1731
|
+
}
|
|
1732
|
+
return {
|
|
1733
|
+
style: `color: ${attributes.color}`
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
];
|
|
1740
|
+
},
|
|
1741
|
+
addCommands() {
|
|
1742
|
+
return {
|
|
1743
|
+
setColor: (color) => ({ chain }) => {
|
|
1744
|
+
return chain().setMark("textStyle", { color }).run();
|
|
1745
|
+
},
|
|
1746
|
+
unsetColor: () => ({ chain }) => {
|
|
1747
|
+
return chain().setMark("textStyle", { color: null }).removeEmptyTextStyle().run();
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
});
|
|
1752
|
+
var FontFamily = index.Extension.create({
|
|
1753
|
+
name: "fontFamily",
|
|
1754
|
+
addOptions() {
|
|
1755
|
+
return {
|
|
1756
|
+
types: ["textStyle"]
|
|
1757
|
+
};
|
|
1758
|
+
},
|
|
1759
|
+
addGlobalAttributes() {
|
|
1760
|
+
return [
|
|
1761
|
+
{
|
|
1762
|
+
types: this.options.types,
|
|
1763
|
+
attributes: {
|
|
1764
|
+
fontFamily: {
|
|
1765
|
+
default: null,
|
|
1766
|
+
parseHTML: (element) => element.style.fontFamily,
|
|
1767
|
+
renderHTML: (attributes) => {
|
|
1768
|
+
if (!attributes.fontFamily) {
|
|
1769
|
+
return {};
|
|
1770
|
+
}
|
|
1771
|
+
return {
|
|
1772
|
+
style: `font-family: ${attributes.fontFamily}`
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
];
|
|
1779
|
+
},
|
|
1780
|
+
addCommands() {
|
|
1781
|
+
return {
|
|
1782
|
+
setFontFamily: (fontFamily) => ({ chain }) => {
|
|
1783
|
+
return chain().setMark("textStyle", { fontFamily }).run();
|
|
1784
|
+
},
|
|
1785
|
+
unsetFontFamily: () => ({ chain }) => {
|
|
1786
|
+
return chain().setMark("textStyle", { fontFamily: null }).removeEmptyTextStyle().run();
|
|
1787
|
+
}
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
});
|
|
1791
|
+
var FontSize = index.Extension.create({
|
|
1792
|
+
name: "fontSize",
|
|
1793
|
+
addOptions() {
|
|
1794
|
+
return {
|
|
1795
|
+
types: ["textStyle"]
|
|
1796
|
+
};
|
|
1797
|
+
},
|
|
1798
|
+
addGlobalAttributes() {
|
|
1799
|
+
return [
|
|
1800
|
+
{
|
|
1801
|
+
types: this.options.types,
|
|
1802
|
+
attributes: {
|
|
1803
|
+
fontSize: {
|
|
1804
|
+
default: null,
|
|
1805
|
+
parseHTML: (element) => element.style.fontSize,
|
|
1806
|
+
renderHTML: (attributes) => {
|
|
1807
|
+
if (!attributes.fontSize) {
|
|
1808
|
+
return {};
|
|
1809
|
+
}
|
|
1810
|
+
return {
|
|
1811
|
+
style: `font-size: ${attributes.fontSize}`
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
];
|
|
1818
|
+
},
|
|
1819
|
+
addCommands() {
|
|
1820
|
+
return {
|
|
1821
|
+
setFontSize: (fontSize) => ({ chain }) => {
|
|
1822
|
+
return chain().setMark("textStyle", { fontSize }).run();
|
|
1823
|
+
},
|
|
1824
|
+
unsetFontSize: () => ({ chain }) => {
|
|
1825
|
+
return chain().setMark("textStyle", { fontSize: null }).removeEmptyTextStyle().run();
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
var LineHeight = index.Extension.create({
|
|
1831
|
+
name: "lineHeight",
|
|
1832
|
+
addOptions() {
|
|
1833
|
+
return {
|
|
1834
|
+
types: ["textStyle"]
|
|
1835
|
+
};
|
|
1836
|
+
},
|
|
1837
|
+
addGlobalAttributes() {
|
|
1838
|
+
return [
|
|
1839
|
+
{
|
|
1840
|
+
types: this.options.types,
|
|
1841
|
+
attributes: {
|
|
1842
|
+
lineHeight: {
|
|
1843
|
+
default: null,
|
|
1844
|
+
parseHTML: (element) => element.style.lineHeight,
|
|
1845
|
+
renderHTML: (attributes) => {
|
|
1846
|
+
if (!attributes.lineHeight) {
|
|
1847
|
+
return {};
|
|
1848
|
+
}
|
|
1849
|
+
return {
|
|
1850
|
+
style: `line-height: ${attributes.lineHeight}`
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
];
|
|
1857
|
+
},
|
|
1858
|
+
addCommands() {
|
|
1859
|
+
return {
|
|
1860
|
+
setLineHeight: (lineHeight) => ({ chain }) => {
|
|
1861
|
+
return chain().setMark("textStyle", { lineHeight }).run();
|
|
1862
|
+
},
|
|
1863
|
+
unsetLineHeight: () => ({ chain }) => {
|
|
1864
|
+
return chain().setMark("textStyle", { lineHeight: null }).removeEmptyTextStyle().run();
|
|
1865
|
+
}
|
|
1866
|
+
};
|
|
1867
|
+
}
|
|
1868
|
+
});
|
|
1869
|
+
var TextStyleKit = index.Extension.create({
|
|
1870
|
+
name: "textStyleKit",
|
|
1871
|
+
addExtensions() {
|
|
1872
|
+
const extensions = [];
|
|
1873
|
+
if (this.options.backgroundColor !== false) {
|
|
1874
|
+
extensions.push(BackgroundColor.configure(this.options.backgroundColor));
|
|
1875
|
+
}
|
|
1876
|
+
if (this.options.color !== false) {
|
|
1877
|
+
extensions.push(Color.configure(this.options.color));
|
|
1878
|
+
}
|
|
1879
|
+
if (this.options.fontFamily !== false) {
|
|
1880
|
+
extensions.push(FontFamily.configure(this.options.fontFamily));
|
|
1881
|
+
}
|
|
1882
|
+
if (this.options.fontSize !== false) {
|
|
1883
|
+
extensions.push(FontSize.configure(this.options.fontSize));
|
|
1884
|
+
}
|
|
1885
|
+
if (this.options.lineHeight !== false) {
|
|
1886
|
+
extensions.push(LineHeight.configure(this.options.lineHeight));
|
|
1887
|
+
}
|
|
1888
|
+
if (this.options.textStyle !== false) {
|
|
1889
|
+
extensions.push(TextStyle.configure(this.options.textStyle));
|
|
1890
|
+
}
|
|
1891
|
+
return extensions;
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
function dropCursor(options = {}) {
|
|
1895
|
+
return new index.Plugin({
|
|
1896
|
+
view(editorView) {
|
|
1897
|
+
return new DropCursorView(editorView, options);
|
|
1898
|
+
}
|
|
1899
|
+
});
|
|
1900
|
+
}
|
|
1901
|
+
class DropCursorView {
|
|
1902
|
+
constructor(editorView, options) {
|
|
1903
|
+
var _a;
|
|
1904
|
+
this.editorView = editorView;
|
|
1905
|
+
this.cursorPos = null;
|
|
1906
|
+
this.element = null;
|
|
1907
|
+
this.timeout = -1;
|
|
1908
|
+
this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
|
|
1909
|
+
this.color = options.color === false ? void 0 : options.color || "black";
|
|
1910
|
+
this.class = options.class;
|
|
1911
|
+
this.handlers = ["dragover", "dragend", "drop", "dragleave"].map((name) => {
|
|
1912
|
+
let handler = (e) => {
|
|
1913
|
+
this[name](e);
|
|
1914
|
+
};
|
|
1915
|
+
editorView.dom.addEventListener(name, handler);
|
|
1916
|
+
return { name, handler };
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1919
|
+
destroy() {
|
|
1920
|
+
this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
|
|
1921
|
+
}
|
|
1922
|
+
update(editorView, prevState) {
|
|
1923
|
+
if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
|
|
1924
|
+
if (this.cursorPos > editorView.state.doc.content.size)
|
|
1925
|
+
this.setCursor(null);
|
|
1926
|
+
else
|
|
1927
|
+
this.updateOverlay();
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
setCursor(pos) {
|
|
1931
|
+
if (pos == this.cursorPos)
|
|
1932
|
+
return;
|
|
1933
|
+
this.cursorPos = pos;
|
|
1934
|
+
if (pos == null) {
|
|
1935
|
+
this.element.parentNode.removeChild(this.element);
|
|
1936
|
+
this.element = null;
|
|
1937
|
+
} else {
|
|
1938
|
+
this.updateOverlay();
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
updateOverlay() {
|
|
1942
|
+
let $pos = this.editorView.state.doc.resolve(this.cursorPos);
|
|
1943
|
+
let isBlock = !$pos.parent.inlineContent, rect;
|
|
1944
|
+
let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
|
|
1945
|
+
let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
|
|
1946
|
+
if (isBlock) {
|
|
1947
|
+
let before = $pos.nodeBefore, after = $pos.nodeAfter;
|
|
1948
|
+
if (before || after) {
|
|
1949
|
+
let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
|
|
1950
|
+
if (node) {
|
|
1951
|
+
let nodeRect = node.getBoundingClientRect();
|
|
1952
|
+
let top = before ? nodeRect.bottom : nodeRect.top;
|
|
1953
|
+
if (before && after)
|
|
1954
|
+
top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
|
|
1955
|
+
let halfWidth = this.width / 2 * scaleY;
|
|
1956
|
+
rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
if (!rect) {
|
|
1961
|
+
let coords = this.editorView.coordsAtPos(this.cursorPos);
|
|
1962
|
+
let halfWidth = this.width / 2 * scaleX;
|
|
1963
|
+
rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };
|
|
1964
|
+
}
|
|
1965
|
+
let parent = this.editorView.dom.offsetParent;
|
|
1966
|
+
if (!this.element) {
|
|
1967
|
+
this.element = parent.appendChild(document.createElement("div"));
|
|
1968
|
+
if (this.class)
|
|
1969
|
+
this.element.className = this.class;
|
|
1970
|
+
this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
|
|
1971
|
+
if (this.color) {
|
|
1972
|
+
this.element.style.backgroundColor = this.color;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
|
|
1976
|
+
this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
|
|
1977
|
+
let parentLeft, parentTop;
|
|
1978
|
+
if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
|
|
1979
|
+
parentLeft = -pageXOffset;
|
|
1980
|
+
parentTop = -pageYOffset;
|
|
1981
|
+
} else {
|
|
1982
|
+
let rect2 = parent.getBoundingClientRect();
|
|
1983
|
+
let parentScaleX = rect2.width / parent.offsetWidth, parentScaleY = rect2.height / parent.offsetHeight;
|
|
1984
|
+
parentLeft = rect2.left - parent.scrollLeft * parentScaleX;
|
|
1985
|
+
parentTop = rect2.top - parent.scrollTop * parentScaleY;
|
|
1986
|
+
}
|
|
1987
|
+
this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
|
|
1988
|
+
this.element.style.top = (rect.top - parentTop) / scaleY + "px";
|
|
1989
|
+
this.element.style.width = (rect.right - rect.left) / scaleX + "px";
|
|
1990
|
+
this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
|
|
1991
|
+
}
|
|
1992
|
+
scheduleRemoval(timeout) {
|
|
1993
|
+
clearTimeout(this.timeout);
|
|
1994
|
+
this.timeout = setTimeout(() => this.setCursor(null), timeout);
|
|
1995
|
+
}
|
|
1996
|
+
dragover(event) {
|
|
1997
|
+
if (!this.editorView.editable)
|
|
1998
|
+
return;
|
|
1999
|
+
let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
2000
|
+
let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
|
|
2001
|
+
let disableDropCursor = node && node.type.spec.disableDropCursor;
|
|
2002
|
+
let disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor;
|
|
2003
|
+
if (pos && !disabled) {
|
|
2004
|
+
let target = pos.pos;
|
|
2005
|
+
if (this.editorView.dragging && this.editorView.dragging.slice) {
|
|
2006
|
+
let point = index.dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
|
|
2007
|
+
if (point != null)
|
|
2008
|
+
target = point;
|
|
2009
|
+
}
|
|
2010
|
+
this.setCursor(target);
|
|
2011
|
+
this.scheduleRemoval(5e3);
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
dragend() {
|
|
2015
|
+
this.scheduleRemoval(20);
|
|
2016
|
+
}
|
|
2017
|
+
drop() {
|
|
2018
|
+
this.scheduleRemoval(20);
|
|
2019
|
+
}
|
|
2020
|
+
dragleave(event) {
|
|
2021
|
+
if (!this.editorView.dom.contains(event.relatedTarget))
|
|
2022
|
+
this.setCursor(null);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
class GapCursor extends index.Selection {
|
|
2026
|
+
/**
|
|
2027
|
+
Create a gap cursor.
|
|
2028
|
+
*/
|
|
2029
|
+
constructor($pos) {
|
|
2030
|
+
super($pos, $pos);
|
|
2031
|
+
}
|
|
2032
|
+
map(doc, mapping) {
|
|
2033
|
+
let $pos = doc.resolve(mapping.map(this.head));
|
|
2034
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : index.Selection.near($pos);
|
|
2035
|
+
}
|
|
2036
|
+
content() {
|
|
2037
|
+
return index.Slice.empty;
|
|
2038
|
+
}
|
|
2039
|
+
eq(other) {
|
|
2040
|
+
return other instanceof GapCursor && other.head == this.head;
|
|
2041
|
+
}
|
|
2042
|
+
toJSON() {
|
|
2043
|
+
return { type: "gapcursor", pos: this.head };
|
|
2044
|
+
}
|
|
2045
|
+
/**
|
|
2046
|
+
@internal
|
|
2047
|
+
*/
|
|
2048
|
+
static fromJSON(doc, json) {
|
|
2049
|
+
if (typeof json.pos != "number")
|
|
2050
|
+
throw new RangeError("Invalid input for GapCursor.fromJSON");
|
|
2051
|
+
return new GapCursor(doc.resolve(json.pos));
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
@internal
|
|
2055
|
+
*/
|
|
2056
|
+
getBookmark() {
|
|
2057
|
+
return new GapBookmark(this.anchor);
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
@internal
|
|
2061
|
+
*/
|
|
2062
|
+
static valid($pos) {
|
|
2063
|
+
let parent = $pos.parent;
|
|
2064
|
+
if (parent.isTextblock || !closedBefore($pos) || !closedAfter($pos))
|
|
2065
|
+
return false;
|
|
2066
|
+
let override = parent.type.spec.allowGapCursor;
|
|
2067
|
+
if (override != null)
|
|
2068
|
+
return override;
|
|
2069
|
+
let deflt = parent.contentMatchAt($pos.index()).defaultType;
|
|
2070
|
+
return deflt && deflt.isTextblock;
|
|
2071
|
+
}
|
|
2072
|
+
/**
|
|
2073
|
+
@internal
|
|
2074
|
+
*/
|
|
2075
|
+
static findGapCursorFrom($pos, dir, mustMove = false) {
|
|
2076
|
+
search: for (; ; ) {
|
|
2077
|
+
if (!mustMove && GapCursor.valid($pos))
|
|
2078
|
+
return $pos;
|
|
2079
|
+
let pos = $pos.pos, next = null;
|
|
2080
|
+
for (let d = $pos.depth; ; d--) {
|
|
2081
|
+
let parent = $pos.node(d);
|
|
2082
|
+
if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
|
|
2083
|
+
next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
|
|
2084
|
+
break;
|
|
2085
|
+
} else if (d == 0) {
|
|
2086
|
+
return null;
|
|
2087
|
+
}
|
|
2088
|
+
pos += dir;
|
|
2089
|
+
let $cur = $pos.doc.resolve(pos);
|
|
2090
|
+
if (GapCursor.valid($cur))
|
|
2091
|
+
return $cur;
|
|
2092
|
+
}
|
|
2093
|
+
for (; ; ) {
|
|
2094
|
+
let inside = dir > 0 ? next.firstChild : next.lastChild;
|
|
2095
|
+
if (!inside) {
|
|
2096
|
+
if (next.isAtom && !next.isText && !index.NodeSelection.isSelectable(next)) {
|
|
2097
|
+
$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
|
|
2098
|
+
mustMove = false;
|
|
2099
|
+
continue search;
|
|
2100
|
+
}
|
|
2101
|
+
break;
|
|
2102
|
+
}
|
|
2103
|
+
next = inside;
|
|
2104
|
+
pos += dir;
|
|
2105
|
+
let $cur = $pos.doc.resolve(pos);
|
|
2106
|
+
if (GapCursor.valid($cur))
|
|
2107
|
+
return $cur;
|
|
2108
|
+
}
|
|
2109
|
+
return null;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
GapCursor.prototype.visible = false;
|
|
2114
|
+
GapCursor.findFrom = GapCursor.findGapCursorFrom;
|
|
2115
|
+
index.Selection.jsonID("gapcursor", GapCursor);
|
|
2116
|
+
class GapBookmark {
|
|
2117
|
+
constructor(pos) {
|
|
2118
|
+
this.pos = pos;
|
|
2119
|
+
}
|
|
2120
|
+
map(mapping) {
|
|
2121
|
+
return new GapBookmark(mapping.map(this.pos));
|
|
2122
|
+
}
|
|
2123
|
+
resolve(doc) {
|
|
2124
|
+
let $pos = doc.resolve(this.pos);
|
|
2125
|
+
return GapCursor.valid($pos) ? new GapCursor($pos) : index.Selection.near($pos);
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
function closedBefore($pos) {
|
|
2129
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
2130
|
+
let index2 = $pos.index(d), parent = $pos.node(d);
|
|
2131
|
+
if (index2 == 0) {
|
|
2132
|
+
if (parent.type.spec.isolating)
|
|
2133
|
+
return true;
|
|
2134
|
+
continue;
|
|
2135
|
+
}
|
|
2136
|
+
for (let before = parent.child(index2 - 1); ; before = before.lastChild) {
|
|
2137
|
+
if (before.childCount == 0 && !before.inlineContent || before.isAtom || before.type.spec.isolating)
|
|
2138
|
+
return true;
|
|
2139
|
+
if (before.inlineContent)
|
|
2140
|
+
return false;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return true;
|
|
2144
|
+
}
|
|
2145
|
+
function closedAfter($pos) {
|
|
2146
|
+
for (let d = $pos.depth; d >= 0; d--) {
|
|
2147
|
+
let index2 = $pos.indexAfter(d), parent = $pos.node(d);
|
|
2148
|
+
if (index2 == parent.childCount) {
|
|
2149
|
+
if (parent.type.spec.isolating)
|
|
2150
|
+
return true;
|
|
2151
|
+
continue;
|
|
2152
|
+
}
|
|
2153
|
+
for (let after = parent.child(index2); ; after = after.firstChild) {
|
|
2154
|
+
if (after.childCount == 0 && !after.inlineContent || after.isAtom || after.type.spec.isolating)
|
|
2155
|
+
return true;
|
|
2156
|
+
if (after.inlineContent)
|
|
2157
|
+
return false;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
return true;
|
|
2161
|
+
}
|
|
2162
|
+
function gapCursor() {
|
|
2163
|
+
return new index.Plugin({
|
|
2164
|
+
props: {
|
|
2165
|
+
decorations: drawGapCursor,
|
|
2166
|
+
createSelectionBetween(_view, $anchor, $head) {
|
|
2167
|
+
return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
|
|
2168
|
+
},
|
|
2169
|
+
handleClick,
|
|
2170
|
+
handleKeyDown,
|
|
2171
|
+
handleDOMEvents: { beforeinput }
|
|
2172
|
+
}
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
const handleKeyDown = index.keydownHandler({
|
|
2176
|
+
"ArrowLeft": arrow("horiz", -1),
|
|
2177
|
+
"ArrowRight": arrow("horiz", 1),
|
|
2178
|
+
"ArrowUp": arrow("vert", -1),
|
|
2179
|
+
"ArrowDown": arrow("vert", 1)
|
|
2180
|
+
});
|
|
2181
|
+
function arrow(axis, dir) {
|
|
2182
|
+
const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
|
|
2183
|
+
return function(state, dispatch, view) {
|
|
2184
|
+
let sel = state.selection;
|
|
2185
|
+
let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
|
|
2186
|
+
if (sel instanceof index.TextSelection) {
|
|
2187
|
+
if (!view.endOfTextblock(dirStr) || $start.depth == 0)
|
|
2188
|
+
return false;
|
|
2189
|
+
mustMove = false;
|
|
2190
|
+
$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());
|
|
2191
|
+
}
|
|
2192
|
+
let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
|
|
2193
|
+
if (!$found)
|
|
2194
|
+
return false;
|
|
2195
|
+
if (dispatch)
|
|
2196
|
+
dispatch(state.tr.setSelection(new GapCursor($found)));
|
|
2197
|
+
return true;
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
function handleClick(view, pos, event) {
|
|
2201
|
+
if (!view || !view.editable)
|
|
2202
|
+
return false;
|
|
2203
|
+
let $pos = view.state.doc.resolve(pos);
|
|
2204
|
+
if (!GapCursor.valid($pos))
|
|
2205
|
+
return false;
|
|
2206
|
+
let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
2207
|
+
if (clickPos && clickPos.inside > -1 && index.NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))
|
|
2208
|
+
return false;
|
|
2209
|
+
view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
|
|
2210
|
+
return true;
|
|
2211
|
+
}
|
|
2212
|
+
function beforeinput(view, event) {
|
|
2213
|
+
if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor))
|
|
2214
|
+
return false;
|
|
2215
|
+
let { $from } = view.state.selection;
|
|
2216
|
+
let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
|
|
2217
|
+
if (!insert)
|
|
2218
|
+
return false;
|
|
2219
|
+
let frag = index.Fragment.empty;
|
|
2220
|
+
for (let i = insert.length - 1; i >= 0; i--)
|
|
2221
|
+
frag = index.Fragment.from(insert[i].createAndFill(null, frag));
|
|
2222
|
+
let tr2 = view.state.tr.replace($from.pos, $from.pos, new index.Slice(frag, 0, 0));
|
|
2223
|
+
tr2.setSelection(index.TextSelection.near(tr2.doc.resolve($from.pos + 1)));
|
|
2224
|
+
view.dispatch(tr2);
|
|
2225
|
+
return false;
|
|
2226
|
+
}
|
|
2227
|
+
function drawGapCursor(state) {
|
|
2228
|
+
if (!(state.selection instanceof GapCursor))
|
|
2229
|
+
return null;
|
|
2230
|
+
let node = document.createElement("div");
|
|
2231
|
+
node.className = "ProseMirror-gapcursor";
|
|
2232
|
+
return index.DecorationSet.create(state.doc, [index.Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
|
|
2233
|
+
}
|
|
2234
|
+
var GOOD_LEAF_SIZE = 200;
|
|
2235
|
+
var RopeSequence = function RopeSequence2() {
|
|
2236
|
+
};
|
|
2237
|
+
RopeSequence.prototype.append = function append(other) {
|
|
2238
|
+
if (!other.length) {
|
|
2239
|
+
return this;
|
|
2240
|
+
}
|
|
2241
|
+
other = RopeSequence.from(other);
|
|
2242
|
+
return !this.length && other || other.length < GOOD_LEAF_SIZE && this.leafAppend(other) || this.length < GOOD_LEAF_SIZE && other.leafPrepend(this) || this.appendInner(other);
|
|
2243
|
+
};
|
|
2244
|
+
RopeSequence.prototype.prepend = function prepend(other) {
|
|
2245
|
+
if (!other.length) {
|
|
2246
|
+
return this;
|
|
2247
|
+
}
|
|
2248
|
+
return RopeSequence.from(other).append(this);
|
|
2249
|
+
};
|
|
2250
|
+
RopeSequence.prototype.appendInner = function appendInner(other) {
|
|
2251
|
+
return new Append(this, other);
|
|
2252
|
+
};
|
|
2253
|
+
RopeSequence.prototype.slice = function slice(from2, to) {
|
|
2254
|
+
if (from2 === void 0) from2 = 0;
|
|
2255
|
+
if (to === void 0) to = this.length;
|
|
2256
|
+
if (from2 >= to) {
|
|
2257
|
+
return RopeSequence.empty;
|
|
2258
|
+
}
|
|
2259
|
+
return this.sliceInner(Math.max(0, from2), Math.min(this.length, to));
|
|
2260
|
+
};
|
|
2261
|
+
RopeSequence.prototype.get = function get(i) {
|
|
2262
|
+
if (i < 0 || i >= this.length) {
|
|
2263
|
+
return void 0;
|
|
2264
|
+
}
|
|
2265
|
+
return this.getInner(i);
|
|
2266
|
+
};
|
|
2267
|
+
RopeSequence.prototype.forEach = function forEach(f, from2, to) {
|
|
2268
|
+
if (from2 === void 0) from2 = 0;
|
|
2269
|
+
if (to === void 0) to = this.length;
|
|
2270
|
+
if (from2 <= to) {
|
|
2271
|
+
this.forEachInner(f, from2, to, 0);
|
|
2272
|
+
} else {
|
|
2273
|
+
this.forEachInvertedInner(f, from2, to, 0);
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
RopeSequence.prototype.map = function map(f, from2, to) {
|
|
2277
|
+
if (from2 === void 0) from2 = 0;
|
|
2278
|
+
if (to === void 0) to = this.length;
|
|
2279
|
+
var result = [];
|
|
2280
|
+
this.forEach(function(elt, i) {
|
|
2281
|
+
return result.push(f(elt, i));
|
|
2282
|
+
}, from2, to);
|
|
2283
|
+
return result;
|
|
2284
|
+
};
|
|
2285
|
+
RopeSequence.from = function from(values) {
|
|
2286
|
+
if (values instanceof RopeSequence) {
|
|
2287
|
+
return values;
|
|
2288
|
+
}
|
|
2289
|
+
return values && values.length ? new Leaf(values) : RopeSequence.empty;
|
|
2290
|
+
};
|
|
2291
|
+
var Leaf = /* @__PURE__ */ function(RopeSequence3) {
|
|
2292
|
+
function Leaf2(values) {
|
|
2293
|
+
RopeSequence3.call(this);
|
|
2294
|
+
this.values = values;
|
|
2295
|
+
}
|
|
2296
|
+
Leaf2.__proto__ = RopeSequence3;
|
|
2297
|
+
Leaf2.prototype = Object.create(RopeSequence3.prototype);
|
|
2298
|
+
Leaf2.prototype.constructor = Leaf2;
|
|
2299
|
+
var prototypeAccessors = { length: { configurable: true }, depth: { configurable: true } };
|
|
2300
|
+
Leaf2.prototype.flatten = function flatten() {
|
|
2301
|
+
return this.values;
|
|
2302
|
+
};
|
|
2303
|
+
Leaf2.prototype.sliceInner = function sliceInner(from2, to) {
|
|
2304
|
+
if (from2 == 0 && to == this.length) {
|
|
2305
|
+
return this;
|
|
2306
|
+
}
|
|
2307
|
+
return new Leaf2(this.values.slice(from2, to));
|
|
2308
|
+
};
|
|
2309
|
+
Leaf2.prototype.getInner = function getInner(i) {
|
|
2310
|
+
return this.values[i];
|
|
2311
|
+
};
|
|
2312
|
+
Leaf2.prototype.forEachInner = function forEachInner(f, from2, to, start) {
|
|
2313
|
+
for (var i = from2; i < to; i++) {
|
|
2314
|
+
if (f(this.values[i], start + i) === false) {
|
|
2315
|
+
return false;
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
};
|
|
2319
|
+
Leaf2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from2, to, start) {
|
|
2320
|
+
for (var i = from2 - 1; i >= to; i--) {
|
|
2321
|
+
if (f(this.values[i], start + i) === false) {
|
|
2322
|
+
return false;
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
Leaf2.prototype.leafAppend = function leafAppend(other) {
|
|
2327
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE) {
|
|
2328
|
+
return new Leaf2(this.values.concat(other.flatten()));
|
|
2329
|
+
}
|
|
2330
|
+
};
|
|
2331
|
+
Leaf2.prototype.leafPrepend = function leafPrepend(other) {
|
|
2332
|
+
if (this.length + other.length <= GOOD_LEAF_SIZE) {
|
|
2333
|
+
return new Leaf2(other.flatten().concat(this.values));
|
|
2334
|
+
}
|
|
2335
|
+
};
|
|
2336
|
+
prototypeAccessors.length.get = function() {
|
|
2337
|
+
return this.values.length;
|
|
2338
|
+
};
|
|
2339
|
+
prototypeAccessors.depth.get = function() {
|
|
2340
|
+
return 0;
|
|
2341
|
+
};
|
|
2342
|
+
Object.defineProperties(Leaf2.prototype, prototypeAccessors);
|
|
2343
|
+
return Leaf2;
|
|
2344
|
+
}(RopeSequence);
|
|
2345
|
+
RopeSequence.empty = new Leaf([]);
|
|
2346
|
+
var Append = /* @__PURE__ */ function(RopeSequence3) {
|
|
2347
|
+
function Append2(left, right) {
|
|
2348
|
+
RopeSequence3.call(this);
|
|
2349
|
+
this.left = left;
|
|
2350
|
+
this.right = right;
|
|
2351
|
+
this.length = left.length + right.length;
|
|
2352
|
+
this.depth = Math.max(left.depth, right.depth) + 1;
|
|
2353
|
+
}
|
|
2354
|
+
Append2.__proto__ = RopeSequence3;
|
|
2355
|
+
Append2.prototype = Object.create(RopeSequence3.prototype);
|
|
2356
|
+
Append2.prototype.constructor = Append2;
|
|
2357
|
+
Append2.prototype.flatten = function flatten() {
|
|
2358
|
+
return this.left.flatten().concat(this.right.flatten());
|
|
2359
|
+
};
|
|
2360
|
+
Append2.prototype.getInner = function getInner(i) {
|
|
2361
|
+
return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length);
|
|
2362
|
+
};
|
|
2363
|
+
Append2.prototype.forEachInner = function forEachInner(f, from2, to, start) {
|
|
2364
|
+
var leftLen = this.left.length;
|
|
2365
|
+
if (from2 < leftLen && this.left.forEachInner(f, from2, Math.min(to, leftLen), start) === false) {
|
|
2366
|
+
return false;
|
|
2367
|
+
}
|
|
2368
|
+
if (to > leftLen && this.right.forEachInner(f, Math.max(from2 - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false) {
|
|
2369
|
+
return false;
|
|
2370
|
+
}
|
|
2371
|
+
};
|
|
2372
|
+
Append2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from2, to, start) {
|
|
2373
|
+
var leftLen = this.left.length;
|
|
2374
|
+
if (from2 > leftLen && this.right.forEachInvertedInner(f, from2 - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false) {
|
|
2375
|
+
return false;
|
|
2376
|
+
}
|
|
2377
|
+
if (to < leftLen && this.left.forEachInvertedInner(f, Math.min(from2, leftLen), to, start) === false) {
|
|
2378
|
+
return false;
|
|
2379
|
+
}
|
|
2380
|
+
};
|
|
2381
|
+
Append2.prototype.sliceInner = function sliceInner(from2, to) {
|
|
2382
|
+
if (from2 == 0 && to == this.length) {
|
|
2383
|
+
return this;
|
|
2384
|
+
}
|
|
2385
|
+
var leftLen = this.left.length;
|
|
2386
|
+
if (to <= leftLen) {
|
|
2387
|
+
return this.left.slice(from2, to);
|
|
2388
|
+
}
|
|
2389
|
+
if (from2 >= leftLen) {
|
|
2390
|
+
return this.right.slice(from2 - leftLen, to - leftLen);
|
|
2391
|
+
}
|
|
2392
|
+
return this.left.slice(from2, leftLen).append(this.right.slice(0, to - leftLen));
|
|
2393
|
+
};
|
|
2394
|
+
Append2.prototype.leafAppend = function leafAppend(other) {
|
|
2395
|
+
var inner = this.right.leafAppend(other);
|
|
2396
|
+
if (inner) {
|
|
2397
|
+
return new Append2(this.left, inner);
|
|
2398
|
+
}
|
|
2399
|
+
};
|
|
2400
|
+
Append2.prototype.leafPrepend = function leafPrepend(other) {
|
|
2401
|
+
var inner = this.left.leafPrepend(other);
|
|
2402
|
+
if (inner) {
|
|
2403
|
+
return new Append2(inner, this.right);
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
Append2.prototype.appendInner = function appendInner2(other) {
|
|
2407
|
+
if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1) {
|
|
2408
|
+
return new Append2(this.left, new Append2(this.right, other));
|
|
2409
|
+
}
|
|
2410
|
+
return new Append2(this, other);
|
|
2411
|
+
};
|
|
2412
|
+
return Append2;
|
|
2413
|
+
}(RopeSequence);
|
|
2414
|
+
const max_empty_items = 500;
|
|
2415
|
+
class Branch {
|
|
2416
|
+
constructor(items, eventCount) {
|
|
2417
|
+
this.items = items;
|
|
2418
|
+
this.eventCount = eventCount;
|
|
2419
|
+
}
|
|
2420
|
+
// Pop the latest event off the branch's history and apply it
|
|
2421
|
+
// to a document transform.
|
|
2422
|
+
popEvent(state, preserveItems) {
|
|
2423
|
+
if (this.eventCount == 0)
|
|
2424
|
+
return null;
|
|
2425
|
+
let end = this.items.length;
|
|
2426
|
+
for (; ; end--) {
|
|
2427
|
+
let next = this.items.get(end - 1);
|
|
2428
|
+
if (next.selection) {
|
|
2429
|
+
--end;
|
|
2430
|
+
break;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
let remap, mapFrom;
|
|
2434
|
+
if (preserveItems) {
|
|
2435
|
+
remap = this.remapping(end, this.items.length);
|
|
2436
|
+
mapFrom = remap.maps.length;
|
|
2437
|
+
}
|
|
2438
|
+
let transform = state.tr;
|
|
2439
|
+
let selection, remaining;
|
|
2440
|
+
let addAfter = [], addBefore = [];
|
|
2441
|
+
this.items.forEach((item, i) => {
|
|
2442
|
+
if (!item.step) {
|
|
2443
|
+
if (!remap) {
|
|
2444
|
+
remap = this.remapping(end, i + 1);
|
|
2445
|
+
mapFrom = remap.maps.length;
|
|
2446
|
+
}
|
|
2447
|
+
mapFrom--;
|
|
2448
|
+
addBefore.push(item);
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2451
|
+
if (remap) {
|
|
2452
|
+
addBefore.push(new Item(item.map));
|
|
2453
|
+
let step = item.step.map(remap.slice(mapFrom)), map2;
|
|
2454
|
+
if (step && transform.maybeStep(step).doc) {
|
|
2455
|
+
map2 = transform.mapping.maps[transform.mapping.maps.length - 1];
|
|
2456
|
+
addAfter.push(new Item(map2, void 0, void 0, addAfter.length + addBefore.length));
|
|
2457
|
+
}
|
|
2458
|
+
mapFrom--;
|
|
2459
|
+
if (map2)
|
|
2460
|
+
remap.appendMap(map2, mapFrom);
|
|
2461
|
+
} else {
|
|
2462
|
+
transform.maybeStep(item.step);
|
|
2463
|
+
}
|
|
2464
|
+
if (item.selection) {
|
|
2465
|
+
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
|
2466
|
+
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
|
2467
|
+
return false;
|
|
2468
|
+
}
|
|
2469
|
+
}, this.items.length, 0);
|
|
2470
|
+
return { remaining, transform, selection };
|
|
2471
|
+
}
|
|
2472
|
+
// Create a new branch with the given transform added.
|
|
2473
|
+
addTransform(transform, selection, histOptions, preserveItems) {
|
|
2474
|
+
let newItems = [], eventCount = this.eventCount;
|
|
2475
|
+
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
|
2476
|
+
for (let i = 0; i < transform.steps.length; i++) {
|
|
2477
|
+
let step = transform.steps[i].invert(transform.docs[i]);
|
|
2478
|
+
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
|
2479
|
+
if (merged = lastItem && lastItem.merge(item)) {
|
|
2480
|
+
item = merged;
|
|
2481
|
+
if (i)
|
|
2482
|
+
newItems.pop();
|
|
2483
|
+
else
|
|
2484
|
+
oldItems = oldItems.slice(0, oldItems.length - 1);
|
|
2485
|
+
}
|
|
2486
|
+
newItems.push(item);
|
|
2487
|
+
if (selection) {
|
|
2488
|
+
eventCount++;
|
|
2489
|
+
selection = void 0;
|
|
2490
|
+
}
|
|
2491
|
+
if (!preserveItems)
|
|
2492
|
+
lastItem = item;
|
|
2493
|
+
}
|
|
2494
|
+
let overflow = eventCount - histOptions.depth;
|
|
2495
|
+
if (overflow > DEPTH_OVERFLOW) {
|
|
2496
|
+
oldItems = cutOffEvents(oldItems, overflow);
|
|
2497
|
+
eventCount -= overflow;
|
|
2498
|
+
}
|
|
2499
|
+
return new Branch(oldItems.append(newItems), eventCount);
|
|
2500
|
+
}
|
|
2501
|
+
remapping(from2, to) {
|
|
2502
|
+
let maps = new index.Mapping();
|
|
2503
|
+
this.items.forEach((item, i) => {
|
|
2504
|
+
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from2 ? maps.maps.length - item.mirrorOffset : void 0;
|
|
2505
|
+
maps.appendMap(item.map, mirrorPos);
|
|
2506
|
+
}, from2, to);
|
|
2507
|
+
return maps;
|
|
2508
|
+
}
|
|
2509
|
+
addMaps(array) {
|
|
2510
|
+
if (this.eventCount == 0)
|
|
2511
|
+
return this;
|
|
2512
|
+
return new Branch(this.items.append(array.map((map2) => new Item(map2))), this.eventCount);
|
|
2513
|
+
}
|
|
2514
|
+
// When the collab module receives remote changes, the history has
|
|
2515
|
+
// to know about those, so that it can adjust the steps that were
|
|
2516
|
+
// rebased on top of the remote changes, and include the position
|
|
2517
|
+
// maps for the remote changes in its array of items.
|
|
2518
|
+
rebased(rebasedTransform, rebasedCount) {
|
|
2519
|
+
if (!this.eventCount)
|
|
2520
|
+
return this;
|
|
2521
|
+
let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
|
|
2522
|
+
let mapping = rebasedTransform.mapping;
|
|
2523
|
+
let newUntil = rebasedTransform.steps.length;
|
|
2524
|
+
let eventCount = this.eventCount;
|
|
2525
|
+
this.items.forEach((item) => {
|
|
2526
|
+
if (item.selection)
|
|
2527
|
+
eventCount--;
|
|
2528
|
+
}, start);
|
|
2529
|
+
let iRebased = rebasedCount;
|
|
2530
|
+
this.items.forEach((item) => {
|
|
2531
|
+
let pos = mapping.getMirror(--iRebased);
|
|
2532
|
+
if (pos == null)
|
|
2533
|
+
return;
|
|
2534
|
+
newUntil = Math.min(newUntil, pos);
|
|
2535
|
+
let map2 = mapping.maps[pos];
|
|
2536
|
+
if (item.step) {
|
|
2537
|
+
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
|
2538
|
+
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
|
2539
|
+
if (selection)
|
|
2540
|
+
eventCount++;
|
|
2541
|
+
rebasedItems.push(new Item(map2, step, selection));
|
|
2542
|
+
} else {
|
|
2543
|
+
rebasedItems.push(new Item(map2));
|
|
2544
|
+
}
|
|
2545
|
+
}, start);
|
|
2546
|
+
let newMaps = [];
|
|
2547
|
+
for (let i = rebasedCount; i < newUntil; i++)
|
|
2548
|
+
newMaps.push(new Item(mapping.maps[i]));
|
|
2549
|
+
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
|
2550
|
+
let branch = new Branch(items, eventCount);
|
|
2551
|
+
if (branch.emptyItemCount() > max_empty_items)
|
|
2552
|
+
branch = branch.compress(this.items.length - rebasedItems.length);
|
|
2553
|
+
return branch;
|
|
2554
|
+
}
|
|
2555
|
+
emptyItemCount() {
|
|
2556
|
+
let count = 0;
|
|
2557
|
+
this.items.forEach((item) => {
|
|
2558
|
+
if (!item.step)
|
|
2559
|
+
count++;
|
|
2560
|
+
});
|
|
2561
|
+
return count;
|
|
2562
|
+
}
|
|
2563
|
+
// Compressing a branch means rewriting it to push the air (map-only
|
|
2564
|
+
// items) out. During collaboration, these naturally accumulate
|
|
2565
|
+
// because each remote change adds one. The `upto` argument is used
|
|
2566
|
+
// to ensure that only the items below a given level are compressed,
|
|
2567
|
+
// because `rebased` relies on a clean, untouched set of items in
|
|
2568
|
+
// order to associate old items with rebased steps.
|
|
2569
|
+
compress(upto = this.items.length) {
|
|
2570
|
+
let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
|
|
2571
|
+
let items = [], events = 0;
|
|
2572
|
+
this.items.forEach((item, i) => {
|
|
2573
|
+
if (i >= upto) {
|
|
2574
|
+
items.push(item);
|
|
2575
|
+
if (item.selection)
|
|
2576
|
+
events++;
|
|
2577
|
+
} else if (item.step) {
|
|
2578
|
+
let step = item.step.map(remap.slice(mapFrom)), map2 = step && step.getMap();
|
|
2579
|
+
mapFrom--;
|
|
2580
|
+
if (map2)
|
|
2581
|
+
remap.appendMap(map2, mapFrom);
|
|
2582
|
+
if (step) {
|
|
2583
|
+
let selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
|
2584
|
+
if (selection)
|
|
2585
|
+
events++;
|
|
2586
|
+
let newItem = new Item(map2.invert(), step, selection), merged, last = items.length - 1;
|
|
2587
|
+
if (merged = items.length && items[last].merge(newItem))
|
|
2588
|
+
items[last] = merged;
|
|
2589
|
+
else
|
|
2590
|
+
items.push(newItem);
|
|
2591
|
+
}
|
|
2592
|
+
} else if (item.map) {
|
|
2593
|
+
mapFrom--;
|
|
2594
|
+
}
|
|
2595
|
+
}, this.items.length, 0);
|
|
2596
|
+
return new Branch(RopeSequence.from(items.reverse()), events);
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
Branch.empty = new Branch(RopeSequence.empty, 0);
|
|
2600
|
+
function cutOffEvents(items, n) {
|
|
2601
|
+
let cutPoint;
|
|
2602
|
+
items.forEach((item, i) => {
|
|
2603
|
+
if (item.selection && n-- == 0) {
|
|
2604
|
+
cutPoint = i;
|
|
2605
|
+
return false;
|
|
2606
|
+
}
|
|
2607
|
+
});
|
|
2608
|
+
return items.slice(cutPoint);
|
|
2609
|
+
}
|
|
2610
|
+
class Item {
|
|
2611
|
+
constructor(map2, step, selection, mirrorOffset) {
|
|
2612
|
+
this.map = map2;
|
|
2613
|
+
this.step = step;
|
|
2614
|
+
this.selection = selection;
|
|
2615
|
+
this.mirrorOffset = mirrorOffset;
|
|
2616
|
+
}
|
|
2617
|
+
merge(other) {
|
|
2618
|
+
if (this.step && other.step && !other.selection) {
|
|
2619
|
+
let step = other.step.merge(this.step);
|
|
2620
|
+
if (step)
|
|
2621
|
+
return new Item(step.getMap().invert(), step, this.selection);
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
class HistoryState {
|
|
2626
|
+
constructor(done, undone, prevRanges, prevTime, prevComposition) {
|
|
2627
|
+
this.done = done;
|
|
2628
|
+
this.undone = undone;
|
|
2629
|
+
this.prevRanges = prevRanges;
|
|
2630
|
+
this.prevTime = prevTime;
|
|
2631
|
+
this.prevComposition = prevComposition;
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
const DEPTH_OVERFLOW = 20;
|
|
2635
|
+
function applyTransaction(history2, state, tr2, options) {
|
|
2636
|
+
let historyTr = tr2.getMeta(historyKey), rebased;
|
|
2637
|
+
if (historyTr)
|
|
2638
|
+
return historyTr.historyState;
|
|
2639
|
+
if (tr2.getMeta(closeHistoryKey))
|
|
2640
|
+
history2 = new HistoryState(history2.done, history2.undone, null, 0, -1);
|
|
2641
|
+
let appended = tr2.getMeta("appendedTransaction");
|
|
2642
|
+
if (tr2.steps.length == 0) {
|
|
2643
|
+
return history2;
|
|
2644
|
+
} else if (appended && appended.getMeta(historyKey)) {
|
|
2645
|
+
if (appended.getMeta(historyKey).redo)
|
|
2646
|
+
return new HistoryState(history2.done.addTransform(tr2, void 0, options, mustPreserveItems(state)), history2.undone, rangesFor(tr2.mapping.maps), history2.prevTime, history2.prevComposition);
|
|
2647
|
+
else
|
|
2648
|
+
return new HistoryState(history2.done, history2.undone.addTransform(tr2, void 0, options, mustPreserveItems(state)), null, history2.prevTime, history2.prevComposition);
|
|
2649
|
+
} else if (tr2.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
|
2650
|
+
let composition = tr2.getMeta("composition");
|
|
2651
|
+
let newGroup = history2.prevTime == 0 || !appended && history2.prevComposition != composition && (history2.prevTime < (tr2.time || 0) - options.newGroupDelay || !isAdjacentTo(tr2, history2.prevRanges));
|
|
2652
|
+
let prevRanges = appended ? mapRanges(history2.prevRanges, tr2.mapping) : rangesFor(tr2.mapping.maps);
|
|
2653
|
+
return new HistoryState(history2.done.addTransform(tr2, newGroup ? state.selection.getBookmark() : void 0, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr2.time, composition == null ? history2.prevComposition : composition);
|
|
2654
|
+
} else if (rebased = tr2.getMeta("rebased")) {
|
|
2655
|
+
return new HistoryState(history2.done.rebased(tr2, rebased), history2.undone.rebased(tr2, rebased), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition);
|
|
2656
|
+
} else {
|
|
2657
|
+
return new HistoryState(history2.done.addMaps(tr2.mapping.maps), history2.undone.addMaps(tr2.mapping.maps), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition);
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
function isAdjacentTo(transform, prevRanges) {
|
|
2661
|
+
if (!prevRanges)
|
|
2662
|
+
return false;
|
|
2663
|
+
if (!transform.docChanged)
|
|
2664
|
+
return true;
|
|
2665
|
+
let adjacent = false;
|
|
2666
|
+
transform.mapping.maps[0].forEach((start, end) => {
|
|
2667
|
+
for (let i = 0; i < prevRanges.length; i += 2)
|
|
2668
|
+
if (start <= prevRanges[i + 1] && end >= prevRanges[i])
|
|
2669
|
+
adjacent = true;
|
|
2670
|
+
});
|
|
2671
|
+
return adjacent;
|
|
2672
|
+
}
|
|
2673
|
+
function rangesFor(maps) {
|
|
2674
|
+
let result = [];
|
|
2675
|
+
for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
|
|
2676
|
+
maps[i].forEach((_from, _to, from2, to) => result.push(from2, to));
|
|
2677
|
+
return result;
|
|
2678
|
+
}
|
|
2679
|
+
function mapRanges(ranges, mapping) {
|
|
2680
|
+
if (!ranges)
|
|
2681
|
+
return null;
|
|
2682
|
+
let result = [];
|
|
2683
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
2684
|
+
let from2 = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
|
|
2685
|
+
if (from2 <= to)
|
|
2686
|
+
result.push(from2, to);
|
|
2687
|
+
}
|
|
2688
|
+
return result;
|
|
2689
|
+
}
|
|
2690
|
+
function histTransaction(history2, state, redo2) {
|
|
2691
|
+
let preserveItems = mustPreserveItems(state);
|
|
2692
|
+
let histOptions = historyKey.get(state).spec.config;
|
|
2693
|
+
let pop = (redo2 ? history2.undone : history2.done).popEvent(state, preserveItems);
|
|
2694
|
+
if (!pop)
|
|
2695
|
+
return null;
|
|
2696
|
+
let selection = pop.selection.resolve(pop.transform.doc);
|
|
2697
|
+
let added = (redo2 ? history2.done : history2.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
|
2698
|
+
let newHist = new HistoryState(redo2 ? added : pop.remaining, redo2 ? pop.remaining : added, null, 0, -1);
|
|
2699
|
+
return pop.transform.setSelection(selection).setMeta(historyKey, { redo: redo2, historyState: newHist });
|
|
2700
|
+
}
|
|
2701
|
+
let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
|
|
2702
|
+
function mustPreserveItems(state) {
|
|
2703
|
+
let plugins = state.plugins;
|
|
2704
|
+
if (cachedPreserveItemsPlugins != plugins) {
|
|
2705
|
+
cachedPreserveItems = false;
|
|
2706
|
+
cachedPreserveItemsPlugins = plugins;
|
|
2707
|
+
for (let i = 0; i < plugins.length; i++)
|
|
2708
|
+
if (plugins[i].spec.historyPreserveItems) {
|
|
2709
|
+
cachedPreserveItems = true;
|
|
2710
|
+
break;
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
return cachedPreserveItems;
|
|
2714
|
+
}
|
|
2715
|
+
const historyKey = new index.PluginKey("history");
|
|
2716
|
+
const closeHistoryKey = new index.PluginKey("closeHistory");
|
|
2717
|
+
function history(config2 = {}) {
|
|
2718
|
+
config2 = {
|
|
2719
|
+
depth: config2.depth || 100,
|
|
2720
|
+
newGroupDelay: config2.newGroupDelay || 500
|
|
2721
|
+
};
|
|
2722
|
+
return new index.Plugin({
|
|
2723
|
+
key: historyKey,
|
|
2724
|
+
state: {
|
|
2725
|
+
init() {
|
|
2726
|
+
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
|
2727
|
+
},
|
|
2728
|
+
apply(tr2, hist, state) {
|
|
2729
|
+
return applyTransaction(hist, state, tr2, config2);
|
|
2730
|
+
}
|
|
2731
|
+
},
|
|
2732
|
+
config: config2,
|
|
2733
|
+
props: {
|
|
2734
|
+
handleDOMEvents: {
|
|
2735
|
+
beforeinput(view, e) {
|
|
2736
|
+
let inputType = e.inputType;
|
|
2737
|
+
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
|
2738
|
+
if (!command)
|
|
2739
|
+
return false;
|
|
2740
|
+
e.preventDefault();
|
|
2741
|
+
return command(view.state, view.dispatch);
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
});
|
|
2746
|
+
}
|
|
2747
|
+
function buildCommand(redo2, scroll) {
|
|
2748
|
+
return (state, dispatch) => {
|
|
2749
|
+
let hist = historyKey.getState(state);
|
|
2750
|
+
if (!hist || (redo2 ? hist.undone : hist.done).eventCount == 0)
|
|
2751
|
+
return false;
|
|
2752
|
+
if (dispatch) {
|
|
2753
|
+
let tr2 = histTransaction(hist, state, redo2);
|
|
2754
|
+
if (tr2)
|
|
2755
|
+
dispatch(scroll ? tr2.scrollIntoView() : tr2);
|
|
2756
|
+
}
|
|
2757
|
+
return true;
|
|
2758
|
+
};
|
|
2759
|
+
}
|
|
2760
|
+
const undo = buildCommand(false, true);
|
|
2761
|
+
const redo = buildCommand(true, true);
|
|
2762
|
+
var CharacterCount = index.Extension.create({
|
|
2763
|
+
name: "characterCount",
|
|
2764
|
+
addOptions() {
|
|
2765
|
+
return {
|
|
2766
|
+
limit: null,
|
|
2767
|
+
mode: "textSize",
|
|
2768
|
+
textCounter: (text) => text.length,
|
|
2769
|
+
wordCounter: (text) => text.split(" ").filter((word) => word !== "").length
|
|
2770
|
+
};
|
|
2771
|
+
},
|
|
2772
|
+
addStorage() {
|
|
2773
|
+
return {
|
|
2774
|
+
characters: () => 0,
|
|
2775
|
+
words: () => 0
|
|
2776
|
+
};
|
|
2777
|
+
},
|
|
2778
|
+
onBeforeCreate() {
|
|
2779
|
+
this.storage.characters = (options) => {
|
|
2780
|
+
const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
|
|
2781
|
+
const mode = (options == null ? void 0 : options.mode) || this.options.mode;
|
|
2782
|
+
if (mode === "textSize") {
|
|
2783
|
+
const text = node.textBetween(0, node.content.size, void 0, " ");
|
|
2784
|
+
return this.options.textCounter(text);
|
|
2785
|
+
}
|
|
2786
|
+
return node.nodeSize;
|
|
2787
|
+
};
|
|
2788
|
+
this.storage.words = (options) => {
|
|
2789
|
+
const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
|
|
2790
|
+
const text = node.textBetween(0, node.content.size, " ", " ");
|
|
2791
|
+
return this.options.wordCounter(text);
|
|
2792
|
+
};
|
|
2793
|
+
},
|
|
2794
|
+
addProseMirrorPlugins() {
|
|
2795
|
+
let initialEvaluationDone = false;
|
|
2796
|
+
return [
|
|
2797
|
+
new index.Plugin({
|
|
2798
|
+
key: new index.PluginKey("characterCount"),
|
|
2799
|
+
appendTransaction: (transactions, oldState, newState) => {
|
|
2800
|
+
if (initialEvaluationDone) {
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
const limit = this.options.limit;
|
|
2804
|
+
if (limit === null || limit === void 0 || limit === 0) {
|
|
2805
|
+
initialEvaluationDone = true;
|
|
2806
|
+
return;
|
|
2807
|
+
}
|
|
2808
|
+
const initialContentSize = this.storage.characters({ node: newState.doc });
|
|
2809
|
+
if (initialContentSize > limit) {
|
|
2810
|
+
const over = initialContentSize - limit;
|
|
2811
|
+
const from2 = 0;
|
|
2812
|
+
const to = over;
|
|
2813
|
+
console.warn(
|
|
2814
|
+
`[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`
|
|
2815
|
+
);
|
|
2816
|
+
const tr2 = newState.tr.deleteRange(from2, to);
|
|
2817
|
+
initialEvaluationDone = true;
|
|
2818
|
+
return tr2;
|
|
2819
|
+
}
|
|
2820
|
+
initialEvaluationDone = true;
|
|
2821
|
+
},
|
|
2822
|
+
filterTransaction: (transaction, state) => {
|
|
2823
|
+
const limit = this.options.limit;
|
|
2824
|
+
if (!transaction.docChanged || limit === 0 || limit === null || limit === void 0) {
|
|
2825
|
+
return true;
|
|
2826
|
+
}
|
|
2827
|
+
const oldSize = this.storage.characters({ node: state.doc });
|
|
2828
|
+
const newSize = this.storage.characters({ node: transaction.doc });
|
|
2829
|
+
if (newSize <= limit) {
|
|
2830
|
+
return true;
|
|
2831
|
+
}
|
|
2832
|
+
if (oldSize > limit && newSize > limit && newSize <= oldSize) {
|
|
2833
|
+
return true;
|
|
2834
|
+
}
|
|
2835
|
+
if (oldSize > limit && newSize > limit && newSize > oldSize) {
|
|
2836
|
+
return false;
|
|
2837
|
+
}
|
|
2838
|
+
const isPaste = transaction.getMeta("paste");
|
|
2839
|
+
if (!isPaste) {
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2842
|
+
const pos = transaction.selection.$head.pos;
|
|
2843
|
+
const over = newSize - limit;
|
|
2844
|
+
const from2 = pos - over;
|
|
2845
|
+
const to = pos;
|
|
2846
|
+
transaction.deleteRange(from2, to);
|
|
2847
|
+
const updatedSize = this.storage.characters({ node: transaction.doc });
|
|
2848
|
+
if (updatedSize > limit) {
|
|
2849
|
+
return false;
|
|
2850
|
+
}
|
|
2851
|
+
return true;
|
|
2852
|
+
}
|
|
2853
|
+
})
|
|
2854
|
+
];
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
var Dropcursor = index.Extension.create({
|
|
2858
|
+
name: "dropCursor",
|
|
2859
|
+
addOptions() {
|
|
2860
|
+
return {
|
|
2861
|
+
color: "currentColor",
|
|
2862
|
+
width: 1,
|
|
2863
|
+
class: void 0
|
|
2864
|
+
};
|
|
2865
|
+
},
|
|
2866
|
+
addProseMirrorPlugins() {
|
|
2867
|
+
return [dropCursor(this.options)];
|
|
2868
|
+
}
|
|
2869
|
+
});
|
|
2870
|
+
index.Extension.create({
|
|
2871
|
+
name: "focus",
|
|
2872
|
+
addOptions() {
|
|
2873
|
+
return {
|
|
2874
|
+
className: "has-focus",
|
|
2875
|
+
mode: "all"
|
|
2876
|
+
};
|
|
2877
|
+
},
|
|
2878
|
+
addProseMirrorPlugins() {
|
|
2879
|
+
return [
|
|
2880
|
+
new index.Plugin({
|
|
2881
|
+
key: new index.PluginKey("focus"),
|
|
2882
|
+
props: {
|
|
2883
|
+
decorations: ({ doc, selection }) => {
|
|
2884
|
+
const { isEditable, isFocused } = this.editor;
|
|
2885
|
+
const { anchor } = selection;
|
|
2886
|
+
const decorations = [];
|
|
2887
|
+
if (!isEditable || !isFocused) {
|
|
2888
|
+
return index.DecorationSet.create(doc, []);
|
|
2889
|
+
}
|
|
2890
|
+
let maxLevels = 0;
|
|
2891
|
+
if (this.options.mode === "deepest") {
|
|
2892
|
+
doc.descendants((node, pos) => {
|
|
2893
|
+
if (node.isText) {
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;
|
|
2897
|
+
if (!isCurrent) {
|
|
2898
|
+
return false;
|
|
2899
|
+
}
|
|
2900
|
+
maxLevels += 1;
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
let currentLevel = 0;
|
|
2904
|
+
doc.descendants((node, pos) => {
|
|
2905
|
+
if (node.isText) {
|
|
2906
|
+
return false;
|
|
2907
|
+
}
|
|
2908
|
+
const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;
|
|
2909
|
+
if (!isCurrent) {
|
|
2910
|
+
return false;
|
|
2911
|
+
}
|
|
2912
|
+
currentLevel += 1;
|
|
2913
|
+
const outOfScope = this.options.mode === "deepest" && maxLevels - currentLevel > 0 || this.options.mode === "shallowest" && currentLevel > 1;
|
|
2914
|
+
if (outOfScope) {
|
|
2915
|
+
return this.options.mode === "deepest";
|
|
2916
|
+
}
|
|
2917
|
+
decorations.push(
|
|
2918
|
+
index.Decoration.node(pos, pos + node.nodeSize, {
|
|
2919
|
+
class: this.options.className
|
|
2920
|
+
})
|
|
2921
|
+
);
|
|
2922
|
+
});
|
|
2923
|
+
return index.DecorationSet.create(doc, decorations);
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
})
|
|
2927
|
+
];
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
var Gapcursor = index.Extension.create({
|
|
2931
|
+
name: "gapCursor",
|
|
2932
|
+
addProseMirrorPlugins() {
|
|
2933
|
+
return [gapCursor()];
|
|
2934
|
+
},
|
|
2935
|
+
extendNodeSchema(extension) {
|
|
2936
|
+
var _a;
|
|
2937
|
+
const context = {
|
|
2938
|
+
name: extension.name,
|
|
2939
|
+
options: extension.options,
|
|
2940
|
+
storage: extension.storage
|
|
2941
|
+
};
|
|
2942
|
+
return {
|
|
2943
|
+
allowGapCursor: (_a = index.callOrReturn(index.getExtensionField(extension, "allowGapCursor", context))) != null ? _a : null
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
});
|
|
2947
|
+
var Placeholder = index.Extension.create({
|
|
2948
|
+
name: "placeholder",
|
|
2949
|
+
addOptions() {
|
|
2950
|
+
return {
|
|
2951
|
+
emptyEditorClass: "is-editor-empty",
|
|
2952
|
+
emptyNodeClass: "is-empty",
|
|
2953
|
+
placeholder: "Write something …",
|
|
2954
|
+
showOnlyWhenEditable: true,
|
|
2955
|
+
showOnlyCurrent: true,
|
|
2956
|
+
includeChildren: false
|
|
2957
|
+
};
|
|
2958
|
+
},
|
|
2959
|
+
addProseMirrorPlugins() {
|
|
2960
|
+
return [
|
|
2961
|
+
new index.Plugin({
|
|
2962
|
+
key: new index.PluginKey("placeholder"),
|
|
2963
|
+
props: {
|
|
2964
|
+
decorations: ({ doc, selection }) => {
|
|
2965
|
+
const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
|
|
2966
|
+
const { anchor } = selection;
|
|
2967
|
+
const decorations = [];
|
|
2968
|
+
if (!active) {
|
|
2969
|
+
return null;
|
|
2970
|
+
}
|
|
2971
|
+
const isEmptyDoc = this.editor.isEmpty;
|
|
2972
|
+
doc.descendants((node, pos) => {
|
|
2973
|
+
const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
|
|
2974
|
+
const isEmpty = !node.isLeaf && index.isNodeEmpty(node);
|
|
2975
|
+
if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
|
|
2976
|
+
const classes = [this.options.emptyNodeClass];
|
|
2977
|
+
if (isEmptyDoc) {
|
|
2978
|
+
classes.push(this.options.emptyEditorClass);
|
|
2979
|
+
}
|
|
2980
|
+
const decoration = index.Decoration.node(pos, pos + node.nodeSize, {
|
|
2981
|
+
class: classes.join(" "),
|
|
2982
|
+
"data-placeholder": typeof this.options.placeholder === "function" ? this.options.placeholder({
|
|
2983
|
+
editor: this.editor,
|
|
2984
|
+
node,
|
|
2985
|
+
pos,
|
|
2986
|
+
hasAnchor
|
|
2987
|
+
}) : this.options.placeholder
|
|
2988
|
+
});
|
|
2989
|
+
decorations.push(decoration);
|
|
2990
|
+
}
|
|
2991
|
+
return this.options.includeChildren;
|
|
2992
|
+
});
|
|
2993
|
+
return index.DecorationSet.create(doc, decorations);
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
})
|
|
2997
|
+
];
|
|
2998
|
+
}
|
|
2999
|
+
});
|
|
3000
|
+
index.Extension.create({
|
|
3001
|
+
name: "selection",
|
|
3002
|
+
addOptions() {
|
|
3003
|
+
return {
|
|
3004
|
+
className: "selection"
|
|
3005
|
+
};
|
|
3006
|
+
},
|
|
3007
|
+
addProseMirrorPlugins() {
|
|
3008
|
+
const { editor, options } = this;
|
|
3009
|
+
return [
|
|
3010
|
+
new index.Plugin({
|
|
3011
|
+
key: new index.PluginKey("selection"),
|
|
3012
|
+
props: {
|
|
3013
|
+
decorations(state) {
|
|
3014
|
+
if (state.selection.empty || editor.isFocused || !editor.isEditable || index.isNodeSelection(state.selection) || editor.view.dragging) {
|
|
3015
|
+
return null;
|
|
3016
|
+
}
|
|
3017
|
+
return index.DecorationSet.create(state.doc, [
|
|
3018
|
+
index.Decoration.inline(state.selection.from, state.selection.to, {
|
|
3019
|
+
class: options.className
|
|
3020
|
+
})
|
|
3021
|
+
]);
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
})
|
|
3025
|
+
];
|
|
3026
|
+
}
|
|
3027
|
+
});
|
|
3028
|
+
function nodeEqualsType({ types, node }) {
|
|
3029
|
+
return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;
|
|
3030
|
+
}
|
|
3031
|
+
var TrailingNode = index.Extension.create({
|
|
3032
|
+
name: "trailingNode",
|
|
3033
|
+
addOptions() {
|
|
3034
|
+
return {
|
|
3035
|
+
node: "paragraph",
|
|
3036
|
+
notAfter: []
|
|
3037
|
+
};
|
|
3038
|
+
},
|
|
3039
|
+
addProseMirrorPlugins() {
|
|
3040
|
+
const plugin = new index.PluginKey(this.name);
|
|
3041
|
+
const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => (this.options.notAfter || []).concat(this.options.node).includes(node.name));
|
|
3042
|
+
return [
|
|
3043
|
+
new index.Plugin({
|
|
3044
|
+
key: plugin,
|
|
3045
|
+
appendTransaction: (_, __, state) => {
|
|
3046
|
+
const { doc, tr: tr2, schema } = state;
|
|
3047
|
+
const shouldInsertNodeAtEnd = plugin.getState(state);
|
|
3048
|
+
const endPosition = doc.content.size;
|
|
3049
|
+
const type = schema.nodes[this.options.node];
|
|
3050
|
+
if (!shouldInsertNodeAtEnd) {
|
|
3051
|
+
return;
|
|
3052
|
+
}
|
|
3053
|
+
return tr2.insert(endPosition, type.create());
|
|
3054
|
+
},
|
|
3055
|
+
state: {
|
|
3056
|
+
init: (_, state) => {
|
|
3057
|
+
const lastNode = state.tr.doc.lastChild;
|
|
3058
|
+
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
|
|
3059
|
+
},
|
|
3060
|
+
apply: (tr2, value) => {
|
|
3061
|
+
if (!tr2.docChanged) {
|
|
3062
|
+
return value;
|
|
3063
|
+
}
|
|
3064
|
+
const lastNode = tr2.doc.lastChild;
|
|
3065
|
+
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
})
|
|
3069
|
+
];
|
|
3070
|
+
}
|
|
3071
|
+
});
|
|
3072
|
+
var UndoRedo = index.Extension.create({
|
|
3073
|
+
name: "undoRedo",
|
|
3074
|
+
addOptions() {
|
|
3075
|
+
return {
|
|
3076
|
+
depth: 100,
|
|
3077
|
+
newGroupDelay: 500
|
|
3078
|
+
};
|
|
3079
|
+
},
|
|
3080
|
+
addCommands() {
|
|
3081
|
+
return {
|
|
3082
|
+
undo: () => ({ state, dispatch }) => {
|
|
3083
|
+
return undo(state, dispatch);
|
|
3084
|
+
},
|
|
3085
|
+
redo: () => ({ state, dispatch }) => {
|
|
3086
|
+
return redo(state, dispatch);
|
|
3087
|
+
}
|
|
3088
|
+
};
|
|
3089
|
+
},
|
|
3090
|
+
addProseMirrorPlugins() {
|
|
3091
|
+
return [history(this.options)];
|
|
3092
|
+
},
|
|
3093
|
+
addKeyboardShortcuts() {
|
|
3094
|
+
return {
|
|
3095
|
+
"Mod-z": () => this.editor.commands.undo(),
|
|
3096
|
+
"Shift-Mod-z": () => this.editor.commands.redo(),
|
|
3097
|
+
"Mod-y": () => this.editor.commands.redo(),
|
|
3098
|
+
// Russian keyboard layouts
|
|
3099
|
+
"Mod-я": () => this.editor.commands.undo(),
|
|
3100
|
+
"Shift-Mod-я": () => this.editor.commands.redo()
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
var h = (tag, attributes) => {
|
|
3105
|
+
if (tag === "slot") {
|
|
3106
|
+
return 0;
|
|
3107
|
+
}
|
|
3108
|
+
if (tag instanceof Function) {
|
|
3109
|
+
return tag(attributes);
|
|
3110
|
+
}
|
|
3111
|
+
const { children, ...rest } = attributes != null ? attributes : {};
|
|
3112
|
+
if (tag === "svg") {
|
|
3113
|
+
throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
|
|
3114
|
+
}
|
|
3115
|
+
return [tag, rest, children];
|
|
3116
|
+
};
|
|
3117
|
+
var inputRegex$3 = /^\s*>\s$/;
|
|
3118
|
+
var Blockquote = index.Node3.create({
|
|
3119
|
+
name: "blockquote",
|
|
3120
|
+
addOptions() {
|
|
3121
|
+
return {
|
|
3122
|
+
HTMLAttributes: {}
|
|
3123
|
+
};
|
|
3124
|
+
},
|
|
3125
|
+
content: "block+",
|
|
3126
|
+
group: "block",
|
|
3127
|
+
defining: true,
|
|
3128
|
+
parseHTML() {
|
|
3129
|
+
return [{ tag: "blockquote" }];
|
|
3130
|
+
},
|
|
3131
|
+
renderHTML({ HTMLAttributes }) {
|
|
3132
|
+
return /* @__PURE__ */ h("blockquote", { ...index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), children: /* @__PURE__ */ h("slot", {}) });
|
|
3133
|
+
},
|
|
3134
|
+
addCommands() {
|
|
3135
|
+
return {
|
|
3136
|
+
setBlockquote: () => ({ commands }) => {
|
|
3137
|
+
return commands.wrapIn(this.name);
|
|
3138
|
+
},
|
|
3139
|
+
toggleBlockquote: () => ({ commands }) => {
|
|
3140
|
+
return commands.toggleWrap(this.name);
|
|
3141
|
+
},
|
|
3142
|
+
unsetBlockquote: () => ({ commands }) => {
|
|
3143
|
+
return commands.lift(this.name);
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
},
|
|
3147
|
+
addKeyboardShortcuts() {
|
|
3148
|
+
return {
|
|
3149
|
+
"Mod-Shift-b": () => this.editor.commands.toggleBlockquote()
|
|
3150
|
+
};
|
|
3151
|
+
},
|
|
3152
|
+
addInputRules() {
|
|
3153
|
+
return [
|
|
3154
|
+
index.wrappingInputRule({
|
|
3155
|
+
find: inputRegex$3,
|
|
3156
|
+
type: this.type
|
|
3157
|
+
})
|
|
3158
|
+
];
|
|
3159
|
+
}
|
|
3160
|
+
});
|
|
3161
|
+
var starInputRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/;
|
|
3162
|
+
var starPasteRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g;
|
|
3163
|
+
var underscoreInputRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/;
|
|
3164
|
+
var underscorePasteRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g;
|
|
3165
|
+
var Bold = index.Mark.create({
|
|
3166
|
+
name: "bold",
|
|
3167
|
+
addOptions() {
|
|
3168
|
+
return {
|
|
3169
|
+
HTMLAttributes: {}
|
|
3170
|
+
};
|
|
3171
|
+
},
|
|
3172
|
+
parseHTML() {
|
|
3173
|
+
return [
|
|
3174
|
+
{
|
|
3175
|
+
tag: "strong"
|
|
3176
|
+
},
|
|
3177
|
+
{
|
|
3178
|
+
tag: "b",
|
|
3179
|
+
getAttrs: (node) => node.style.fontWeight !== "normal" && null
|
|
3180
|
+
},
|
|
3181
|
+
{
|
|
3182
|
+
style: "font-weight=400",
|
|
3183
|
+
clearMark: (mark) => mark.type.name === this.name
|
|
3184
|
+
},
|
|
3185
|
+
{
|
|
3186
|
+
style: "font-weight",
|
|
3187
|
+
getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
|
|
3188
|
+
}
|
|
3189
|
+
];
|
|
3190
|
+
},
|
|
3191
|
+
renderHTML({ HTMLAttributes }) {
|
|
3192
|
+
return /* @__PURE__ */ h("strong", { ...index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), children: /* @__PURE__ */ h("slot", {}) });
|
|
3193
|
+
},
|
|
3194
|
+
addCommands() {
|
|
3195
|
+
return {
|
|
3196
|
+
setBold: () => ({ commands }) => {
|
|
3197
|
+
return commands.setMark(this.name);
|
|
3198
|
+
},
|
|
3199
|
+
toggleBold: () => ({ commands }) => {
|
|
3200
|
+
return commands.toggleMark(this.name);
|
|
3201
|
+
},
|
|
3202
|
+
unsetBold: () => ({ commands }) => {
|
|
3203
|
+
return commands.unsetMark(this.name);
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
},
|
|
3207
|
+
addKeyboardShortcuts() {
|
|
3208
|
+
return {
|
|
3209
|
+
"Mod-b": () => this.editor.commands.toggleBold(),
|
|
3210
|
+
"Mod-B": () => this.editor.commands.toggleBold()
|
|
3211
|
+
};
|
|
3212
|
+
},
|
|
3213
|
+
addInputRules() {
|
|
3214
|
+
return [
|
|
3215
|
+
index.markInputRule({
|
|
3216
|
+
find: starInputRegex$1,
|
|
3217
|
+
type: this.type
|
|
3218
|
+
}),
|
|
3219
|
+
index.markInputRule({
|
|
3220
|
+
find: underscoreInputRegex$1,
|
|
3221
|
+
type: this.type
|
|
3222
|
+
})
|
|
3223
|
+
];
|
|
3224
|
+
},
|
|
3225
|
+
addPasteRules() {
|
|
3226
|
+
return [
|
|
3227
|
+
index.markPasteRule({
|
|
3228
|
+
find: starPasteRegex$1,
|
|
3229
|
+
type: this.type
|
|
3230
|
+
}),
|
|
3231
|
+
index.markPasteRule({
|
|
3232
|
+
find: underscorePasteRegex$1,
|
|
3233
|
+
type: this.type
|
|
3234
|
+
})
|
|
3235
|
+
];
|
|
3236
|
+
}
|
|
3237
|
+
});
|
|
3238
|
+
var inputRegex$2 = /(^|[^`])`([^`]+)`(?!`)/;
|
|
3239
|
+
var pasteRegex$1 = /(^|[^`])`([^`]+)`(?!`)/g;
|
|
3240
|
+
var Code = index.Mark.create({
|
|
3241
|
+
name: "code",
|
|
3242
|
+
addOptions() {
|
|
3243
|
+
return {
|
|
3244
|
+
HTMLAttributes: {}
|
|
3245
|
+
};
|
|
3246
|
+
},
|
|
3247
|
+
excludes: "_",
|
|
3248
|
+
code: true,
|
|
3249
|
+
exitable: true,
|
|
3250
|
+
parseHTML() {
|
|
3251
|
+
return [{ tag: "code" }];
|
|
3252
|
+
},
|
|
3253
|
+
renderHTML({ HTMLAttributes }) {
|
|
3254
|
+
return ["code", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
3255
|
+
},
|
|
3256
|
+
addCommands() {
|
|
3257
|
+
return {
|
|
3258
|
+
setCode: () => ({ commands }) => {
|
|
3259
|
+
return commands.setMark(this.name);
|
|
3260
|
+
},
|
|
3261
|
+
toggleCode: () => ({ commands }) => {
|
|
3262
|
+
return commands.toggleMark(this.name);
|
|
3263
|
+
},
|
|
3264
|
+
unsetCode: () => ({ commands }) => {
|
|
3265
|
+
return commands.unsetMark(this.name);
|
|
3266
|
+
}
|
|
3267
|
+
};
|
|
3268
|
+
},
|
|
3269
|
+
addKeyboardShortcuts() {
|
|
3270
|
+
return {
|
|
3271
|
+
"Mod-e": () => this.editor.commands.toggleCode()
|
|
3272
|
+
};
|
|
3273
|
+
},
|
|
3274
|
+
addInputRules() {
|
|
3275
|
+
return [
|
|
3276
|
+
index.markInputRule({
|
|
3277
|
+
find: inputRegex$2,
|
|
3278
|
+
type: this.type
|
|
3279
|
+
})
|
|
3280
|
+
];
|
|
3281
|
+
},
|
|
3282
|
+
addPasteRules() {
|
|
3283
|
+
return [
|
|
3284
|
+
index.markPasteRule({
|
|
3285
|
+
find: pasteRegex$1,
|
|
3286
|
+
type: this.type
|
|
3287
|
+
})
|
|
3288
|
+
];
|
|
3289
|
+
}
|
|
3290
|
+
});
|
|
3291
|
+
var backtickInputRegex = /^```([a-z]+)?[\s\n]$/;
|
|
3292
|
+
var tildeInputRegex = /^~~~([a-z]+)?[\s\n]$/;
|
|
3293
|
+
var CodeBlock = index.Node3.create({
|
|
3294
|
+
name: "codeBlock",
|
|
3295
|
+
addOptions() {
|
|
3296
|
+
return {
|
|
3297
|
+
languageClassPrefix: "language-",
|
|
3298
|
+
exitOnTripleEnter: true,
|
|
3299
|
+
exitOnArrowDown: true,
|
|
3300
|
+
defaultLanguage: null,
|
|
3301
|
+
HTMLAttributes: {}
|
|
3302
|
+
};
|
|
3303
|
+
},
|
|
3304
|
+
content: "text*",
|
|
3305
|
+
marks: "",
|
|
3306
|
+
group: "block",
|
|
3307
|
+
code: true,
|
|
3308
|
+
defining: true,
|
|
3309
|
+
addAttributes() {
|
|
3310
|
+
return {
|
|
3311
|
+
language: {
|
|
3312
|
+
default: this.options.defaultLanguage,
|
|
3313
|
+
parseHTML: (element) => {
|
|
3314
|
+
var _a;
|
|
3315
|
+
const { languageClassPrefix } = this.options;
|
|
3316
|
+
const classNames = [...((_a = element.firstElementChild) == null ? void 0 : _a.classList) || []];
|
|
3317
|
+
const languages = classNames.filter((className) => className.startsWith(languageClassPrefix)).map((className) => className.replace(languageClassPrefix, ""));
|
|
3318
|
+
const language = languages[0];
|
|
3319
|
+
if (!language) {
|
|
3320
|
+
return null;
|
|
3321
|
+
}
|
|
3322
|
+
return language;
|
|
3323
|
+
},
|
|
3324
|
+
rendered: false
|
|
3325
|
+
}
|
|
3326
|
+
};
|
|
3327
|
+
},
|
|
3328
|
+
parseHTML() {
|
|
3329
|
+
return [
|
|
3330
|
+
{
|
|
3331
|
+
tag: "pre",
|
|
3332
|
+
preserveWhitespace: "full"
|
|
3333
|
+
}
|
|
3334
|
+
];
|
|
3335
|
+
},
|
|
3336
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
3337
|
+
return [
|
|
3338
|
+
"pre",
|
|
3339
|
+
index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
|
3340
|
+
[
|
|
3341
|
+
"code",
|
|
3342
|
+
{
|
|
3343
|
+
class: node.attrs.language ? this.options.languageClassPrefix + node.attrs.language : null
|
|
3344
|
+
},
|
|
3345
|
+
0
|
|
3346
|
+
]
|
|
3347
|
+
];
|
|
3348
|
+
},
|
|
3349
|
+
addCommands() {
|
|
3350
|
+
return {
|
|
3351
|
+
setCodeBlock: (attributes) => ({ commands }) => {
|
|
3352
|
+
return commands.setNode(this.name, attributes);
|
|
3353
|
+
},
|
|
3354
|
+
toggleCodeBlock: (attributes) => ({ commands }) => {
|
|
3355
|
+
return commands.toggleNode(this.name, "paragraph", attributes);
|
|
3356
|
+
}
|
|
3357
|
+
};
|
|
3358
|
+
},
|
|
3359
|
+
addKeyboardShortcuts() {
|
|
3360
|
+
return {
|
|
3361
|
+
"Mod-Alt-c": () => this.editor.commands.toggleCodeBlock(),
|
|
3362
|
+
// remove code block when at start of document or code block is empty
|
|
3363
|
+
Backspace: () => {
|
|
3364
|
+
const { empty, $anchor } = this.editor.state.selection;
|
|
3365
|
+
const isAtStart = $anchor.pos === 1;
|
|
3366
|
+
if (!empty || $anchor.parent.type.name !== this.name) {
|
|
3367
|
+
return false;
|
|
3368
|
+
}
|
|
3369
|
+
if (isAtStart || !$anchor.parent.textContent.length) {
|
|
3370
|
+
return this.editor.commands.clearNodes();
|
|
3371
|
+
}
|
|
3372
|
+
return false;
|
|
3373
|
+
},
|
|
3374
|
+
// exit node on triple enter
|
|
3375
|
+
Enter: ({ editor }) => {
|
|
3376
|
+
if (!this.options.exitOnTripleEnter) {
|
|
3377
|
+
return false;
|
|
3378
|
+
}
|
|
3379
|
+
const { state } = editor;
|
|
3380
|
+
const { selection } = state;
|
|
3381
|
+
const { $from, empty } = selection;
|
|
3382
|
+
if (!empty || $from.parent.type !== this.type) {
|
|
3383
|
+
return false;
|
|
3384
|
+
}
|
|
3385
|
+
const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
|
|
3386
|
+
const endsWithDoubleNewline = $from.parent.textContent.endsWith("\n\n");
|
|
3387
|
+
if (!isAtEnd || !endsWithDoubleNewline) {
|
|
3388
|
+
return false;
|
|
3389
|
+
}
|
|
3390
|
+
return editor.chain().command(({ tr: tr2 }) => {
|
|
3391
|
+
tr2.delete($from.pos - 2, $from.pos);
|
|
3392
|
+
return true;
|
|
3393
|
+
}).exitCode().run();
|
|
3394
|
+
},
|
|
3395
|
+
// exit node on arrow down
|
|
3396
|
+
ArrowDown: ({ editor }) => {
|
|
3397
|
+
if (!this.options.exitOnArrowDown) {
|
|
3398
|
+
return false;
|
|
3399
|
+
}
|
|
3400
|
+
const { state } = editor;
|
|
3401
|
+
const { selection, doc } = state;
|
|
3402
|
+
const { $from, empty } = selection;
|
|
3403
|
+
if (!empty || $from.parent.type !== this.type) {
|
|
3404
|
+
return false;
|
|
3405
|
+
}
|
|
3406
|
+
const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
|
|
3407
|
+
if (!isAtEnd) {
|
|
3408
|
+
return false;
|
|
3409
|
+
}
|
|
3410
|
+
const after = $from.after();
|
|
3411
|
+
if (after === void 0) {
|
|
3412
|
+
return false;
|
|
3413
|
+
}
|
|
3414
|
+
const nodeAfter = doc.nodeAt(after);
|
|
3415
|
+
if (nodeAfter) {
|
|
3416
|
+
return editor.commands.command(({ tr: tr2 }) => {
|
|
3417
|
+
tr2.setSelection(index.Selection.near(doc.resolve(after)));
|
|
3418
|
+
return true;
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3421
|
+
return editor.commands.exitCode();
|
|
3422
|
+
}
|
|
3423
|
+
};
|
|
3424
|
+
},
|
|
3425
|
+
addInputRules() {
|
|
3426
|
+
return [
|
|
3427
|
+
index.textblockTypeInputRule({
|
|
3428
|
+
find: backtickInputRegex,
|
|
3429
|
+
type: this.type,
|
|
3430
|
+
getAttributes: (match) => ({
|
|
3431
|
+
language: match[1]
|
|
3432
|
+
})
|
|
3433
|
+
}),
|
|
3434
|
+
index.textblockTypeInputRule({
|
|
3435
|
+
find: tildeInputRegex,
|
|
3436
|
+
type: this.type,
|
|
3437
|
+
getAttributes: (match) => ({
|
|
3438
|
+
language: match[1]
|
|
3439
|
+
})
|
|
3440
|
+
})
|
|
3441
|
+
];
|
|
3442
|
+
},
|
|
3443
|
+
addProseMirrorPlugins() {
|
|
3444
|
+
return [
|
|
3445
|
+
// this plugin creates a code block for pasted content from VS Code
|
|
3446
|
+
// we can also detect the copied code language
|
|
3447
|
+
new index.Plugin({
|
|
3448
|
+
key: new index.PluginKey("codeBlockVSCodeHandler"),
|
|
3449
|
+
props: {
|
|
3450
|
+
handlePaste: (view, event) => {
|
|
3451
|
+
if (!event.clipboardData) {
|
|
3452
|
+
return false;
|
|
3453
|
+
}
|
|
3454
|
+
if (this.editor.isActive(this.type.name)) {
|
|
3455
|
+
return false;
|
|
3456
|
+
}
|
|
3457
|
+
const text = event.clipboardData.getData("text/plain");
|
|
3458
|
+
const vscode = event.clipboardData.getData("vscode-editor-data");
|
|
3459
|
+
const vscodeData = vscode ? JSON.parse(vscode) : void 0;
|
|
3460
|
+
const language = vscodeData == null ? void 0 : vscodeData.mode;
|
|
3461
|
+
if (!text || !language) {
|
|
3462
|
+
return false;
|
|
3463
|
+
}
|
|
3464
|
+
const { tr: tr2, schema } = view.state;
|
|
3465
|
+
const textNode = schema.text(text.replace(/\r\n?/g, "\n"));
|
|
3466
|
+
tr2.replaceSelectionWith(this.type.create({ language }, textNode));
|
|
3467
|
+
if (tr2.selection.$from.parent.type !== this.type) {
|
|
3468
|
+
tr2.setSelection(index.TextSelection.near(tr2.doc.resolve(Math.max(0, tr2.selection.from - 2))));
|
|
3469
|
+
}
|
|
3470
|
+
tr2.setMeta("paste", true);
|
|
3471
|
+
view.dispatch(tr2);
|
|
3472
|
+
return true;
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
})
|
|
3476
|
+
];
|
|
3477
|
+
}
|
|
3478
|
+
});
|
|
3479
|
+
var Document = index.Node3.create({
|
|
3480
|
+
name: "doc",
|
|
3481
|
+
topNode: true,
|
|
3482
|
+
content: "block+"
|
|
3483
|
+
});
|
|
3484
|
+
var HardBreak = index.Node3.create({
|
|
3485
|
+
name: "hardBreak",
|
|
3486
|
+
addOptions() {
|
|
3487
|
+
return {
|
|
3488
|
+
keepMarks: true,
|
|
3489
|
+
HTMLAttributes: {}
|
|
3490
|
+
};
|
|
3491
|
+
},
|
|
3492
|
+
inline: true,
|
|
3493
|
+
group: "inline",
|
|
3494
|
+
selectable: false,
|
|
3495
|
+
linebreakReplacement: true,
|
|
3496
|
+
parseHTML() {
|
|
3497
|
+
return [{ tag: "br" }];
|
|
3498
|
+
},
|
|
3499
|
+
renderHTML({ HTMLAttributes }) {
|
|
3500
|
+
return ["br", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
|
3501
|
+
},
|
|
3502
|
+
renderText() {
|
|
3503
|
+
return "\n";
|
|
3504
|
+
},
|
|
3505
|
+
addCommands() {
|
|
3506
|
+
return {
|
|
3507
|
+
setHardBreak: () => ({ commands, chain, state, editor }) => {
|
|
3508
|
+
return commands.first([
|
|
3509
|
+
() => commands.exitCode(),
|
|
3510
|
+
() => commands.command(() => {
|
|
3511
|
+
const { selection, storedMarks } = state;
|
|
3512
|
+
if (selection.$from.parent.type.spec.isolating) {
|
|
3513
|
+
return false;
|
|
3514
|
+
}
|
|
3515
|
+
const { keepMarks } = this.options;
|
|
3516
|
+
const { splittableMarks } = editor.extensionManager;
|
|
3517
|
+
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
3518
|
+
return chain().insertContent({ type: this.name }).command(({ tr: tr2, dispatch }) => {
|
|
3519
|
+
if (dispatch && marks && keepMarks) {
|
|
3520
|
+
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
3521
|
+
tr2.ensureMarks(filteredMarks);
|
|
3522
|
+
}
|
|
3523
|
+
return true;
|
|
3524
|
+
}).run();
|
|
3525
|
+
})
|
|
3526
|
+
]);
|
|
3527
|
+
}
|
|
3528
|
+
};
|
|
3529
|
+
},
|
|
3530
|
+
addKeyboardShortcuts() {
|
|
3531
|
+
return {
|
|
3532
|
+
"Mod-Enter": () => this.editor.commands.setHardBreak(),
|
|
3533
|
+
"Shift-Enter": () => this.editor.commands.setHardBreak()
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
});
|
|
3537
|
+
var Heading = index.Node3.create({
|
|
3538
|
+
name: "heading",
|
|
3539
|
+
addOptions() {
|
|
3540
|
+
return {
|
|
3541
|
+
levels: [1, 2, 3, 4, 5, 6],
|
|
3542
|
+
HTMLAttributes: {}
|
|
3543
|
+
};
|
|
3544
|
+
},
|
|
3545
|
+
content: "inline*",
|
|
3546
|
+
group: "block",
|
|
3547
|
+
defining: true,
|
|
3548
|
+
addAttributes() {
|
|
3549
|
+
return {
|
|
3550
|
+
level: {
|
|
3551
|
+
default: 1,
|
|
3552
|
+
rendered: false
|
|
3553
|
+
}
|
|
3554
|
+
};
|
|
3555
|
+
},
|
|
3556
|
+
parseHTML() {
|
|
3557
|
+
return this.options.levels.map((level) => ({
|
|
3558
|
+
tag: `h${level}`,
|
|
3559
|
+
attrs: { level }
|
|
3560
|
+
}));
|
|
3561
|
+
},
|
|
3562
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
3563
|
+
const hasLevel = this.options.levels.includes(node.attrs.level);
|
|
3564
|
+
const level = hasLevel ? node.attrs.level : this.options.levels[0];
|
|
3565
|
+
return [`h${level}`, index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
3566
|
+
},
|
|
3567
|
+
addCommands() {
|
|
3568
|
+
return {
|
|
3569
|
+
setHeading: (attributes) => ({ commands }) => {
|
|
3570
|
+
if (!this.options.levels.includes(attributes.level)) {
|
|
3571
|
+
return false;
|
|
3572
|
+
}
|
|
3573
|
+
return commands.setNode(this.name, attributes);
|
|
3574
|
+
},
|
|
3575
|
+
toggleHeading: (attributes) => ({ commands }) => {
|
|
3576
|
+
if (!this.options.levels.includes(attributes.level)) {
|
|
3577
|
+
return false;
|
|
3578
|
+
}
|
|
3579
|
+
return commands.toggleNode(this.name, "paragraph", attributes);
|
|
3580
|
+
}
|
|
3581
|
+
};
|
|
3582
|
+
},
|
|
3583
|
+
addKeyboardShortcuts() {
|
|
3584
|
+
return this.options.levels.reduce(
|
|
3585
|
+
(items, level) => ({
|
|
3586
|
+
...items,
|
|
3587
|
+
...{
|
|
3588
|
+
[`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level })
|
|
3589
|
+
}
|
|
3590
|
+
}),
|
|
3591
|
+
{}
|
|
3592
|
+
);
|
|
3593
|
+
},
|
|
3594
|
+
addInputRules() {
|
|
3595
|
+
return this.options.levels.map((level) => {
|
|
3596
|
+
return index.textblockTypeInputRule({
|
|
3597
|
+
find: new RegExp(`^(#{${Math.min(...this.options.levels)},${level}})\\s$`),
|
|
3598
|
+
type: this.type,
|
|
3599
|
+
getAttributes: {
|
|
3600
|
+
level
|
|
3601
|
+
}
|
|
3602
|
+
});
|
|
3603
|
+
});
|
|
3604
|
+
}
|
|
3605
|
+
});
|
|
3606
|
+
var HorizontalRule = index.Node3.create({
|
|
3607
|
+
name: "horizontalRule",
|
|
3608
|
+
addOptions() {
|
|
3609
|
+
return {
|
|
3610
|
+
HTMLAttributes: {}
|
|
3611
|
+
};
|
|
3612
|
+
},
|
|
3613
|
+
group: "block",
|
|
3614
|
+
parseHTML() {
|
|
3615
|
+
return [{ tag: "hr" }];
|
|
3616
|
+
},
|
|
3617
|
+
renderHTML({ HTMLAttributes }) {
|
|
3618
|
+
return ["hr", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
|
3619
|
+
},
|
|
3620
|
+
addCommands() {
|
|
3621
|
+
return {
|
|
3622
|
+
setHorizontalRule: () => ({ chain, state }) => {
|
|
3623
|
+
if (!index.canInsertNode(state, state.schema.nodes[this.name])) {
|
|
3624
|
+
return false;
|
|
3625
|
+
}
|
|
3626
|
+
const { selection } = state;
|
|
3627
|
+
const { $to: $originTo } = selection;
|
|
3628
|
+
const currentChain = chain();
|
|
3629
|
+
if (index.isNodeSelection(selection)) {
|
|
3630
|
+
currentChain.insertContentAt($originTo.pos, {
|
|
3631
|
+
type: this.name
|
|
3632
|
+
});
|
|
3633
|
+
} else {
|
|
3634
|
+
currentChain.insertContent({ type: this.name });
|
|
3635
|
+
}
|
|
3636
|
+
return currentChain.command(({ tr: tr2, dispatch }) => {
|
|
3637
|
+
var _a;
|
|
3638
|
+
if (dispatch) {
|
|
3639
|
+
const { $to } = tr2.selection;
|
|
3640
|
+
const posAfter = $to.end();
|
|
3641
|
+
if ($to.nodeAfter) {
|
|
3642
|
+
if ($to.nodeAfter.isTextblock) {
|
|
3643
|
+
tr2.setSelection(index.TextSelection.create(tr2.doc, $to.pos + 1));
|
|
3644
|
+
} else if ($to.nodeAfter.isBlock) {
|
|
3645
|
+
tr2.setSelection(index.NodeSelection.create(tr2.doc, $to.pos));
|
|
3646
|
+
} else {
|
|
3647
|
+
tr2.setSelection(index.TextSelection.create(tr2.doc, $to.pos));
|
|
3648
|
+
}
|
|
3649
|
+
} else {
|
|
3650
|
+
const node = (_a = $to.parent.type.contentMatch.defaultType) == null ? void 0 : _a.create();
|
|
3651
|
+
if (node) {
|
|
3652
|
+
tr2.insert(posAfter, node);
|
|
3653
|
+
tr2.setSelection(index.TextSelection.create(tr2.doc, posAfter + 1));
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
tr2.scrollIntoView();
|
|
3657
|
+
}
|
|
3658
|
+
return true;
|
|
3659
|
+
}).run();
|
|
3660
|
+
}
|
|
3661
|
+
};
|
|
3662
|
+
},
|
|
3663
|
+
addInputRules() {
|
|
3664
|
+
return [
|
|
3665
|
+
index.nodeInputRule({
|
|
3666
|
+
find: /^(?:---|—-|___\s|\*\*\*\s)$/,
|
|
3667
|
+
type: this.type
|
|
3668
|
+
})
|
|
3669
|
+
];
|
|
3670
|
+
}
|
|
3671
|
+
});
|
|
3672
|
+
var starInputRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/;
|
|
3673
|
+
var starPasteRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g;
|
|
3674
|
+
var underscoreInputRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/;
|
|
3675
|
+
var underscorePasteRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g;
|
|
3676
|
+
var Italic = index.Mark.create({
|
|
3677
|
+
name: "italic",
|
|
3678
|
+
addOptions() {
|
|
3679
|
+
return {
|
|
3680
|
+
HTMLAttributes: {}
|
|
3681
|
+
};
|
|
3682
|
+
},
|
|
3683
|
+
parseHTML() {
|
|
3684
|
+
return [
|
|
3685
|
+
{
|
|
3686
|
+
tag: "em"
|
|
3687
|
+
},
|
|
3688
|
+
{
|
|
3689
|
+
tag: "i",
|
|
3690
|
+
getAttrs: (node) => node.style.fontStyle !== "normal" && null
|
|
3691
|
+
},
|
|
3692
|
+
{
|
|
3693
|
+
style: "font-style=normal",
|
|
3694
|
+
clearMark: (mark) => mark.type.name === this.name
|
|
3695
|
+
},
|
|
3696
|
+
{
|
|
3697
|
+
style: "font-style=italic"
|
|
3698
|
+
}
|
|
3699
|
+
];
|
|
3700
|
+
},
|
|
3701
|
+
renderHTML({ HTMLAttributes }) {
|
|
3702
|
+
return ["em", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
3703
|
+
},
|
|
3704
|
+
addCommands() {
|
|
3705
|
+
return {
|
|
3706
|
+
setItalic: () => ({ commands }) => {
|
|
3707
|
+
return commands.setMark(this.name);
|
|
3708
|
+
},
|
|
3709
|
+
toggleItalic: () => ({ commands }) => {
|
|
3710
|
+
return commands.toggleMark(this.name);
|
|
3711
|
+
},
|
|
3712
|
+
unsetItalic: () => ({ commands }) => {
|
|
3713
|
+
return commands.unsetMark(this.name);
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3716
|
+
},
|
|
3717
|
+
addKeyboardShortcuts() {
|
|
3718
|
+
return {
|
|
3719
|
+
"Mod-i": () => this.editor.commands.toggleItalic(),
|
|
3720
|
+
"Mod-I": () => this.editor.commands.toggleItalic()
|
|
3721
|
+
};
|
|
3722
|
+
},
|
|
3723
|
+
addInputRules() {
|
|
3724
|
+
return [
|
|
3725
|
+
index.markInputRule({
|
|
3726
|
+
find: starInputRegex,
|
|
3727
|
+
type: this.type
|
|
3728
|
+
}),
|
|
3729
|
+
index.markInputRule({
|
|
3730
|
+
find: underscoreInputRegex,
|
|
3731
|
+
type: this.type
|
|
3732
|
+
})
|
|
3733
|
+
];
|
|
3734
|
+
},
|
|
3735
|
+
addPasteRules() {
|
|
3736
|
+
return [
|
|
3737
|
+
index.markPasteRule({
|
|
3738
|
+
find: starPasteRegex,
|
|
3739
|
+
type: this.type
|
|
3740
|
+
}),
|
|
3741
|
+
index.markPasteRule({
|
|
3742
|
+
find: underscorePasteRegex,
|
|
3743
|
+
type: this.type
|
|
3744
|
+
})
|
|
3745
|
+
];
|
|
3746
|
+
}
|
|
3747
|
+
});
|
|
3748
|
+
var __defProp = Object.defineProperty;
|
|
3749
|
+
var __export = (target, all) => {
|
|
3750
|
+
for (var name in all)
|
|
3751
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
3752
|
+
};
|
|
3753
|
+
var ListItemName = "listItem";
|
|
3754
|
+
var TextStyleName = "textStyle";
|
|
3755
|
+
var bulletListInputRegex = /^\s*([-+*])\s$/;
|
|
3756
|
+
var BulletList = index.Node3.create({
|
|
3757
|
+
name: "bulletList",
|
|
3758
|
+
addOptions() {
|
|
3759
|
+
return {
|
|
3760
|
+
itemTypeName: "listItem",
|
|
3761
|
+
HTMLAttributes: {},
|
|
3762
|
+
keepMarks: false,
|
|
3763
|
+
keepAttributes: false
|
|
3764
|
+
};
|
|
3765
|
+
},
|
|
3766
|
+
group: "block list",
|
|
3767
|
+
content() {
|
|
3768
|
+
return `${this.options.itemTypeName}+`;
|
|
3769
|
+
},
|
|
3770
|
+
parseHTML() {
|
|
3771
|
+
return [{ tag: "ul" }];
|
|
3772
|
+
},
|
|
3773
|
+
renderHTML({ HTMLAttributes }) {
|
|
3774
|
+
return ["ul", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
3775
|
+
},
|
|
3776
|
+
addCommands() {
|
|
3777
|
+
return {
|
|
3778
|
+
toggleBulletList: () => ({ commands, chain }) => {
|
|
3779
|
+
if (this.options.keepAttributes) {
|
|
3780
|
+
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
|
|
3781
|
+
}
|
|
3782
|
+
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
|
3783
|
+
}
|
|
3784
|
+
};
|
|
3785
|
+
},
|
|
3786
|
+
addKeyboardShortcuts() {
|
|
3787
|
+
return {
|
|
3788
|
+
"Mod-Shift-8": () => this.editor.commands.toggleBulletList()
|
|
3789
|
+
};
|
|
3790
|
+
},
|
|
3791
|
+
addInputRules() {
|
|
3792
|
+
let inputRule = index.wrappingInputRule({
|
|
3793
|
+
find: bulletListInputRegex,
|
|
3794
|
+
type: this.type
|
|
3795
|
+
});
|
|
3796
|
+
if (this.options.keepMarks || this.options.keepAttributes) {
|
|
3797
|
+
inputRule = index.wrappingInputRule({
|
|
3798
|
+
find: bulletListInputRegex,
|
|
3799
|
+
type: this.type,
|
|
3800
|
+
keepMarks: this.options.keepMarks,
|
|
3801
|
+
keepAttributes: this.options.keepAttributes,
|
|
3802
|
+
getAttributes: () => {
|
|
3803
|
+
return this.editor.getAttributes(TextStyleName);
|
|
3804
|
+
},
|
|
3805
|
+
editor: this.editor
|
|
3806
|
+
});
|
|
3807
|
+
}
|
|
3808
|
+
return [inputRule];
|
|
3809
|
+
}
|
|
3810
|
+
});
|
|
3811
|
+
var ListItem = index.Node3.create({
|
|
3812
|
+
name: "listItem",
|
|
3813
|
+
addOptions() {
|
|
3814
|
+
return {
|
|
3815
|
+
HTMLAttributes: {},
|
|
3816
|
+
bulletListTypeName: "bulletList",
|
|
3817
|
+
orderedListTypeName: "orderedList"
|
|
3818
|
+
};
|
|
3819
|
+
},
|
|
3820
|
+
content: "paragraph block*",
|
|
3821
|
+
defining: true,
|
|
3822
|
+
parseHTML() {
|
|
3823
|
+
return [
|
|
3824
|
+
{
|
|
3825
|
+
tag: "li"
|
|
3826
|
+
}
|
|
3827
|
+
];
|
|
3828
|
+
},
|
|
3829
|
+
renderHTML({ HTMLAttributes }) {
|
|
3830
|
+
return ["li", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
3831
|
+
},
|
|
3832
|
+
addKeyboardShortcuts() {
|
|
3833
|
+
return {
|
|
3834
|
+
Enter: () => this.editor.commands.splitListItem(this.name),
|
|
3835
|
+
Tab: () => this.editor.commands.sinkListItem(this.name),
|
|
3836
|
+
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
|
3837
|
+
};
|
|
3838
|
+
}
|
|
3839
|
+
});
|
|
3840
|
+
var listHelpers_exports = {};
|
|
3841
|
+
__export(listHelpers_exports, {
|
|
3842
|
+
findListItemPos: () => findListItemPos,
|
|
3843
|
+
getNextListDepth: () => getNextListDepth,
|
|
3844
|
+
handleBackspace: () => handleBackspace,
|
|
3845
|
+
handleDelete: () => handleDelete,
|
|
3846
|
+
hasListBefore: () => hasListBefore,
|
|
3847
|
+
hasListItemAfter: () => hasListItemAfter,
|
|
3848
|
+
hasListItemBefore: () => hasListItemBefore,
|
|
3849
|
+
listItemHasSubList: () => listItemHasSubList,
|
|
3850
|
+
nextListIsDeeper: () => nextListIsDeeper,
|
|
3851
|
+
nextListIsHigher: () => nextListIsHigher
|
|
3852
|
+
});
|
|
3853
|
+
var findListItemPos = (typeOrName, state) => {
|
|
3854
|
+
const { $from } = state.selection;
|
|
3855
|
+
const nodeType = index.getNodeType(typeOrName, state.schema);
|
|
3856
|
+
let currentNode = null;
|
|
3857
|
+
let currentDepth = $from.depth;
|
|
3858
|
+
let currentPos = $from.pos;
|
|
3859
|
+
let targetDepth = null;
|
|
3860
|
+
while (currentDepth > 0 && targetDepth === null) {
|
|
3861
|
+
currentNode = $from.node(currentDepth);
|
|
3862
|
+
if (currentNode.type === nodeType) {
|
|
3863
|
+
targetDepth = currentDepth;
|
|
3864
|
+
} else {
|
|
3865
|
+
currentDepth -= 1;
|
|
3866
|
+
currentPos -= 1;
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
if (targetDepth === null) {
|
|
3870
|
+
return null;
|
|
3871
|
+
}
|
|
3872
|
+
return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
|
|
3873
|
+
};
|
|
3874
|
+
var getNextListDepth = (typeOrName, state) => {
|
|
3875
|
+
const listItemPos = findListItemPos(typeOrName, state);
|
|
3876
|
+
if (!listItemPos) {
|
|
3877
|
+
return false;
|
|
3878
|
+
}
|
|
3879
|
+
const [, depth] = index.getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
|
|
3880
|
+
return depth;
|
|
3881
|
+
};
|
|
3882
|
+
var hasListBefore = (editorState, name, parentListTypes) => {
|
|
3883
|
+
const { $anchor } = editorState.selection;
|
|
3884
|
+
const previousNodePos = Math.max(0, $anchor.pos - 2);
|
|
3885
|
+
const previousNode = editorState.doc.resolve(previousNodePos).node();
|
|
3886
|
+
if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
|
|
3887
|
+
return false;
|
|
3888
|
+
}
|
|
3889
|
+
return true;
|
|
3890
|
+
};
|
|
3891
|
+
var hasListItemBefore = (typeOrName, state) => {
|
|
3892
|
+
var _a;
|
|
3893
|
+
const { $anchor } = state.selection;
|
|
3894
|
+
const $targetPos = state.doc.resolve($anchor.pos - 2);
|
|
3895
|
+
if ($targetPos.index() === 0) {
|
|
3896
|
+
return false;
|
|
3897
|
+
}
|
|
3898
|
+
if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
|
|
3899
|
+
return false;
|
|
3900
|
+
}
|
|
3901
|
+
return true;
|
|
3902
|
+
};
|
|
3903
|
+
var listItemHasSubList = (typeOrName, state, node) => {
|
|
3904
|
+
if (!node) {
|
|
3905
|
+
return false;
|
|
3906
|
+
}
|
|
3907
|
+
const nodeType = index.getNodeType(typeOrName, state.schema);
|
|
3908
|
+
let hasSubList = false;
|
|
3909
|
+
node.descendants((child) => {
|
|
3910
|
+
if (child.type === nodeType) {
|
|
3911
|
+
hasSubList = true;
|
|
3912
|
+
}
|
|
3913
|
+
});
|
|
3914
|
+
return hasSubList;
|
|
3915
|
+
};
|
|
3916
|
+
var handleBackspace = (editor, name, parentListTypes) => {
|
|
3917
|
+
if (editor.commands.undoInputRule()) {
|
|
3918
|
+
return true;
|
|
3919
|
+
}
|
|
3920
|
+
if (editor.state.selection.from !== editor.state.selection.to) {
|
|
3921
|
+
return false;
|
|
3922
|
+
}
|
|
3923
|
+
if (!index.isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
|
|
3924
|
+
const { $anchor } = editor.state.selection;
|
|
3925
|
+
const $listPos = editor.state.doc.resolve($anchor.before() - 1);
|
|
3926
|
+
const listDescendants = [];
|
|
3927
|
+
$listPos.node().descendants((node, pos) => {
|
|
3928
|
+
if (node.type.name === name) {
|
|
3929
|
+
listDescendants.push({ node, pos });
|
|
3930
|
+
}
|
|
3931
|
+
});
|
|
3932
|
+
const lastItem = listDescendants.at(-1);
|
|
3933
|
+
if (!lastItem) {
|
|
3934
|
+
return false;
|
|
3935
|
+
}
|
|
3936
|
+
const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
|
|
3937
|
+
return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run();
|
|
3938
|
+
}
|
|
3939
|
+
if (!index.isNodeActive(editor.state, name)) {
|
|
3940
|
+
return false;
|
|
3941
|
+
}
|
|
3942
|
+
if (!index.isAtStartOfNode(editor.state)) {
|
|
3943
|
+
return false;
|
|
3944
|
+
}
|
|
3945
|
+
const listItemPos = findListItemPos(name, editor.state);
|
|
3946
|
+
if (!listItemPos) {
|
|
3947
|
+
return false;
|
|
3948
|
+
}
|
|
3949
|
+
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
|
|
3950
|
+
const prevNode = $prev.node(listItemPos.depth);
|
|
3951
|
+
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
|
|
3952
|
+
if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
|
|
3953
|
+
return editor.commands.joinItemBackward();
|
|
3954
|
+
}
|
|
3955
|
+
return editor.chain().liftListItem(name).run();
|
|
3956
|
+
};
|
|
3957
|
+
var nextListIsDeeper = (typeOrName, state) => {
|
|
3958
|
+
const listDepth = getNextListDepth(typeOrName, state);
|
|
3959
|
+
const listItemPos = findListItemPos(typeOrName, state);
|
|
3960
|
+
if (!listItemPos || !listDepth) {
|
|
3961
|
+
return false;
|
|
3962
|
+
}
|
|
3963
|
+
if (listDepth > listItemPos.depth) {
|
|
3964
|
+
return true;
|
|
3965
|
+
}
|
|
3966
|
+
return false;
|
|
3967
|
+
};
|
|
3968
|
+
var nextListIsHigher = (typeOrName, state) => {
|
|
3969
|
+
const listDepth = getNextListDepth(typeOrName, state);
|
|
3970
|
+
const listItemPos = findListItemPos(typeOrName, state);
|
|
3971
|
+
if (!listItemPos || !listDepth) {
|
|
3972
|
+
return false;
|
|
3973
|
+
}
|
|
3974
|
+
if (listDepth < listItemPos.depth) {
|
|
3975
|
+
return true;
|
|
3976
|
+
}
|
|
3977
|
+
return false;
|
|
3978
|
+
};
|
|
3979
|
+
var handleDelete = (editor, name) => {
|
|
3980
|
+
if (!index.isNodeActive(editor.state, name)) {
|
|
3981
|
+
return false;
|
|
3982
|
+
}
|
|
3983
|
+
if (!index.isAtEndOfNode(editor.state, name)) {
|
|
3984
|
+
return false;
|
|
3985
|
+
}
|
|
3986
|
+
const { selection } = editor.state;
|
|
3987
|
+
const { $from, $to } = selection;
|
|
3988
|
+
if (!selection.empty && $from.sameParent($to)) {
|
|
3989
|
+
return false;
|
|
3990
|
+
}
|
|
3991
|
+
if (nextListIsDeeper(name, editor.state)) {
|
|
3992
|
+
return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run();
|
|
3993
|
+
}
|
|
3994
|
+
if (nextListIsHigher(name, editor.state)) {
|
|
3995
|
+
return editor.chain().joinForward().joinBackward().run();
|
|
3996
|
+
}
|
|
3997
|
+
return editor.commands.joinItemForward();
|
|
3998
|
+
};
|
|
3999
|
+
var hasListItemAfter = (typeOrName, state) => {
|
|
4000
|
+
var _a;
|
|
4001
|
+
const { $anchor } = state.selection;
|
|
4002
|
+
const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
|
|
4003
|
+
if ($targetPos.index() === $targetPos.parent.childCount - 1) {
|
|
4004
|
+
return false;
|
|
4005
|
+
}
|
|
4006
|
+
if (((_a = $targetPos.nodeAfter) == null ? void 0 : _a.type.name) !== typeOrName) {
|
|
4007
|
+
return false;
|
|
4008
|
+
}
|
|
4009
|
+
return true;
|
|
4010
|
+
};
|
|
4011
|
+
var ListKeymap = index.Extension.create({
|
|
4012
|
+
name: "listKeymap",
|
|
4013
|
+
addOptions() {
|
|
4014
|
+
return {
|
|
4015
|
+
listTypes: [
|
|
4016
|
+
{
|
|
4017
|
+
itemName: "listItem",
|
|
4018
|
+
wrapperNames: ["bulletList", "orderedList"]
|
|
4019
|
+
},
|
|
4020
|
+
{
|
|
4021
|
+
itemName: "taskItem",
|
|
4022
|
+
wrapperNames: ["taskList"]
|
|
4023
|
+
}
|
|
4024
|
+
]
|
|
4025
|
+
};
|
|
4026
|
+
},
|
|
4027
|
+
addKeyboardShortcuts() {
|
|
4028
|
+
return {
|
|
4029
|
+
Delete: ({ editor }) => {
|
|
4030
|
+
let handled = false;
|
|
4031
|
+
this.options.listTypes.forEach(({ itemName }) => {
|
|
4032
|
+
if (editor.state.schema.nodes[itemName] === void 0) {
|
|
4033
|
+
return;
|
|
4034
|
+
}
|
|
4035
|
+
if (handleDelete(editor, itemName)) {
|
|
4036
|
+
handled = true;
|
|
4037
|
+
}
|
|
4038
|
+
});
|
|
4039
|
+
return handled;
|
|
4040
|
+
},
|
|
4041
|
+
"Mod-Delete": ({ editor }) => {
|
|
4042
|
+
let handled = false;
|
|
4043
|
+
this.options.listTypes.forEach(({ itemName }) => {
|
|
4044
|
+
if (editor.state.schema.nodes[itemName] === void 0) {
|
|
4045
|
+
return;
|
|
4046
|
+
}
|
|
4047
|
+
if (handleDelete(editor, itemName)) {
|
|
4048
|
+
handled = true;
|
|
4049
|
+
}
|
|
4050
|
+
});
|
|
4051
|
+
return handled;
|
|
4052
|
+
},
|
|
4053
|
+
Backspace: ({ editor }) => {
|
|
4054
|
+
let handled = false;
|
|
4055
|
+
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
|
4056
|
+
if (editor.state.schema.nodes[itemName] === void 0) {
|
|
4057
|
+
return;
|
|
4058
|
+
}
|
|
4059
|
+
if (handleBackspace(editor, itemName, wrapperNames)) {
|
|
4060
|
+
handled = true;
|
|
4061
|
+
}
|
|
4062
|
+
});
|
|
4063
|
+
return handled;
|
|
4064
|
+
},
|
|
4065
|
+
"Mod-Backspace": ({ editor }) => {
|
|
4066
|
+
let handled = false;
|
|
4067
|
+
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
|
|
4068
|
+
if (editor.state.schema.nodes[itemName] === void 0) {
|
|
4069
|
+
return;
|
|
4070
|
+
}
|
|
4071
|
+
if (handleBackspace(editor, itemName, wrapperNames)) {
|
|
4072
|
+
handled = true;
|
|
4073
|
+
}
|
|
4074
|
+
});
|
|
4075
|
+
return handled;
|
|
4076
|
+
}
|
|
4077
|
+
};
|
|
4078
|
+
}
|
|
4079
|
+
});
|
|
4080
|
+
var ListItemName2 = "listItem";
|
|
4081
|
+
var TextStyleName2 = "textStyle";
|
|
4082
|
+
var orderedListInputRegex = /^(\d+)\.\s$/;
|
|
4083
|
+
var OrderedList = index.Node3.create({
|
|
4084
|
+
name: "orderedList",
|
|
4085
|
+
addOptions() {
|
|
4086
|
+
return {
|
|
4087
|
+
itemTypeName: "listItem",
|
|
4088
|
+
HTMLAttributes: {},
|
|
4089
|
+
keepMarks: false,
|
|
4090
|
+
keepAttributes: false
|
|
4091
|
+
};
|
|
4092
|
+
},
|
|
4093
|
+
group: "block list",
|
|
4094
|
+
content() {
|
|
4095
|
+
return `${this.options.itemTypeName}+`;
|
|
4096
|
+
},
|
|
4097
|
+
addAttributes() {
|
|
4098
|
+
return {
|
|
4099
|
+
start: {
|
|
4100
|
+
default: 1,
|
|
4101
|
+
parseHTML: (element) => {
|
|
4102
|
+
return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
|
|
4103
|
+
}
|
|
4104
|
+
},
|
|
4105
|
+
type: {
|
|
4106
|
+
default: null,
|
|
4107
|
+
parseHTML: (element) => element.getAttribute("type")
|
|
4108
|
+
}
|
|
4109
|
+
};
|
|
4110
|
+
},
|
|
4111
|
+
parseHTML() {
|
|
4112
|
+
return [
|
|
4113
|
+
{
|
|
4114
|
+
tag: "ol"
|
|
4115
|
+
}
|
|
4116
|
+
];
|
|
4117
|
+
},
|
|
4118
|
+
renderHTML({ HTMLAttributes }) {
|
|
4119
|
+
const { start, ...attributesWithoutStart } = HTMLAttributes;
|
|
4120
|
+
return start === 1 ? ["ol", index.mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
4121
|
+
},
|
|
4122
|
+
addCommands() {
|
|
4123
|
+
return {
|
|
4124
|
+
toggleOrderedList: () => ({ commands, chain }) => {
|
|
4125
|
+
if (this.options.keepAttributes) {
|
|
4126
|
+
return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName2, this.editor.getAttributes(TextStyleName2)).run();
|
|
4127
|
+
}
|
|
4128
|
+
return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
|
|
4129
|
+
}
|
|
4130
|
+
};
|
|
4131
|
+
},
|
|
4132
|
+
addKeyboardShortcuts() {
|
|
4133
|
+
return {
|
|
4134
|
+
"Mod-Shift-7": () => this.editor.commands.toggleOrderedList()
|
|
4135
|
+
};
|
|
4136
|
+
},
|
|
4137
|
+
addInputRules() {
|
|
4138
|
+
let inputRule = index.wrappingInputRule({
|
|
4139
|
+
find: orderedListInputRegex,
|
|
4140
|
+
type: this.type,
|
|
4141
|
+
getAttributes: (match) => ({ start: +match[1] }),
|
|
4142
|
+
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1]
|
|
4143
|
+
});
|
|
4144
|
+
if (this.options.keepMarks || this.options.keepAttributes) {
|
|
4145
|
+
inputRule = index.wrappingInputRule({
|
|
4146
|
+
find: orderedListInputRegex,
|
|
4147
|
+
type: this.type,
|
|
4148
|
+
keepMarks: this.options.keepMarks,
|
|
4149
|
+
keepAttributes: this.options.keepAttributes,
|
|
4150
|
+
getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName2) }),
|
|
4151
|
+
joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
|
|
4152
|
+
editor: this.editor
|
|
4153
|
+
});
|
|
4154
|
+
}
|
|
4155
|
+
return [inputRule];
|
|
4156
|
+
}
|
|
4157
|
+
});
|
|
4158
|
+
var inputRegex$1 = /^\s*(\[([( |x])?\])\s$/;
|
|
4159
|
+
var TaskItem = index.Node3.create({
|
|
4160
|
+
name: "taskItem",
|
|
4161
|
+
addOptions() {
|
|
4162
|
+
return {
|
|
4163
|
+
nested: false,
|
|
4164
|
+
HTMLAttributes: {},
|
|
4165
|
+
taskListTypeName: "taskList",
|
|
4166
|
+
a11y: void 0
|
|
4167
|
+
};
|
|
4168
|
+
},
|
|
4169
|
+
content() {
|
|
4170
|
+
return this.options.nested ? "paragraph block*" : "paragraph+";
|
|
4171
|
+
},
|
|
4172
|
+
defining: true,
|
|
4173
|
+
addAttributes() {
|
|
4174
|
+
return {
|
|
4175
|
+
checked: {
|
|
4176
|
+
default: false,
|
|
4177
|
+
keepOnSplit: false,
|
|
4178
|
+
parseHTML: (element) => {
|
|
4179
|
+
const dataChecked = element.getAttribute("data-checked");
|
|
4180
|
+
return dataChecked === "" || dataChecked === "true";
|
|
4181
|
+
},
|
|
4182
|
+
renderHTML: (attributes) => ({
|
|
4183
|
+
"data-checked": attributes.checked
|
|
4184
|
+
})
|
|
4185
|
+
}
|
|
4186
|
+
};
|
|
4187
|
+
},
|
|
4188
|
+
parseHTML() {
|
|
4189
|
+
return [
|
|
4190
|
+
{
|
|
4191
|
+
tag: `li[data-type="${this.name}"]`,
|
|
4192
|
+
priority: 51
|
|
4193
|
+
}
|
|
4194
|
+
];
|
|
4195
|
+
},
|
|
4196
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
4197
|
+
return [
|
|
4198
|
+
"li",
|
|
4199
|
+
index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
|
4200
|
+
"data-type": this.name
|
|
4201
|
+
}),
|
|
4202
|
+
[
|
|
4203
|
+
"label",
|
|
4204
|
+
[
|
|
4205
|
+
"input",
|
|
4206
|
+
{
|
|
4207
|
+
type: "checkbox",
|
|
4208
|
+
checked: node.attrs.checked ? "checked" : null
|
|
4209
|
+
}
|
|
4210
|
+
],
|
|
4211
|
+
["span"]
|
|
4212
|
+
],
|
|
4213
|
+
["div", 0]
|
|
4214
|
+
];
|
|
4215
|
+
},
|
|
4216
|
+
addKeyboardShortcuts() {
|
|
4217
|
+
const shortcuts = {
|
|
4218
|
+
Enter: () => this.editor.commands.splitListItem(this.name),
|
|
4219
|
+
"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
|
|
4220
|
+
};
|
|
4221
|
+
if (!this.options.nested) {
|
|
4222
|
+
return shortcuts;
|
|
4223
|
+
}
|
|
4224
|
+
return {
|
|
4225
|
+
...shortcuts,
|
|
4226
|
+
Tab: () => this.editor.commands.sinkListItem(this.name)
|
|
4227
|
+
};
|
|
4228
|
+
},
|
|
4229
|
+
addNodeView() {
|
|
4230
|
+
return ({ node, HTMLAttributes, getPos, editor }) => {
|
|
4231
|
+
const listItem = document.createElement("li");
|
|
4232
|
+
const checkboxWrapper = document.createElement("label");
|
|
4233
|
+
const checkboxStyler = document.createElement("span");
|
|
4234
|
+
const checkbox = document.createElement("input");
|
|
4235
|
+
const content = document.createElement("div");
|
|
4236
|
+
const updateA11Y = () => {
|
|
4237
|
+
var _a, _b;
|
|
4238
|
+
checkbox.ariaLabel = ((_b = (_a = this.options.a11y) == null ? void 0 : _a.checkboxLabel) == null ? void 0 : _b.call(_a, node, checkbox.checked)) || `Task item checkbox for ${node.textContent || "empty task item"}`;
|
|
4239
|
+
};
|
|
4240
|
+
updateA11Y();
|
|
4241
|
+
checkboxWrapper.contentEditable = "false";
|
|
4242
|
+
checkbox.type = "checkbox";
|
|
4243
|
+
checkbox.addEventListener("mousedown", (event) => event.preventDefault());
|
|
4244
|
+
checkbox.addEventListener("change", (event) => {
|
|
4245
|
+
if (!editor.isEditable && !this.options.onReadOnlyChecked) {
|
|
4246
|
+
checkbox.checked = !checkbox.checked;
|
|
4247
|
+
return;
|
|
4248
|
+
}
|
|
4249
|
+
const { checked } = event.target;
|
|
4250
|
+
if (editor.isEditable && typeof getPos === "function") {
|
|
4251
|
+
editor.chain().focus(void 0, { scrollIntoView: false }).command(({ tr: tr2 }) => {
|
|
4252
|
+
const position = getPos();
|
|
4253
|
+
if (typeof position !== "number") {
|
|
4254
|
+
return false;
|
|
4255
|
+
}
|
|
4256
|
+
const currentNode = tr2.doc.nodeAt(position);
|
|
4257
|
+
tr2.setNodeMarkup(position, void 0, {
|
|
4258
|
+
...currentNode == null ? void 0 : currentNode.attrs,
|
|
4259
|
+
checked
|
|
4260
|
+
});
|
|
4261
|
+
return true;
|
|
4262
|
+
}).run();
|
|
4263
|
+
}
|
|
4264
|
+
if (!editor.isEditable && this.options.onReadOnlyChecked) {
|
|
4265
|
+
if (!this.options.onReadOnlyChecked(node, checked)) {
|
|
4266
|
+
checkbox.checked = !checkbox.checked;
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
});
|
|
4270
|
+
Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
|
|
4271
|
+
listItem.setAttribute(key, value);
|
|
4272
|
+
});
|
|
4273
|
+
listItem.dataset.checked = node.attrs.checked;
|
|
4274
|
+
checkbox.checked = node.attrs.checked;
|
|
4275
|
+
checkboxWrapper.append(checkbox, checkboxStyler);
|
|
4276
|
+
listItem.append(checkboxWrapper, content);
|
|
4277
|
+
Object.entries(HTMLAttributes).forEach(([key, value]) => {
|
|
4278
|
+
listItem.setAttribute(key, value);
|
|
4279
|
+
});
|
|
4280
|
+
return {
|
|
4281
|
+
dom: listItem,
|
|
4282
|
+
contentDOM: content,
|
|
4283
|
+
update: (updatedNode) => {
|
|
4284
|
+
if (updatedNode.type !== this.type) {
|
|
4285
|
+
return false;
|
|
4286
|
+
}
|
|
4287
|
+
listItem.dataset.checked = updatedNode.attrs.checked;
|
|
4288
|
+
checkbox.checked = updatedNode.attrs.checked;
|
|
4289
|
+
updateA11Y();
|
|
4290
|
+
return true;
|
|
4291
|
+
}
|
|
4292
|
+
};
|
|
4293
|
+
};
|
|
4294
|
+
},
|
|
4295
|
+
addInputRules() {
|
|
4296
|
+
return [
|
|
4297
|
+
index.wrappingInputRule({
|
|
4298
|
+
find: inputRegex$1,
|
|
4299
|
+
type: this.type,
|
|
4300
|
+
getAttributes: (match) => ({
|
|
4301
|
+
checked: match[match.length - 1] === "x"
|
|
4302
|
+
})
|
|
4303
|
+
})
|
|
4304
|
+
];
|
|
4305
|
+
}
|
|
4306
|
+
});
|
|
4307
|
+
var TaskList = index.Node3.create({
|
|
4308
|
+
name: "taskList",
|
|
4309
|
+
addOptions() {
|
|
4310
|
+
return {
|
|
4311
|
+
itemTypeName: "taskItem",
|
|
4312
|
+
HTMLAttributes: {}
|
|
4313
|
+
};
|
|
4314
|
+
},
|
|
4315
|
+
group: "block list",
|
|
4316
|
+
content() {
|
|
4317
|
+
return `${this.options.itemTypeName}+`;
|
|
4318
|
+
},
|
|
4319
|
+
parseHTML() {
|
|
4320
|
+
return [
|
|
4321
|
+
{
|
|
4322
|
+
tag: `ul[data-type="${this.name}"]`,
|
|
4323
|
+
priority: 51
|
|
4324
|
+
}
|
|
4325
|
+
];
|
|
4326
|
+
},
|
|
4327
|
+
renderHTML({ HTMLAttributes }) {
|
|
4328
|
+
return ["ul", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), 0];
|
|
4329
|
+
},
|
|
4330
|
+
addCommands() {
|
|
4331
|
+
return {
|
|
4332
|
+
toggleTaskList: () => ({ commands }) => {
|
|
4333
|
+
return commands.toggleList(this.name, this.options.itemTypeName);
|
|
4334
|
+
}
|
|
4335
|
+
};
|
|
4336
|
+
},
|
|
4337
|
+
addKeyboardShortcuts() {
|
|
4338
|
+
return {
|
|
4339
|
+
"Mod-Shift-9": () => this.editor.commands.toggleTaskList()
|
|
4340
|
+
};
|
|
4341
|
+
}
|
|
4342
|
+
});
|
|
4343
|
+
index.Extension.create({
|
|
4344
|
+
name: "listKit",
|
|
4345
|
+
addExtensions() {
|
|
4346
|
+
const extensions = [];
|
|
4347
|
+
if (this.options.bulletList !== false) {
|
|
4348
|
+
extensions.push(BulletList.configure(this.options.bulletList));
|
|
4349
|
+
}
|
|
4350
|
+
if (this.options.listItem !== false) {
|
|
4351
|
+
extensions.push(ListItem.configure(this.options.listItem));
|
|
4352
|
+
}
|
|
4353
|
+
if (this.options.listKeymap !== false) {
|
|
4354
|
+
extensions.push(ListKeymap.configure(this.options.listKeymap));
|
|
4355
|
+
}
|
|
4356
|
+
if (this.options.orderedList !== false) {
|
|
4357
|
+
extensions.push(OrderedList.configure(this.options.orderedList));
|
|
4358
|
+
}
|
|
4359
|
+
if (this.options.taskItem !== false) {
|
|
4360
|
+
extensions.push(TaskItem.configure(this.options.taskItem));
|
|
4361
|
+
}
|
|
4362
|
+
if (this.options.taskList !== false) {
|
|
4363
|
+
extensions.push(TaskList.configure(this.options.taskList));
|
|
4364
|
+
}
|
|
4365
|
+
return extensions;
|
|
4366
|
+
}
|
|
4367
|
+
});
|
|
4368
|
+
var Paragraph = index.Node3.create({
|
|
4369
|
+
name: "paragraph",
|
|
4370
|
+
priority: 1e3,
|
|
4371
|
+
addOptions() {
|
|
4372
|
+
return {
|
|
4373
|
+
HTMLAttributes: {}
|
|
4374
|
+
};
|
|
4375
|
+
},
|
|
4376
|
+
group: "block",
|
|
4377
|
+
content: "inline*",
|
|
4378
|
+
parseHTML() {
|
|
4379
|
+
return [{ tag: "p" }];
|
|
4380
|
+
},
|
|
4381
|
+
renderHTML({ HTMLAttributes }) {
|
|
4382
|
+
return ["p", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
4383
|
+
},
|
|
4384
|
+
addCommands() {
|
|
4385
|
+
return {
|
|
4386
|
+
setParagraph: () => ({ commands }) => {
|
|
4387
|
+
return commands.setNode(this.name);
|
|
4388
|
+
}
|
|
4389
|
+
};
|
|
4390
|
+
},
|
|
4391
|
+
addKeyboardShortcuts() {
|
|
4392
|
+
return {
|
|
4393
|
+
"Mod-Alt-0": () => this.editor.commands.setParagraph()
|
|
4394
|
+
};
|
|
4395
|
+
}
|
|
4396
|
+
});
|
|
4397
|
+
var inputRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/;
|
|
4398
|
+
var pasteRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g;
|
|
4399
|
+
var Strike = index.Mark.create({
|
|
4400
|
+
name: "strike",
|
|
4401
|
+
addOptions() {
|
|
4402
|
+
return {
|
|
4403
|
+
HTMLAttributes: {}
|
|
4404
|
+
};
|
|
4405
|
+
},
|
|
4406
|
+
parseHTML() {
|
|
4407
|
+
return [
|
|
4408
|
+
{
|
|
4409
|
+
tag: "s"
|
|
4410
|
+
},
|
|
4411
|
+
{
|
|
4412
|
+
tag: "del"
|
|
4413
|
+
},
|
|
4414
|
+
{
|
|
4415
|
+
tag: "strike"
|
|
4416
|
+
},
|
|
4417
|
+
{
|
|
4418
|
+
style: "text-decoration",
|
|
4419
|
+
consuming: false,
|
|
4420
|
+
getAttrs: (style) => style.includes("line-through") ? {} : false
|
|
4421
|
+
}
|
|
4422
|
+
];
|
|
4423
|
+
},
|
|
4424
|
+
renderHTML({ HTMLAttributes }) {
|
|
4425
|
+
return ["s", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
4426
|
+
},
|
|
4427
|
+
addCommands() {
|
|
4428
|
+
return {
|
|
4429
|
+
setStrike: () => ({ commands }) => {
|
|
4430
|
+
return commands.setMark(this.name);
|
|
4431
|
+
},
|
|
4432
|
+
toggleStrike: () => ({ commands }) => {
|
|
4433
|
+
return commands.toggleMark(this.name);
|
|
4434
|
+
},
|
|
4435
|
+
unsetStrike: () => ({ commands }) => {
|
|
4436
|
+
return commands.unsetMark(this.name);
|
|
4437
|
+
}
|
|
4438
|
+
};
|
|
4439
|
+
},
|
|
4440
|
+
addKeyboardShortcuts() {
|
|
4441
|
+
return {
|
|
4442
|
+
"Mod-Shift-s": () => this.editor.commands.toggleStrike()
|
|
4443
|
+
};
|
|
4444
|
+
},
|
|
4445
|
+
addInputRules() {
|
|
4446
|
+
return [
|
|
4447
|
+
index.markInputRule({
|
|
4448
|
+
find: inputRegex,
|
|
4449
|
+
type: this.type
|
|
4450
|
+
})
|
|
4451
|
+
];
|
|
4452
|
+
},
|
|
4453
|
+
addPasteRules() {
|
|
4454
|
+
return [
|
|
4455
|
+
index.markPasteRule({
|
|
4456
|
+
find: pasteRegex,
|
|
4457
|
+
type: this.type
|
|
4458
|
+
})
|
|
4459
|
+
];
|
|
4460
|
+
}
|
|
4461
|
+
});
|
|
4462
|
+
var Text = index.Node3.create({
|
|
4463
|
+
name: "text",
|
|
4464
|
+
group: "inline"
|
|
4465
|
+
});
|
|
4466
|
+
var Underline = index.Mark.create({
|
|
4467
|
+
name: "underline",
|
|
4468
|
+
addOptions() {
|
|
4469
|
+
return {
|
|
4470
|
+
HTMLAttributes: {}
|
|
4471
|
+
};
|
|
4472
|
+
},
|
|
4473
|
+
parseHTML() {
|
|
4474
|
+
return [
|
|
4475
|
+
{
|
|
4476
|
+
tag: "u"
|
|
4477
|
+
},
|
|
4478
|
+
{
|
|
4479
|
+
style: "text-decoration",
|
|
4480
|
+
consuming: false,
|
|
4481
|
+
getAttrs: (style) => style.includes("underline") ? {} : false
|
|
4482
|
+
}
|
|
4483
|
+
];
|
|
4484
|
+
},
|
|
4485
|
+
renderHTML({ HTMLAttributes }) {
|
|
4486
|
+
return ["u", index.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
4487
|
+
},
|
|
4488
|
+
addCommands() {
|
|
4489
|
+
return {
|
|
4490
|
+
setUnderline: () => ({ commands }) => {
|
|
4491
|
+
return commands.setMark(this.name);
|
|
4492
|
+
},
|
|
4493
|
+
toggleUnderline: () => ({ commands }) => {
|
|
4494
|
+
return commands.toggleMark(this.name);
|
|
4495
|
+
},
|
|
4496
|
+
unsetUnderline: () => ({ commands }) => {
|
|
4497
|
+
return commands.unsetMark(this.name);
|
|
4498
|
+
}
|
|
4499
|
+
};
|
|
4500
|
+
},
|
|
4501
|
+
addKeyboardShortcuts() {
|
|
4502
|
+
return {
|
|
4503
|
+
"Mod-u": () => this.editor.commands.toggleUnderline(),
|
|
4504
|
+
"Mod-U": () => this.editor.commands.toggleUnderline()
|
|
4505
|
+
};
|
|
4506
|
+
}
|
|
4507
|
+
});
|
|
4508
|
+
var StarterKit = index.Extension.create({
|
|
4509
|
+
name: "starterKit",
|
|
4510
|
+
addExtensions() {
|
|
4511
|
+
var _a, _b, _c, _d;
|
|
4512
|
+
const extensions = [];
|
|
4513
|
+
if (this.options.bold !== false) {
|
|
4514
|
+
extensions.push(Bold.configure(this.options.bold));
|
|
4515
|
+
}
|
|
4516
|
+
if (this.options.blockquote !== false) {
|
|
4517
|
+
extensions.push(Blockquote.configure(this.options.blockquote));
|
|
4518
|
+
}
|
|
4519
|
+
if (this.options.bulletList !== false) {
|
|
4520
|
+
extensions.push(BulletList.configure(this.options.bulletList));
|
|
4521
|
+
}
|
|
4522
|
+
if (this.options.code !== false) {
|
|
4523
|
+
extensions.push(Code.configure(this.options.code));
|
|
4524
|
+
}
|
|
4525
|
+
if (this.options.codeBlock !== false) {
|
|
4526
|
+
extensions.push(CodeBlock.configure(this.options.codeBlock));
|
|
4527
|
+
}
|
|
4528
|
+
if (this.options.document !== false) {
|
|
4529
|
+
extensions.push(Document.configure(this.options.document));
|
|
4530
|
+
}
|
|
4531
|
+
if (this.options.dropcursor !== false) {
|
|
4532
|
+
extensions.push(Dropcursor.configure(this.options.dropcursor));
|
|
4533
|
+
}
|
|
4534
|
+
if (this.options.gapcursor !== false) {
|
|
4535
|
+
extensions.push(Gapcursor.configure(this.options.gapcursor));
|
|
4536
|
+
}
|
|
4537
|
+
if (this.options.hardBreak !== false) {
|
|
4538
|
+
extensions.push(HardBreak.configure(this.options.hardBreak));
|
|
4539
|
+
}
|
|
4540
|
+
if (this.options.heading !== false) {
|
|
4541
|
+
extensions.push(Heading.configure(this.options.heading));
|
|
4542
|
+
}
|
|
4543
|
+
if (this.options.undoRedo !== false) {
|
|
4544
|
+
extensions.push(UndoRedo.configure(this.options.undoRedo));
|
|
4545
|
+
}
|
|
4546
|
+
if (this.options.horizontalRule !== false) {
|
|
4547
|
+
extensions.push(HorizontalRule.configure(this.options.horizontalRule));
|
|
4548
|
+
}
|
|
4549
|
+
if (this.options.italic !== false) {
|
|
4550
|
+
extensions.push(Italic.configure(this.options.italic));
|
|
4551
|
+
}
|
|
4552
|
+
if (this.options.listItem !== false) {
|
|
4553
|
+
extensions.push(ListItem.configure(this.options.listItem));
|
|
4554
|
+
}
|
|
4555
|
+
if (this.options.listKeymap !== false) {
|
|
4556
|
+
extensions.push(ListKeymap.configure((_a = this.options) == null ? void 0 : _a.listKeymap));
|
|
4557
|
+
}
|
|
4558
|
+
if (this.options.link !== false) {
|
|
4559
|
+
extensions.push(Link.configure((_b = this.options) == null ? void 0 : _b.link));
|
|
4560
|
+
}
|
|
4561
|
+
if (this.options.orderedList !== false) {
|
|
4562
|
+
extensions.push(OrderedList.configure(this.options.orderedList));
|
|
4563
|
+
}
|
|
4564
|
+
if (this.options.paragraph !== false) {
|
|
4565
|
+
extensions.push(Paragraph.configure(this.options.paragraph));
|
|
4566
|
+
}
|
|
4567
|
+
if (this.options.strike !== false) {
|
|
4568
|
+
extensions.push(Strike.configure(this.options.strike));
|
|
4569
|
+
}
|
|
4570
|
+
if (this.options.text !== false) {
|
|
4571
|
+
extensions.push(Text.configure(this.options.text));
|
|
4572
|
+
}
|
|
4573
|
+
if (this.options.underline !== false) {
|
|
4574
|
+
extensions.push(Underline.configure((_c = this.options) == null ? void 0 : _c.underline));
|
|
4575
|
+
}
|
|
4576
|
+
if (this.options.trailingNode !== false) {
|
|
4577
|
+
extensions.push(TrailingNode.configure((_d = this.options) == null ? void 0 : _d.trailingNode));
|
|
4578
|
+
}
|
|
4579
|
+
return extensions;
|
|
4580
|
+
}
|
|
4581
|
+
});
|
|
4582
|
+
var index_default = StarterKit;
|
|
4583
|
+
function useDebouncedRef(value) {
|
|
4584
|
+
return Mo.customRef((track, trigger) => {
|
|
4585
|
+
return {
|
|
4586
|
+
get() {
|
|
4587
|
+
track();
|
|
4588
|
+
return value;
|
|
4589
|
+
},
|
|
4590
|
+
set(newValue) {
|
|
4591
|
+
value = newValue;
|
|
4592
|
+
requestAnimationFrame(() => {
|
|
4593
|
+
requestAnimationFrame(() => {
|
|
4594
|
+
trigger();
|
|
4595
|
+
});
|
|
4596
|
+
});
|
|
4597
|
+
}
|
|
4598
|
+
};
|
|
4599
|
+
});
|
|
4600
|
+
}
|
|
4601
|
+
var Editor = class extends index.Editor {
|
|
4602
|
+
constructor(options = {}) {
|
|
4603
|
+
super(options);
|
|
4604
|
+
this.contentComponent = null;
|
|
4605
|
+
this.appContext = null;
|
|
4606
|
+
this.reactiveState = useDebouncedRef(this.view.state);
|
|
4607
|
+
this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage);
|
|
4608
|
+
this.on("beforeTransaction", ({ nextState }) => {
|
|
4609
|
+
this.reactiveState.value = nextState;
|
|
4610
|
+
this.reactiveExtensionStorage.value = this.extensionStorage;
|
|
4611
|
+
});
|
|
4612
|
+
return Mo.markRaw(this);
|
|
4613
|
+
}
|
|
4614
|
+
get state() {
|
|
4615
|
+
return this.reactiveState ? this.reactiveState.value : this.view.state;
|
|
4616
|
+
}
|
|
4617
|
+
get storage() {
|
|
4618
|
+
return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage;
|
|
4619
|
+
}
|
|
4620
|
+
/**
|
|
4621
|
+
* Register a ProseMirror plugin.
|
|
4622
|
+
*/
|
|
4623
|
+
registerPlugin(plugin, handlePlugins) {
|
|
4624
|
+
const nextState = super.registerPlugin(plugin, handlePlugins);
|
|
4625
|
+
if (this.reactiveState) {
|
|
4626
|
+
this.reactiveState.value = nextState;
|
|
4627
|
+
}
|
|
4628
|
+
return nextState;
|
|
4629
|
+
}
|
|
4630
|
+
/**
|
|
4631
|
+
* Unregister a ProseMirror plugin.
|
|
4632
|
+
*/
|
|
4633
|
+
unregisterPlugin(nameOrPluginKey) {
|
|
4634
|
+
const nextState = super.unregisterPlugin(nameOrPluginKey);
|
|
4635
|
+
if (this.reactiveState && nextState) {
|
|
4636
|
+
this.reactiveState.value = nextState;
|
|
4637
|
+
}
|
|
4638
|
+
return nextState;
|
|
4639
|
+
}
|
|
4640
|
+
};
|
|
4641
|
+
var EditorContent = Mo.defineComponent({
|
|
4642
|
+
name: "EditorContent",
|
|
4643
|
+
props: {
|
|
4644
|
+
editor: {
|
|
4645
|
+
default: null,
|
|
4646
|
+
type: Object
|
|
4647
|
+
}
|
|
4648
|
+
},
|
|
4649
|
+
setup(props) {
|
|
4650
|
+
const rootEl = Mo.ref();
|
|
4651
|
+
const instance = Mo.getCurrentInstance();
|
|
4652
|
+
Mo.watchEffect(() => {
|
|
4653
|
+
const editor = props.editor;
|
|
4654
|
+
if (editor && editor.options.element && rootEl.value) {
|
|
4655
|
+
Mo.nextTick(() => {
|
|
4656
|
+
var _a;
|
|
4657
|
+
if (!rootEl.value || !((_a = editor.options.element) == null ? void 0 : _a.firstChild)) {
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
const element = Mo.unref(rootEl.value);
|
|
4661
|
+
rootEl.value.append(...editor.options.element.childNodes);
|
|
4662
|
+
editor.contentComponent = instance.ctx._;
|
|
4663
|
+
if (instance) {
|
|
4664
|
+
editor.appContext = {
|
|
4665
|
+
...instance.appContext,
|
|
4666
|
+
// Vue internally uses prototype chain to forward/shadow injects across the entire component chain
|
|
4667
|
+
// so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext
|
|
4668
|
+
// @ts-expect-error forward instance's 'provides' into appContext
|
|
4669
|
+
provides: instance.provides
|
|
4670
|
+
};
|
|
4671
|
+
}
|
|
4672
|
+
editor.setOptions({
|
|
4673
|
+
element
|
|
4674
|
+
});
|
|
4675
|
+
editor.createNodeViews();
|
|
4676
|
+
});
|
|
4677
|
+
}
|
|
4678
|
+
});
|
|
4679
|
+
Mo.onBeforeUnmount(() => {
|
|
4680
|
+
const editor = props.editor;
|
|
4681
|
+
if (!editor) {
|
|
4682
|
+
return;
|
|
4683
|
+
}
|
|
4684
|
+
editor.contentComponent = null;
|
|
4685
|
+
editor.appContext = null;
|
|
4686
|
+
});
|
|
4687
|
+
return { rootEl };
|
|
4688
|
+
},
|
|
4689
|
+
render() {
|
|
4690
|
+
return Mo.h("div", {
|
|
4691
|
+
ref: (el) => {
|
|
4692
|
+
this.rootEl = el;
|
|
4693
|
+
}
|
|
4694
|
+
});
|
|
4695
|
+
}
|
|
4696
|
+
});
|
|
4697
|
+
Mo.defineComponent({
|
|
4698
|
+
name: "NodeViewContent",
|
|
4699
|
+
props: {
|
|
4700
|
+
as: {
|
|
4701
|
+
type: String,
|
|
4702
|
+
default: "div"
|
|
4703
|
+
}
|
|
4704
|
+
},
|
|
4705
|
+
render() {
|
|
4706
|
+
return Mo.h(this.as, {
|
|
4707
|
+
style: {
|
|
4708
|
+
whiteSpace: "pre-wrap"
|
|
4709
|
+
},
|
|
4710
|
+
"data-node-view-content": ""
|
|
4711
|
+
});
|
|
4712
|
+
}
|
|
4713
|
+
});
|
|
4714
|
+
Mo.defineComponent({
|
|
4715
|
+
name: "NodeViewWrapper",
|
|
4716
|
+
props: {
|
|
4717
|
+
as: {
|
|
4718
|
+
type: String,
|
|
4719
|
+
default: "div"
|
|
4720
|
+
}
|
|
4721
|
+
},
|
|
4722
|
+
inject: ["onDragStart", "decorationClasses"],
|
|
4723
|
+
render() {
|
|
4724
|
+
var _a, _b;
|
|
4725
|
+
return Mo.h(
|
|
4726
|
+
this.as,
|
|
4727
|
+
{
|
|
4728
|
+
// @ts-ignore
|
|
4729
|
+
class: this.decorationClasses,
|
|
4730
|
+
style: {
|
|
4731
|
+
whiteSpace: "normal"
|
|
4732
|
+
},
|
|
4733
|
+
"data-node-view-wrapper": "",
|
|
4734
|
+
// @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)
|
|
4735
|
+
onDragstart: this.onDragStart
|
|
4736
|
+
},
|
|
4737
|
+
(_b = (_a = this.$slots).default) == null ? void 0 : _b.call(_a)
|
|
4738
|
+
);
|
|
4739
|
+
}
|
|
4740
|
+
});
|
|
4741
|
+
Mo.defineComponent({
|
|
4742
|
+
name: "MarkViewContent",
|
|
4743
|
+
props: {
|
|
4744
|
+
as: {
|
|
4745
|
+
type: String,
|
|
4746
|
+
default: "span"
|
|
4747
|
+
}
|
|
4748
|
+
},
|
|
4749
|
+
render() {
|
|
4750
|
+
return Mo.h(this.as, {
|
|
4751
|
+
style: {
|
|
4752
|
+
whiteSpace: "inherit"
|
|
4753
|
+
},
|
|
4754
|
+
"data-mark-view-content": ""
|
|
4755
|
+
});
|
|
4756
|
+
}
|
|
4757
|
+
});
|
|
4758
|
+
const _hoisted_1 = {
|
|
4759
|
+
key: 0,
|
|
4760
|
+
class: "celeste-rich-editor"
|
|
4761
|
+
};
|
|
4762
|
+
const _hoisted_2 = { class: "toolbar" };
|
|
4763
|
+
const _hoisted_3 = { class: "select-menu-wrapper" };
|
|
4764
|
+
const _hoisted_4 = { key: 2 };
|
|
4765
|
+
const _hoisted_5 = {
|
|
4766
|
+
key: 2,
|
|
4767
|
+
class: "divider"
|
|
4768
|
+
};
|
|
4769
|
+
const _hoisted_6 = {
|
|
4770
|
+
key: 0,
|
|
4771
|
+
class: "extra-settings-wrapper"
|
|
4772
|
+
};
|
|
4773
|
+
const _hoisted_7 = { class: "text-field" };
|
|
4774
|
+
const _sfc_main = /* @__PURE__ */ Mo.defineComponent({
|
|
4775
|
+
__name: "rich-editor",
|
|
4776
|
+
props: {
|
|
4777
|
+
modelValue: {
|
|
4778
|
+
type: String,
|
|
4779
|
+
default: ""
|
|
4780
|
+
},
|
|
4781
|
+
placeholder: {
|
|
4782
|
+
type: String,
|
|
4783
|
+
default: ""
|
|
4784
|
+
},
|
|
4785
|
+
customToolbar: {
|
|
4786
|
+
type: Array,
|
|
4787
|
+
default: () => []
|
|
4788
|
+
},
|
|
4789
|
+
maxLimit: {
|
|
4790
|
+
type: Number,
|
|
4791
|
+
default: null
|
|
4792
|
+
},
|
|
4793
|
+
showExtraSettings: {
|
|
4794
|
+
type: Boolean,
|
|
4795
|
+
default: true
|
|
4796
|
+
}
|
|
4797
|
+
},
|
|
4798
|
+
emits: ["update:modelValue"],
|
|
4799
|
+
setup(__props, { emit: __emit }) {
|
|
4800
|
+
const props = __props;
|
|
4801
|
+
const emit = __emit;
|
|
4802
|
+
const filteredToolbar = Mo.computed(() => {
|
|
4803
|
+
const customToolbar = props.customToolbar;
|
|
4804
|
+
if (!customToolbar || customToolbar.length === 0) {
|
|
4805
|
+
return config.fullToolbar.value;
|
|
4806
|
+
}
|
|
4807
|
+
const toolbarMap = new Map(
|
|
4808
|
+
config.fullToolbar.value.filter((item) => item.type !== "divider" && "slug" in item).map((item) => [item.slug, item])
|
|
4809
|
+
);
|
|
4810
|
+
return customToolbar.map((key) => {
|
|
4811
|
+
if (key === "divider") {
|
|
4812
|
+
return { type: "divider" };
|
|
4813
|
+
}
|
|
4814
|
+
return toolbarMap.get(key);
|
|
4815
|
+
}).filter((item) => Boolean(item));
|
|
4816
|
+
});
|
|
4817
|
+
const editor = Mo.ref();
|
|
4818
|
+
const showSetLinkFromToolbar = Mo.ref(false);
|
|
4819
|
+
function openLinkBubbleFromToolbar() {
|
|
4820
|
+
showSetLinkFromToolbar.value = true;
|
|
4821
|
+
}
|
|
4822
|
+
const charactersCount = Mo.computed(() => {
|
|
4823
|
+
var _a;
|
|
4824
|
+
return ((_a = editor.value) == null ? void 0 : _a.storage.characterCount.characters()) || 0;
|
|
4825
|
+
});
|
|
4826
|
+
const limitWarning = Mo.computed(() => {
|
|
4827
|
+
const isCloseToMaxCharacter = charactersCount.value >= props.maxLimit - 20;
|
|
4828
|
+
const isMaxCharacter = charactersCount.value === props.maxLimit;
|
|
4829
|
+
if (isCloseToMaxCharacter && !isMaxCharacter) {
|
|
4830
|
+
return "warning";
|
|
4831
|
+
}
|
|
4832
|
+
if (isMaxCharacter) {
|
|
4833
|
+
return "danger";
|
|
4834
|
+
}
|
|
4835
|
+
return "";
|
|
4836
|
+
});
|
|
4837
|
+
Mo.watch(() => props.modelValue, (value) => {
|
|
4838
|
+
var _a, _b;
|
|
4839
|
+
if (((_a = editor.value) == null ? void 0 : _a.getHTML()) === value) {
|
|
4840
|
+
return;
|
|
4841
|
+
}
|
|
4842
|
+
(_b = editor.value) == null ? void 0 : _b.commands.setContent(value);
|
|
4843
|
+
});
|
|
4844
|
+
Mo.onMounted(() => {
|
|
4845
|
+
editor.value = new Editor({
|
|
4846
|
+
content: props.modelValue,
|
|
4847
|
+
extensions: [
|
|
4848
|
+
index_default.configure({
|
|
4849
|
+
link: false
|
|
4850
|
+
}),
|
|
4851
|
+
Placeholder.configure({
|
|
4852
|
+
placeholder: props.placeholder,
|
|
4853
|
+
emptyEditorClass: "is-editor-empty"
|
|
4854
|
+
}),
|
|
4855
|
+
TextStyleKit.configure({
|
|
4856
|
+
color: {
|
|
4857
|
+
types: ["textStyle"]
|
|
4858
|
+
},
|
|
4859
|
+
fontSize: {
|
|
4860
|
+
types: ["textStyle"]
|
|
4861
|
+
}
|
|
4862
|
+
}),
|
|
4863
|
+
index_default$1.configure({
|
|
4864
|
+
types: ["heading", "paragraph"]
|
|
4865
|
+
}),
|
|
4866
|
+
index_default$2.configure({
|
|
4867
|
+
openOnClick: false,
|
|
4868
|
+
autolink: false,
|
|
4869
|
+
HTMLAttributes: {
|
|
4870
|
+
class: "celeste-rich-editor-link",
|
|
4871
|
+
rel: null
|
|
4872
|
+
}
|
|
4873
|
+
}),
|
|
4874
|
+
CharacterCount.configure({
|
|
4875
|
+
limit: props.maxLimit
|
|
4876
|
+
})
|
|
4877
|
+
],
|
|
4878
|
+
onUpdate: () => {
|
|
4879
|
+
var _a;
|
|
4880
|
+
emit("update:modelValue", ((_a = editor.value) == null ? void 0 : _a.getHTML()) || "");
|
|
4881
|
+
}
|
|
4882
|
+
});
|
|
4883
|
+
});
|
|
4884
|
+
Mo.onBeforeUnmount(() => {
|
|
4885
|
+
var _a;
|
|
4886
|
+
(_a = editor.value) == null ? void 0 : _a.destroy();
|
|
4887
|
+
});
|
|
4888
|
+
return (_ctx, _cache) => {
|
|
4889
|
+
return editor.value ? (Mo.openBlock(), Mo.createElementBlock("div", _hoisted_1, [
|
|
4890
|
+
Mo.createElementVNode("div", _hoisted_2, [
|
|
4891
|
+
(Mo.openBlock(true), Mo.createElementBlock(Mo.Fragment, null, Mo.renderList(filteredToolbar.value, (item, parentIndex) => {
|
|
4892
|
+
return Mo.openBlock(), Mo.createElementBlock(Mo.Fragment, { key: parentIndex }, [
|
|
4893
|
+
item.type !== "divider" && !item.children ? (Mo.openBlock(), Mo.createBlock(tooltip, {
|
|
4894
|
+
key: 0,
|
|
4895
|
+
title: item.name,
|
|
4896
|
+
variant: "dark"
|
|
4897
|
+
}, {
|
|
4898
|
+
default: Mo.withCtx(() => [
|
|
4899
|
+
Mo.createVNode(compactButton, {
|
|
4900
|
+
icon: `${item.icon}`,
|
|
4901
|
+
variant: "ghost",
|
|
4902
|
+
class: Mo.normalizeClass({ active: typeof item.active === "string" && editor.value.isActive(item.active) }),
|
|
4903
|
+
onClick: ($event) => Mo.unref(config.onActionClick)(editor.value, item.slug, null, openLinkBubbleFromToolbar)
|
|
4904
|
+
}, null, 8, ["icon", "class", "onClick"])
|
|
4905
|
+
]),
|
|
4906
|
+
_: 2
|
|
4907
|
+
}, 1032, ["title"])) : item.type !== "divider" && item.children ? (Mo.openBlock(), Mo.createBlock(tooltip, {
|
|
4908
|
+
key: 1,
|
|
4909
|
+
title: item.name,
|
|
4910
|
+
variant: "dark"
|
|
4911
|
+
}, {
|
|
4912
|
+
default: Mo.withCtx(() => [
|
|
4913
|
+
Mo.createElementVNode("div", _hoisted_3, [
|
|
4914
|
+
Mo.createVNode(select_vue_vue_type_script_setup_true_lang._sfc_main, {
|
|
4915
|
+
"model-value": Mo.unref(config.selectedOption)(editor.value, item.children),
|
|
4916
|
+
"onUpdate:modelValue": ($event) => Mo.unref(config.onActionClick)(editor.value, item.slug, $event)
|
|
4917
|
+
}, {
|
|
4918
|
+
default: Mo.withCtx(() => [
|
|
4919
|
+
Mo.createVNode(selectTrigger, { variant: "inline" }, {
|
|
4920
|
+
default: Mo.withCtx(() => [
|
|
4921
|
+
Mo.createVNode(selectValue)
|
|
4922
|
+
]),
|
|
4923
|
+
_: 1
|
|
4924
|
+
}),
|
|
4925
|
+
Mo.createVNode(selectContent, {
|
|
4926
|
+
align: "end",
|
|
4927
|
+
width: "fit"
|
|
4928
|
+
}, {
|
|
4929
|
+
default: Mo.withCtx(() => [
|
|
4930
|
+
(Mo.openBlock(true), Mo.createElementBlock(Mo.Fragment, null, Mo.renderList(item.children, (child, childIndex) => {
|
|
4931
|
+
return Mo.openBlock(), Mo.createBlock(selectItem, {
|
|
4932
|
+
key: childIndex,
|
|
4933
|
+
value: child.option
|
|
4934
|
+
}, {
|
|
4935
|
+
default: Mo.withCtx(() => [
|
|
4936
|
+
item.slug === "color" ? (Mo.openBlock(), Mo.createElementBlock(Mo.Fragment, { key: 0 }, [
|
|
4937
|
+
Mo.createVNode(selectIcon, null, {
|
|
4938
|
+
default: Mo.withCtx(() => [
|
|
4939
|
+
Mo.createElementVNode("i", {
|
|
4940
|
+
class: Mo.normalizeClass(child.icon),
|
|
4941
|
+
style: Mo.normalizeStyle({ background: child.option })
|
|
4942
|
+
}, null, 6)
|
|
4943
|
+
]),
|
|
4944
|
+
_: 2
|
|
4945
|
+
}, 1024),
|
|
4946
|
+
Mo.createElementVNode("span", null, Mo.toDisplayString(child.name), 1)
|
|
4947
|
+
], 64)) : item.slug === "align" ? (Mo.openBlock(), Mo.createBlock(selectIcon, { key: 1 }, {
|
|
4948
|
+
default: Mo.withCtx(() => [
|
|
4949
|
+
Mo.createElementVNode("i", {
|
|
4950
|
+
class: Mo.normalizeClass(child.icon)
|
|
4951
|
+
}, null, 2)
|
|
4952
|
+
]),
|
|
4953
|
+
_: 2
|
|
4954
|
+
}, 1024)) : (Mo.openBlock(), Mo.createElementBlock("span", _hoisted_4, Mo.toDisplayString(child.name), 1))
|
|
4955
|
+
]),
|
|
4956
|
+
_: 2
|
|
4957
|
+
}, 1032, ["value"]);
|
|
4958
|
+
}), 128))
|
|
4959
|
+
]),
|
|
4960
|
+
_: 2
|
|
4961
|
+
}, 1024)
|
|
4962
|
+
]),
|
|
4963
|
+
_: 2
|
|
4964
|
+
}, 1032, ["model-value", "onUpdate:modelValue"])
|
|
4965
|
+
])
|
|
4966
|
+
]),
|
|
4967
|
+
_: 2
|
|
4968
|
+
}, 1032, ["title"])) : (Mo.openBlock(), Mo.createElementBlock("div", _hoisted_5))
|
|
4969
|
+
], 64);
|
|
4970
|
+
}), 128)),
|
|
4971
|
+
__props.showExtraSettings ? (Mo.openBlock(), Mo.createElementBlock("div", _hoisted_6, [
|
|
4972
|
+
_cache[1] || (_cache[1] = Mo.createElementVNode("div", { class: "divider" }, null, -1)),
|
|
4973
|
+
Mo.createVNode(extraSettings, { editor: editor.value }, null, 8, ["editor"])
|
|
4974
|
+
])) : Mo.createCommentVNode("", true)
|
|
4975
|
+
]),
|
|
4976
|
+
Mo.createElementVNode("div", _hoisted_7, [
|
|
4977
|
+
Mo.createVNode(Mo.unref(EditorContent), { editor: editor.value }, null, 8, ["editor"])
|
|
4978
|
+
]),
|
|
4979
|
+
__props.maxLimit ? (Mo.openBlock(), Mo.createElementBlock("div", {
|
|
4980
|
+
key: 0,
|
|
4981
|
+
class: Mo.normalizeClass(["characters-count", {
|
|
4982
|
+
warning: limitWarning.value === "warning",
|
|
4983
|
+
danger: limitWarning.value === "danger"
|
|
4984
|
+
}])
|
|
4985
|
+
}, Mo.toDisplayString(charactersCount.value) + "/" + Mo.toDisplayString(__props.maxLimit), 3)) : Mo.createCommentVNode("", true),
|
|
4986
|
+
Mo.createVNode(linkBubble, {
|
|
4987
|
+
editor: editor.value,
|
|
4988
|
+
"show-set-link-from-toolbar": showSetLinkFromToolbar.value,
|
|
4989
|
+
onSetLinkClosed: _cache[0] || (_cache[0] = ($event) => showSetLinkFromToolbar.value = false)
|
|
4990
|
+
}, null, 8, ["editor", "show-set-link-from-toolbar"])
|
|
4991
|
+
])) : Mo.createCommentVNode("", true);
|
|
4992
|
+
};
|
|
4993
|
+
}
|
|
4994
|
+
});
|
|
4995
|
+
const richEditor = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-dbc85b1a"]]);
|
|
4996
|
+
module.exports = richEditor;
|