wiki-formant 0.4.1 → 0.7.0
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/README.md +102 -1
- package/dist/analytics.d.ts +22 -0
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +31 -1
- package/dist/analytics.js.map +1 -1
- package/dist/dom.d.ts +69 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +167 -0
- package/dist/dom.js.map +1 -0
- package/dist/react.d.ts +216 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +470 -0
- package/dist/react.js.map +1 -0
- package/dist/sidebar.d.ts +38 -0
- package/dist/sidebar.d.ts.map +1 -0
- package/dist/sidebar.js +43 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/taxonomy.d.ts +52 -0
- package/dist/taxonomy.d.ts.map +1 -1
- package/dist/taxonomy.js +95 -42
- package/dist/taxonomy.js.map +1 -1
- package/dist/tiptap.d.ts +78 -0
- package/dist/tiptap.d.ts.map +1 -0
- package/dist/tiptap.js +344 -0
- package/dist/tiptap.js.map +1 -0
- package/package.json +54 -3
package/dist/taxonomy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taxonomy.d.ts","sourceRoot":"","sources":["../src/taxonomy.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"taxonomy.d.ts","sourceRoot":"","sources":["../src/taxonomy.ts"],"names":[],"mappings":"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"}
|
package/dist/taxonomy.js
CHANGED
|
@@ -66,11 +66,54 @@ export function createTaxonomy(config) {
|
|
|
66
66
|
return pages;
|
|
67
67
|
return pages.filter(p => matches(p, filters, letter));
|
|
68
68
|
};
|
|
69
|
+
const needsAlphaIndex = (pageCount) => pageCount >= minPages;
|
|
70
|
+
/**
|
|
71
|
+
* Facet values with counts. Each facet is counted over the set narrowed by
|
|
72
|
+
* every *other* active filter, so its own options stay switchable rather
|
|
73
|
+
* than collapsing to the one already chosen.
|
|
74
|
+
*
|
|
75
|
+
* Values are read from the data, never from the declared `options`: a key
|
|
76
|
+
* that declares four and holds seven would otherwise hide three behind a
|
|
77
|
+
* bar claiming to cover everything. Render what is there and the drift
|
|
78
|
+
* becomes visible instead of silent.
|
|
79
|
+
*/
|
|
80
|
+
const buildFacets = (tagPath, pages, filters, letter) => facetKeys(tagPath).flatMap(key => {
|
|
81
|
+
const others = Object.fromEntries(Object.entries(filters).filter(([k]) => k !== key.key));
|
|
82
|
+
const counts = new Map();
|
|
83
|
+
for (const page of filterPages(pages, others, letter)) {
|
|
84
|
+
const value = metaValue(page, key.key);
|
|
85
|
+
if (value)
|
|
86
|
+
counts.set(value, (counts.get(value) ?? 0) + 1);
|
|
87
|
+
}
|
|
88
|
+
// A single-valued facet is no choice, so it stays hidden — unless it is
|
|
89
|
+
// the active one. An infobox row can set a filter the chips never
|
|
90
|
+
// offered, and without its chip the reader lands on a narrowed list
|
|
91
|
+
// with no way to widen it.
|
|
92
|
+
if (counts.size < 2 && !(key.key in filters))
|
|
93
|
+
return [];
|
|
94
|
+
const values = [...counts]
|
|
95
|
+
.map(([value, count]) => ({ value, count }))
|
|
96
|
+
.sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));
|
|
97
|
+
return [{ key: key.key, label: key.label.replace(/:$/, ''), values }];
|
|
98
|
+
});
|
|
99
|
+
/** A–Z buckets present in the set, `#` last. */
|
|
100
|
+
const alphaIndex = (pages, filters) => {
|
|
101
|
+
const counts = new Map();
|
|
102
|
+
for (const page of filterPages(pages, filters)) {
|
|
103
|
+
const letter = firstLetter(page.title);
|
|
104
|
+
counts.set(letter, (counts.get(letter) ?? 0) + 1);
|
|
105
|
+
}
|
|
106
|
+
return [...counts]
|
|
107
|
+
.map(([value, count]) => ({ value, count }))
|
|
108
|
+
.sort((a, b) => (a.value === '#' ? 1 : b.value === '#' ? -1 : a.value.localeCompare(b.value)));
|
|
109
|
+
};
|
|
69
110
|
return {
|
|
70
111
|
facetKeys,
|
|
71
112
|
href,
|
|
72
113
|
filterPages,
|
|
73
|
-
needsAlphaIndex
|
|
114
|
+
needsAlphaIndex,
|
|
115
|
+
buildFacets,
|
|
116
|
+
alphaIndex,
|
|
74
117
|
facetFilters(tagPath, params) {
|
|
75
118
|
const filters = {};
|
|
76
119
|
for (const key of facetKeys(tagPath)) {
|
|
@@ -80,37 +123,6 @@ export function createTaxonomy(config) {
|
|
|
80
123
|
}
|
|
81
124
|
return filters;
|
|
82
125
|
},
|
|
83
|
-
/**
|
|
84
|
-
* Facet values with counts. Each facet is counted over the set narrowed by
|
|
85
|
-
* every *other* active filter, so its own options stay switchable rather
|
|
86
|
-
* than collapsing to the one already chosen.
|
|
87
|
-
*
|
|
88
|
-
* Values are read from the data, never from the declared `options`: a key
|
|
89
|
-
* that declares four and holds seven would otherwise hide three behind a
|
|
90
|
-
* bar claiming to cover everything. Render what is there and the drift
|
|
91
|
-
* becomes visible instead of silent.
|
|
92
|
-
*/
|
|
93
|
-
buildFacets(tagPath, pages, filters, letter) {
|
|
94
|
-
return facetKeys(tagPath).flatMap(key => {
|
|
95
|
-
const others = Object.fromEntries(Object.entries(filters).filter(([k]) => k !== key.key));
|
|
96
|
-
const counts = new Map();
|
|
97
|
-
for (const page of filterPages(pages, others, letter)) {
|
|
98
|
-
const value = metaValue(page, key.key);
|
|
99
|
-
if (value)
|
|
100
|
-
counts.set(value, (counts.get(value) ?? 0) + 1);
|
|
101
|
-
}
|
|
102
|
-
// A single-valued facet is no choice, so it stays hidden — unless it is
|
|
103
|
-
// the active one. An infobox row can set a filter the chips never
|
|
104
|
-
// offered, and without its chip the reader lands on a narrowed list
|
|
105
|
-
// with no way to widen it.
|
|
106
|
-
if (counts.size < 2 && !(key.key in filters))
|
|
107
|
-
return [];
|
|
108
|
-
const values = [...counts]
|
|
109
|
-
.map(([value, count]) => ({ value, count }))
|
|
110
|
-
.sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));
|
|
111
|
-
return [{ key: key.key, label: key.label.replace(/:$/, ''), values }];
|
|
112
|
-
});
|
|
113
|
-
},
|
|
114
126
|
metadataRows(tagPath, page) {
|
|
115
127
|
const facets = new Set(facetKeys(tagPath).map(k => k.key));
|
|
116
128
|
return config.getMetadataKeys(tagPath).flatMap(key => {
|
|
@@ -128,16 +140,57 @@ export function createTaxonomy(config) {
|
|
|
128
140
|
];
|
|
129
141
|
});
|
|
130
142
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
facetControls(tagPath, pages, state = {}) {
|
|
144
|
+
const { sort, filters = {}, letter } = state;
|
|
145
|
+
return buildFacets(tagPath, pages, filters, letter).map(facet => ({
|
|
146
|
+
key: facet.key,
|
|
147
|
+
label: facet.label,
|
|
148
|
+
options: facet.values.map(({ value, count }) => ({
|
|
149
|
+
value,
|
|
150
|
+
label: value,
|
|
151
|
+
count,
|
|
152
|
+
// The letter and the sort ride along: a chip that rebuilt the URL from
|
|
153
|
+
// its own axis alone is how a reader loses their place on every press.
|
|
154
|
+
href: href(tagPath, {
|
|
155
|
+
sort,
|
|
156
|
+
filters: toggleFilter(filters, facet.key, value),
|
|
157
|
+
letter,
|
|
158
|
+
}),
|
|
159
|
+
active: filters[facet.key] === value,
|
|
160
|
+
})),
|
|
161
|
+
}));
|
|
162
|
+
},
|
|
163
|
+
alphaControls(tagPath, pages, state = {}) {
|
|
164
|
+
const { sort, filters = {}, letter } = state;
|
|
165
|
+
if (!needsAlphaIndex(pages.length))
|
|
166
|
+
return [];
|
|
167
|
+
const letters = alphaIndex(pages, filters);
|
|
168
|
+
if (!letters.length)
|
|
169
|
+
return [];
|
|
170
|
+
const active = letters.some(l => l.value === letter) ? letter : undefined;
|
|
171
|
+
return [
|
|
172
|
+
{
|
|
173
|
+
value: '',
|
|
174
|
+
label: 'All',
|
|
175
|
+
count: filterPages(pages, filters).length,
|
|
176
|
+
href: href(tagPath, { sort, filters }),
|
|
177
|
+
active: !active,
|
|
178
|
+
reset: true,
|
|
179
|
+
},
|
|
180
|
+
...letters.map(({ value, count }) => ({
|
|
181
|
+
value,
|
|
182
|
+
label: value,
|
|
183
|
+
count,
|
|
184
|
+
// Re-pressing the active letter clears it, matching `toggleFilter`.
|
|
185
|
+
href: href(tagPath, { sort, filters, letter: active === value ? undefined : value }),
|
|
186
|
+
active: active === value,
|
|
187
|
+
})),
|
|
188
|
+
];
|
|
189
|
+
},
|
|
190
|
+
resolveLetter(pages, filters, letter) {
|
|
191
|
+
if (!letter)
|
|
192
|
+
return undefined;
|
|
193
|
+
return alphaIndex(pages, filters).some(l => l.value === letter) ? letter : undefined;
|
|
141
194
|
},
|
|
142
195
|
/**
|
|
143
196
|
* Siblings ranked by how many facet values they share with the page — a
|
package/dist/taxonomy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taxonomy.js","sourceRoot":"","sources":["../src/taxonomy.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,8EAA8E;AAC9E,2BAA2B;AAC3B,EAAE;AACF,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,wEAAwE;
|
|
1
|
+
{"version":3,"file":"taxonomy.js","sourceRoot":"","sources":["../src/taxonomy.ts"],"names":[],"mappings":"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"}
|
package/dist/tiptap.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { Node as TiptapNode } from '@tiptap/core';
|
|
3
|
+
export declare const Iframe: TiptapNode<any, any>;
|
|
4
|
+
/** The stock extension plus the paste rule it does not ship with. */
|
|
5
|
+
export declare const YouTube: TiptapNode<import("@tiptap/extension-youtube").YoutubeOptions, any>;
|
|
6
|
+
export declare const TwitterEmbed: TiptapNode<any, any>;
|
|
7
|
+
export interface MapEmbedOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Follow a shortened map URL to one that can be embedded, or null.
|
|
10
|
+
*
|
|
11
|
+
* Injected because it needs the consumer's own API route: a `maps.app.goo.gl`
|
|
12
|
+
* link cannot be resolved in the browser, so each app proxies the redirect.
|
|
13
|
+
* The synchronous half of the parsing is `wiki-formant/maps`, used directly.
|
|
14
|
+
*/
|
|
15
|
+
resolveMapUrl: (url: string) => Promise<string | null>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Google and Apple map links, pasted.
|
|
19
|
+
*
|
|
20
|
+
* A shortened link inserts immediately with `about:blank` and swaps its `src`
|
|
21
|
+
* once the redirect resolves — pasting must not block on a network hop, and the
|
|
22
|
+
* node has to already exist for the reader to see anything happen.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createMapEmbed({ resolveMapUrl }: MapEmbedOptions): TiptapNode<any, any>;
|
|
25
|
+
export interface CodeBlockClassNames {
|
|
26
|
+
wrapper?: string;
|
|
27
|
+
/** The control cluster, positioned over the block. */
|
|
28
|
+
control?: string;
|
|
29
|
+
button?: string;
|
|
30
|
+
dropdown?: string;
|
|
31
|
+
option?: string;
|
|
32
|
+
/** Applied alongside `option` on the selected language. */
|
|
33
|
+
optionActive?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface CodeBlockOptions {
|
|
36
|
+
/** Selectable languages. Each wiki's own list, from its block-utils. */
|
|
37
|
+
langs: readonly string[];
|
|
38
|
+
defaultLang: string;
|
|
39
|
+
classNames?: CodeBlockClassNames;
|
|
40
|
+
icons?: {
|
|
41
|
+
lang?: ReactNode;
|
|
42
|
+
/** Receives whether the dropdown is open, as `TableOfContents`'s icon does. */
|
|
43
|
+
chevron?: (open: boolean) => ReactNode;
|
|
44
|
+
selected?: ReactNode;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** A code block whose language is pickable from a dropdown. */
|
|
48
|
+
export declare function createCodeBlock({ langs, defaultLang, classNames, icons, }: CodeBlockOptions): TiptapNode<import("@tiptap/extension-code-block").CodeBlockOptions, any>;
|
|
49
|
+
export interface TabsClassNames {
|
|
50
|
+
editor?: string;
|
|
51
|
+
list?: string;
|
|
52
|
+
tab?: string;
|
|
53
|
+
/** Applied alongside `tab` on the open tab. */
|
|
54
|
+
tabActive?: string;
|
|
55
|
+
title?: string;
|
|
56
|
+
remove?: string;
|
|
57
|
+
add?: string;
|
|
58
|
+
content?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface TabsOptions {
|
|
61
|
+
classNames?: TabsClassNames;
|
|
62
|
+
icons?: {
|
|
63
|
+
add?: ReactNode;
|
|
64
|
+
remove?: ReactNode;
|
|
65
|
+
};
|
|
66
|
+
/** Names a newly added tab. Receives the 1-based position. */
|
|
67
|
+
tabLabel?: (index: number) => string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A tab group and its items, which must be registered together — `tabGroup`'s
|
|
71
|
+
* content expression is `tabItem+`, so registering one without the other leaves
|
|
72
|
+
* a node type the schema cannot satisfy.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createTabs({ classNames, icons, tabLabel, }?: TabsOptions): {
|
|
75
|
+
TabGroup: TiptapNode<any, any>;
|
|
76
|
+
TabItem: TiptapNode<any, any>;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=tiptap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiptap.d.ts","sourceRoot":"","sources":["../src/tiptap.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjF,OAAO,EAAE,IAAI,IAAI,UAAU,EAAgC,MAAM,cAAc,CAAC;AAahF,eAAO,MAAM,MAAM,sBAiBjB,CAAC;AAIH,qEAAqE;AACrE,eAAO,MAAM,OAAO,qEAWlB,CAAC;AAyBH,eAAO,MAAM,YAAY,sBAwDvB,CAAC;AAIH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAAE,aAAa,EAAE,EAAE,eAAe,wBAiFhE;AAID,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,SAAS,CAAC;QACjB,+EAA+E;QAC/E,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC;QACvC,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,CAAC;CACH;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,WAAW,EACX,UAAe,EACf,KAAU,GACX,EAAE,gBAAgB,4EA6DlB;AAID,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,SAAS,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IAChD,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,UAAe,EACf,KAAU,EACV,QAA0B,GAC3B,GAAE,WAAgB;;;EAwIlB"}
|
package/dist/tiptap.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
// tiptap.tsx — the custom editor nodes both wikis had written twice.
|
|
4
|
+
//
|
|
5
|
+
// Behind its own subpath for the same reason `react.tsx` is: the four
|
|
6
|
+
// `@tiptap/*` packages are OPTIONAL peer dependencies, so a consumer that only
|
|
7
|
+
// wants the taxonomy or the MCP transport still installs a package with no
|
|
8
|
+
// runtime dependencies at all.
|
|
9
|
+
//
|
|
10
|
+
// The two copies had drifted in both directions — one had grown tabs the other
|
|
11
|
+
// lacked, the other had extracted the Twitter helper the first still wrote out
|
|
12
|
+
// three times — which is the shape of drift that costs the most: neither copy
|
|
13
|
+
// is behind, so neither looks like the one to fix.
|
|
14
|
+
//
|
|
15
|
+
// What is shared is the node schema and its behaviour, never appearance. Class
|
|
16
|
+
// names and icons are injected, which is what lets one wiki keep `text-jupiter`
|
|
17
|
+
// and the other `text-accent` without either forking the node. It also keeps
|
|
18
|
+
// this file from dragging an icon library in behind it.
|
|
19
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
20
|
+
import { Node as TiptapNode, mergeAttributes } from '@tiptap/core';
|
|
21
|
+
import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';
|
|
22
|
+
import TiptapYoutube from '@tiptap/extension-youtube';
|
|
23
|
+
import TiptapCodeBlock from '@tiptap/extension-code-block';
|
|
24
|
+
import { onTweetResize, tweetEmbedSrc } from './dom.js';
|
|
25
|
+
import { toMapEmbedUrl } from './maps.js';
|
|
26
|
+
import { useClickOutside } from './react.js';
|
|
27
|
+
/** Local `cn`. Both wikis import one; the package will not depend on one. */
|
|
28
|
+
const cx = (...parts) => parts.filter(Boolean).join(' ');
|
|
29
|
+
// ---- iframe -----------------------------------------------------------------
|
|
30
|
+
export const Iframe = TiptapNode.create({
|
|
31
|
+
name: 'iframe',
|
|
32
|
+
group: 'block',
|
|
33
|
+
atom: true,
|
|
34
|
+
addAttributes() {
|
|
35
|
+
return { src: { default: null }, width: { default: '100%' }, height: { default: '400' } };
|
|
36
|
+
},
|
|
37
|
+
parseHTML() {
|
|
38
|
+
return [{ tag: 'iframe' }];
|
|
39
|
+
},
|
|
40
|
+
renderHTML({ HTMLAttributes }) {
|
|
41
|
+
return [
|
|
42
|
+
'div',
|
|
43
|
+
{ 'data-iframe-embed': '', class: 'iframe-embed' },
|
|
44
|
+
['iframe', mergeAttributes(HTMLAttributes, { frameborder: '0', allowfullscreen: 'true' })],
|
|
45
|
+
];
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
// ---- youtube ----------------------------------------------------------------
|
|
49
|
+
/** The stock extension plus the paste rule it does not ship with. */
|
|
50
|
+
export const YouTube = TiptapYoutube.extend({
|
|
51
|
+
addPasteRules() {
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
find: /https?:\/\/(?:www\.)?(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]+)[^\s]*/g,
|
|
55
|
+
handler: ({ match, chain, range }) => {
|
|
56
|
+
if (match[0])
|
|
57
|
+
chain().deleteRange(range).setYoutubeVideo({ src: match[0] }).run();
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
// ---- twitter ----------------------------------------------------------------
|
|
64
|
+
function TwitterEmbedView({ node }) {
|
|
65
|
+
const containerRef = useRef(null);
|
|
66
|
+
// The embed posts its measured height back; `onTweetResize` owns the origin
|
|
67
|
+
// check, which is the part that was written out at four call sites.
|
|
68
|
+
useEffect(() => onTweetResize(height => {
|
|
69
|
+
const iframe = containerRef.current?.querySelector('iframe');
|
|
70
|
+
if (iframe)
|
|
71
|
+
iframe.style.height = `${height}px`;
|
|
72
|
+
}), []);
|
|
73
|
+
return (_jsx(NodeViewWrapper, { children: _jsx("div", { ref: containerRef, className: "twitter-embed", children: _jsx("iframe", { src: tweetEmbedSrc(node.attrs.tweetId), scrolling: "no", allowFullScreen: true }) }) }));
|
|
74
|
+
}
|
|
75
|
+
export const TwitterEmbed = TiptapNode.create({
|
|
76
|
+
name: 'twitterEmbed',
|
|
77
|
+
group: 'block',
|
|
78
|
+
atom: true,
|
|
79
|
+
addAttributes() {
|
|
80
|
+
return { tweetId: { default: null }, url: { default: null } };
|
|
81
|
+
},
|
|
82
|
+
parseHTML() {
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
tag: 'div[data-twitter-embed]',
|
|
86
|
+
getAttrs: el => ({
|
|
87
|
+
tweetId: el.dataset.tweetId,
|
|
88
|
+
url: el.dataset.url,
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
},
|
|
93
|
+
renderHTML({ node }) {
|
|
94
|
+
return [
|
|
95
|
+
'div',
|
|
96
|
+
{
|
|
97
|
+
'data-twitter-embed': '',
|
|
98
|
+
'data-tweet-id': node.attrs.tweetId,
|
|
99
|
+
'data-url': node.attrs.url,
|
|
100
|
+
class: 'twitter-embed',
|
|
101
|
+
},
|
|
102
|
+
[
|
|
103
|
+
'iframe',
|
|
104
|
+
{
|
|
105
|
+
src: tweetEmbedSrc(node.attrs.tweetId),
|
|
106
|
+
frameborder: '0',
|
|
107
|
+
allowfullscreen: 'true',
|
|
108
|
+
scrolling: 'no',
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
];
|
|
112
|
+
},
|
|
113
|
+
addNodeView() {
|
|
114
|
+
return ReactNodeViewRenderer(TwitterEmbedView);
|
|
115
|
+
},
|
|
116
|
+
addPasteRules() {
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
find: /https?:\/\/(?:twitter\.com|x\.com)\/\w+\/status\/(\d+)/g,
|
|
120
|
+
handler: ({ match, chain, range }) => {
|
|
121
|
+
const tweetId = match[1];
|
|
122
|
+
if (tweetId)
|
|
123
|
+
chain()
|
|
124
|
+
.deleteRange(range)
|
|
125
|
+
.insertContent({ type: 'twitterEmbed', attrs: { tweetId, url: match[0] } })
|
|
126
|
+
.run();
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
/**
|
|
133
|
+
* Google and Apple map links, pasted.
|
|
134
|
+
*
|
|
135
|
+
* A shortened link inserts immediately with `about:blank` and swaps its `src`
|
|
136
|
+
* once the redirect resolves — pasting must not block on a network hop, and the
|
|
137
|
+
* node has to already exist for the reader to see anything happen.
|
|
138
|
+
*/
|
|
139
|
+
export function createMapEmbed({ resolveMapUrl }) {
|
|
140
|
+
return TiptapNode.create({
|
|
141
|
+
name: 'mapEmbed',
|
|
142
|
+
group: 'block',
|
|
143
|
+
atom: true,
|
|
144
|
+
addAttributes() {
|
|
145
|
+
return { src: { default: null }, url: { default: null } };
|
|
146
|
+
},
|
|
147
|
+
parseHTML() {
|
|
148
|
+
return [
|
|
149
|
+
{
|
|
150
|
+
tag: 'div[data-map-embed]',
|
|
151
|
+
getAttrs: el => ({
|
|
152
|
+
src: el.querySelector('iframe')?.getAttribute('src'),
|
|
153
|
+
url: el.dataset.url,
|
|
154
|
+
}),
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
},
|
|
158
|
+
renderHTML({ node }) {
|
|
159
|
+
return [
|
|
160
|
+
'div',
|
|
161
|
+
{ 'data-map-embed': '', 'data-url': node.attrs.url || '', class: 'map-embed' },
|
|
162
|
+
[
|
|
163
|
+
'iframe',
|
|
164
|
+
{
|
|
165
|
+
src: node.attrs.src,
|
|
166
|
+
frameborder: '0',
|
|
167
|
+
allowfullscreen: 'true',
|
|
168
|
+
loading: 'lazy',
|
|
169
|
+
referrerpolicy: 'no-referrer-when-downgrade',
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
];
|
|
173
|
+
},
|
|
174
|
+
addPasteRules() {
|
|
175
|
+
const ext = this;
|
|
176
|
+
const handler = ({ match, chain, range }) => {
|
|
177
|
+
const url = match[0];
|
|
178
|
+
const src = toMapEmbedUrl(url);
|
|
179
|
+
if (src) {
|
|
180
|
+
chain().deleteRange(range).insertContent({ type: 'mapEmbed', attrs: { src, url } }).run();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (/maps\.app\.goo\.gl|goo\.gl\/maps/.test(url)) {
|
|
184
|
+
chain()
|
|
185
|
+
.deleteRange(range)
|
|
186
|
+
.insertContent({ type: 'mapEmbed', attrs: { src: 'about:blank', url } })
|
|
187
|
+
.run();
|
|
188
|
+
resolveMapUrl(url).then(resolved => {
|
|
189
|
+
if (!resolved)
|
|
190
|
+
return;
|
|
191
|
+
// Find the placeholder by its url rather than by a captured
|
|
192
|
+
// position: the document has been editable throughout the hop.
|
|
193
|
+
const { doc } = ext.editor.state;
|
|
194
|
+
doc.descendants((node, pos) => {
|
|
195
|
+
if (node.type.name === 'mapEmbed' &&
|
|
196
|
+
node.attrs.url === url &&
|
|
197
|
+
node.attrs.src === 'about:blank') {
|
|
198
|
+
ext.editor
|
|
199
|
+
.chain()
|
|
200
|
+
.setNodeSelection(pos)
|
|
201
|
+
.updateAttributes('mapEmbed', { src: resolved })
|
|
202
|
+
.run();
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
return [
|
|
211
|
+
{ find: /https?:\/\/(?:www\.)?google\.[a-z.]+\/maps[^\s]*/g, handler },
|
|
212
|
+
{ find: /https?:\/\/maps\.app\.goo\.gl\/[^\s]+/g, handler },
|
|
213
|
+
{ find: /https?:\/\/goo\.gl\/maps\/[^\s]+/g, handler },
|
|
214
|
+
{ find: /https?:\/\/maps\.apple\.com[^\s]*/g, handler },
|
|
215
|
+
{ find: /https?:\/\/embed\.apple\.com\/maps[^\s]*/g, handler },
|
|
216
|
+
];
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/** A code block whose language is pickable from a dropdown. */
|
|
221
|
+
export function createCodeBlock({ langs, defaultLang, classNames = {}, icons = {}, }) {
|
|
222
|
+
function CodeBlockView({ node, updateAttributes, }) {
|
|
223
|
+
const [open, setOpen] = useState(false);
|
|
224
|
+
const close = useCallback(() => setOpen(false), []);
|
|
225
|
+
const dropdownRef = useClickOutside(close);
|
|
226
|
+
const lang = node.attrs.language || defaultLang;
|
|
227
|
+
return (_jsxs(NodeViewWrapper, { className: classNames.wrapper, children: [_jsxs("div", { ref: dropdownRef, className: classNames.control, children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), className: classNames.button, children: [icons.lang, _jsx("span", { children: lang }), icons.chevron?.(open)] }), open && (_jsx("div", { className: classNames.dropdown, children: langs.map(l => (_jsxs("button", { type: "button", onClick: () => {
|
|
228
|
+
updateAttributes({ language: l });
|
|
229
|
+
setOpen(false);
|
|
230
|
+
}, className: cx(classNames.option, l === lang && classNames.optionActive), children: [l, l === lang && icons.selected] }, l))) }))] }), _jsx("pre", { children: _jsx(NodeViewContent, { as: "code", className: `language-${lang}` }) })] }));
|
|
231
|
+
}
|
|
232
|
+
return TiptapCodeBlock.extend({
|
|
233
|
+
addAttributes() {
|
|
234
|
+
return {
|
|
235
|
+
...this.parent?.(),
|
|
236
|
+
language: {
|
|
237
|
+
default: defaultLang,
|
|
238
|
+
parseHTML: el => el.querySelector('code')?.className?.match(/language-(\w+)/)?.[1] || defaultLang,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
addNodeView() {
|
|
243
|
+
return ReactNodeViewRenderer(CodeBlockView);
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* A tab group and its items, which must be registered together — `tabGroup`'s
|
|
249
|
+
* content expression is `tabItem+`, so registering one without the other leaves
|
|
250
|
+
* a node type the schema cannot satisfy.
|
|
251
|
+
*/
|
|
252
|
+
export function createTabs({ classNames = {}, icons = {}, tabLabel = i => `Tab ${i}`, } = {}) {
|
|
253
|
+
function TabGroupView({ node, getPos, editor, updateAttributes, }) {
|
|
254
|
+
const activeTab = node.attrs.activeTab ?? 0;
|
|
255
|
+
const tabs = node.content.content || [];
|
|
256
|
+
const setActiveTab = (i) => updateAttributes({ activeTab: i });
|
|
257
|
+
// Positions are walked from the group's own start rather than cached: every
|
|
258
|
+
// edit inside a tab shifts every position after it.
|
|
259
|
+
const posOf = (index) => {
|
|
260
|
+
let pos = getPos() + 1;
|
|
261
|
+
for (let i = 0; i < index; i++)
|
|
262
|
+
pos += tabs[i].nodeSize;
|
|
263
|
+
return pos;
|
|
264
|
+
};
|
|
265
|
+
const addTab = () => editor
|
|
266
|
+
.chain()
|
|
267
|
+
.focus()
|
|
268
|
+
.insertContentAt(getPos() + node.nodeSize - 1, {
|
|
269
|
+
type: 'tabItem',
|
|
270
|
+
attrs: { title: tabLabel(tabs.length + 1) },
|
|
271
|
+
content: [{ type: 'paragraph' }],
|
|
272
|
+
})
|
|
273
|
+
.run();
|
|
274
|
+
const removeTab = (index) => {
|
|
275
|
+
// `tabItem+` means the last tab cannot be removed.
|
|
276
|
+
if (tabs.length <= 1)
|
|
277
|
+
return;
|
|
278
|
+
const pos = posOf(index);
|
|
279
|
+
editor.chain().focus().deleteRange({ from: pos, to: pos + tabs[index].nodeSize }).run();
|
|
280
|
+
if (activeTab >= tabs.length - 1)
|
|
281
|
+
setActiveTab(Math.max(0, tabs.length - 2));
|
|
282
|
+
};
|
|
283
|
+
const renameTab = (index, title) => {
|
|
284
|
+
const { tr } = editor.state;
|
|
285
|
+
tr.setNodeMarkup(posOf(index), undefined, { title });
|
|
286
|
+
editor.view.dispatch(tr);
|
|
287
|
+
};
|
|
288
|
+
return (_jsx(NodeViewWrapper, { "data-tabs": "", "data-active-tab": activeTab, children: _jsxs("div", { className: classNames.editor, children: [_jsxs("div", { className: classNames.list, children: [tabs.map((tab, i) => (_jsxs("div", { className: cx(classNames.tab, activeTab === i && classNames.tabActive), children: [_jsx("input", { type: "text", value: tab.attrs.title, onChange: e => renameTab(i, e.target.value), onClick: () => setActiveTab(i), className: classNames.title }), tabs.length > 1 && (_jsx("button", { type: "button", onClick: () => removeTab(i), className: classNames.remove, children: icons.remove }))] }, i))), _jsx("button", { type: "button", onClick: addTab, className: classNames.add, children: icons.add })] }), _jsx("div", { className: classNames.content, children: _jsx(NodeViewContent, {}) })] }) }));
|
|
289
|
+
}
|
|
290
|
+
const TabGroup = TiptapNode.create({
|
|
291
|
+
name: 'tabGroup',
|
|
292
|
+
group: 'block',
|
|
293
|
+
content: 'tabItem+',
|
|
294
|
+
addAttributes() {
|
|
295
|
+
return { activeTab: { default: 0 } };
|
|
296
|
+
},
|
|
297
|
+
parseHTML() {
|
|
298
|
+
return [{ tag: 'div[data-tabs]' }];
|
|
299
|
+
},
|
|
300
|
+
renderHTML({ HTMLAttributes, node }) {
|
|
301
|
+
return [
|
|
302
|
+
'div',
|
|
303
|
+
mergeAttributes(HTMLAttributes, {
|
|
304
|
+
'data-tabs': '',
|
|
305
|
+
'data-active-tab': node.attrs.activeTab,
|
|
306
|
+
}),
|
|
307
|
+
0,
|
|
308
|
+
];
|
|
309
|
+
},
|
|
310
|
+
addNodeView() {
|
|
311
|
+
return ReactNodeViewRenderer(TabGroupView);
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
const TabItem = TiptapNode.create({
|
|
315
|
+
name: 'tabItem',
|
|
316
|
+
group: 'tabItem',
|
|
317
|
+
content: 'block+',
|
|
318
|
+
defining: true,
|
|
319
|
+
isolating: true,
|
|
320
|
+
addAttributes() {
|
|
321
|
+
return { title: { default: 'Tab' } };
|
|
322
|
+
},
|
|
323
|
+
parseHTML() {
|
|
324
|
+
return [
|
|
325
|
+
{
|
|
326
|
+
tag: 'div[data-tab-item]',
|
|
327
|
+
getAttrs: el => ({ title: el.getAttribute('data-tab-title') || 'Tab' }),
|
|
328
|
+
},
|
|
329
|
+
];
|
|
330
|
+
},
|
|
331
|
+
renderHTML({ HTMLAttributes, node }) {
|
|
332
|
+
return [
|
|
333
|
+
'div',
|
|
334
|
+
mergeAttributes(HTMLAttributes, {
|
|
335
|
+
'data-tab-item': '',
|
|
336
|
+
'data-tab-title': node.attrs.title,
|
|
337
|
+
}),
|
|
338
|
+
0,
|
|
339
|
+
];
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
return { TabGroup, TabItem };
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=tiptap.js.map
|