@docs.plus/extension-hyperlink 1.5.2 → 2.0.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/CHANGELOG.md +523 -0
- package/LICENSE +21 -0
- package/README.md +678 -327
- package/dist/index.cjs +22 -712
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +414 -0
- package/dist/index.d.ts +414 -9
- package/dist/index.js +22 -707
- package/dist/index.js.map +1 -1
- package/dist/styles.css +403 -0
- package/package.json +82 -32
- package/dist/helpers/autoHyperlink.d.ts +0 -8
- package/dist/helpers/clickHandler.d.ts +0 -11
- package/dist/helpers/editHyperlink.d.ts +0 -9
- package/dist/helpers/pasteHandler.d.ts +0 -9
- package/dist/helpers/tippyHelper.d.ts +0 -29
- package/dist/hyperlink.d.ts +0 -77
- package/dist/index.umd.js +0 -713
- package/dist/index.umd.js.map +0 -1
- package/dist/modals/editeHyperlink.d.ts +0 -11
- package/dist/modals/icons.d.ts +0 -9
- package/dist/modals/previewHyperlink.d.ts +0 -11
- package/dist/modals/setHyperlink.d.ts +0 -14
- package/src/helpers/autoHyperlink.ts +0 -167
- package/src/helpers/clickHandler.ts +0 -80
- package/src/helpers/editHyperlink.ts +0 -59
- package/src/helpers/pasteHandler.ts +0 -46
- package/src/helpers/tippyHelper.ts +0 -136
- package/src/hyperlink.ts +0 -277
- package/src/index.ts +0 -17
- package/src/modals/editeHyperlink.ts +0 -99
- package/src/modals/icons.ts +0 -46
- package/src/modals/previewHyperlink.ts +0 -85
- package/src/modals/setHyperlink.ts +0 -97
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { Editor, Mark } from '@tiptap/core';
|
|
2
|
+
import { MarkType } from '@tiptap/pm/model';
|
|
3
|
+
import { Placement } from '@floating-ui/dom';
|
|
4
|
+
export { registerCustomProtocol } from 'linkifyjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Canonicalize a user-supplied href so stored marks point somewhere
|
|
8
|
+
* absolute (bare `google.com` would otherwise resolve against
|
|
9
|
+
* `document.baseURI` at render time). See README → Normalization for
|
|
10
|
+
* the full pipeline order.
|
|
11
|
+
*/
|
|
12
|
+
declare const normalizeHref: (raw: string, defaultProtocol?: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Shape `findLinks` produces (linkifyjs match + our synthetic
|
|
15
|
+
* special-scheme / phone entries). Loosened so linkifyjs types don't
|
|
16
|
+
* leak across the public boundary.
|
|
17
|
+
*/
|
|
18
|
+
type LinkifyMatchLike = {
|
|
19
|
+
type: string;
|
|
20
|
+
value: string;
|
|
21
|
+
href: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Schemes blocked at every write boundary: `javascript:` / `vbscript:`
|
|
26
|
+
* (script execution), `data:` (arbitrary HTML), `file:` (local FS),
|
|
27
|
+
* `blob:` (in-page memory; never legitimate in stored content).
|
|
28
|
+
*
|
|
29
|
+
* Twin of `extension-hypermultimedia`'s copy. Adding a scheme to one and not
|
|
30
|
+
* the other opens a hole in the twin, so preflight diffs them byte-for-byte.
|
|
31
|
+
*/
|
|
32
|
+
declare const DANGEROUS_SCHEME_RE: RegExp;
|
|
33
|
+
/**
|
|
34
|
+
* Single XSS gate used at every read/write boundary. Returns `false`
|
|
35
|
+
* for nullish/empty hrefs and any scheme matched by
|
|
36
|
+
* {@link DANGEROUS_SCHEME_RE}. See README → Security.
|
|
37
|
+
*/
|
|
38
|
+
declare const isSafeHref: (href: string | null | undefined) => href is string;
|
|
39
|
+
type ValidateURLOptions = {
|
|
40
|
+
customValidator?: (url: string) => boolean;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Shape-validate a URL: web schemes with a plausible host, app schemes from
|
|
44
|
+
* the `getSpecialUrlInfo` catalog, and bare E.164 phones. Rejects schemes
|
|
45
|
+
* matched by {@link DANGEROUS_SCHEME_RE}. See README → Validation.
|
|
46
|
+
*/
|
|
47
|
+
declare const validateURL: (url: string, options?: ValidateURLOptions) => boolean;
|
|
48
|
+
|
|
49
|
+
/** Discriminated input to {@link URLDecisions.forWrite}. */
|
|
50
|
+
type WriteInput = {
|
|
51
|
+
kind: 'text';
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
kind: 'href';
|
|
55
|
+
href: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'match';
|
|
58
|
+
match: LinkifyMatchLike;
|
|
59
|
+
};
|
|
60
|
+
type WriteResult = {
|
|
61
|
+
/** Canonical, gated, write-safe href ready to set on the mark. */
|
|
62
|
+
href: string;
|
|
63
|
+
/** Source offset; `0` for `href`/`match` inputs. */
|
|
64
|
+
start: number;
|
|
65
|
+
end: number;
|
|
66
|
+
};
|
|
67
|
+
type ReadDecision = {
|
|
68
|
+
/** Passes the full gate (`isSafeHref` + `isAllowedUri`) — required before any `window.open`. */
|
|
69
|
+
navigable: boolean;
|
|
70
|
+
};
|
|
71
|
+
type WriteOptions = {
|
|
72
|
+
/** Per-call override of the controller's `validate`. */
|
|
73
|
+
validate?: (url: string) => boolean;
|
|
74
|
+
};
|
|
75
|
+
interface URLDecisions {
|
|
76
|
+
/** Resolve a write candidate to its canonical, gated href(s). Returns `[]` when nothing passes. */
|
|
77
|
+
forWrite(input: WriteInput, opts?: WriteOptions): WriteResult[];
|
|
78
|
+
/** Read-side gate for render + navigation. */
|
|
79
|
+
forRead(href: string | null | undefined): ReadDecision;
|
|
80
|
+
/**
|
|
81
|
+
* Pure shape check — skips the gate stack on purpose. That keeps a tightened
|
|
82
|
+
* `isAllowedUri` policy out of autolink's "is the existing link still
|
|
83
|
+
* link-shaped?" cleanup pass.
|
|
84
|
+
*/
|
|
85
|
+
detect(text: string): boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Deps every interaction (input rule, paste rule, autolink, paste handler, click handler) reads. */
|
|
89
|
+
interface LinkContext {
|
|
90
|
+
type: MarkType;
|
|
91
|
+
editor: Editor;
|
|
92
|
+
/** URL Decisions pipeline; one per `createLinkContext` call (the extension allocates one per editor, cached on `storage.context`). */
|
|
93
|
+
urls: URLDecisions;
|
|
94
|
+
options: HyperlinkOptions;
|
|
95
|
+
/** Convenience accessor for `options.validate`. */
|
|
96
|
+
validate?: (url: string) => boolean;
|
|
97
|
+
/** Preview popover factory, or `null` when the host opted out. */
|
|
98
|
+
previewPopover: ((options: PreviewHyperlinkOptions) => HTMLElement | null) | null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
type SetHyperlinkAttributes = {
|
|
102
|
+
href: string;
|
|
103
|
+
target?: string | null;
|
|
104
|
+
title?: string | null;
|
|
105
|
+
image?: string | null;
|
|
106
|
+
} & Record<string, unknown>;
|
|
107
|
+
type EditHyperlinkAttributes = {
|
|
108
|
+
newText?: string;
|
|
109
|
+
newURL?: string;
|
|
110
|
+
title?: string;
|
|
111
|
+
image?: string;
|
|
112
|
+
};
|
|
113
|
+
interface HyperlinkPublicCommands<ReturnType> {
|
|
114
|
+
/** Write the hyperlink mark; returns `false` when `href` is missing or fails the gate. See README → Commands. */
|
|
115
|
+
setHyperlink: (attributes: SetHyperlinkAttributes) => ReturnType;
|
|
116
|
+
/** Remove the hyperlink mark from the current selection. */
|
|
117
|
+
unsetHyperlink: () => ReturnType;
|
|
118
|
+
/** Toggle the hyperlink mark; same gates as `setHyperlink`. */
|
|
119
|
+
toggleHyperlink: (attributes: SetHyperlinkAttributes) => ReturnType;
|
|
120
|
+
/** Open the create popover (configured `popovers.createHyperlink` or the prebuilt fallback); no-op only when the factory returns `null`. See README → Commands. */
|
|
121
|
+
openCreateHyperlinkPopover: (attributes?: Partial<HyperlinkAttributes>) => ReturnType;
|
|
122
|
+
editHyperlinkText: (text: string) => ReturnType;
|
|
123
|
+
editHyperlinkHref: (href: string) => ReturnType;
|
|
124
|
+
editHyperlink: (attributes?: EditHyperlinkAttributes) => ReturnType;
|
|
125
|
+
/** Migration alias for `setHyperlink` (drop-in `@tiptap/extension-link` compat). */
|
|
126
|
+
setLink: (attributes: SetHyperlinkAttributes) => ReturnType;
|
|
127
|
+
/** Migration alias for `unsetHyperlink`. */
|
|
128
|
+
unsetLink: () => ReturnType;
|
|
129
|
+
/** Migration alias for `toggleHyperlink`. */
|
|
130
|
+
toggleLink: (attributes: SetHyperlinkAttributes) => ReturnType;
|
|
131
|
+
}
|
|
132
|
+
declare module '@tiptap/core' {
|
|
133
|
+
interface Commands<ReturnType> {
|
|
134
|
+
hyperlink: HyperlinkPublicCommands<ReturnType>;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface LinkProtocolOptions {
|
|
139
|
+
scheme: string;
|
|
140
|
+
optionalSlashes?: boolean;
|
|
141
|
+
}
|
|
142
|
+
/** Context for the user `isAllowedUri` hook; mirrors `@tiptap/extension-link`. */
|
|
143
|
+
type IsAllowedUriContext = {
|
|
144
|
+
/** Built-in safety gate (`isSafeHref`). */
|
|
145
|
+
defaultValidate: (uri: string) => boolean;
|
|
146
|
+
/** Protocols registered via the `protocols` option. */
|
|
147
|
+
protocols: Array<LinkProtocolOptions | string>;
|
|
148
|
+
defaultProtocol: string;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* `Extra` extends the built-ins with consumer-typed fields; it defaults to
|
|
152
|
+
* `Record<string, unknown>` to keep the v2 open index signature. Example: README → TypeScript.
|
|
153
|
+
*/
|
|
154
|
+
type HyperlinkAttributes<Extra extends Record<string, unknown> = Record<string, unknown>> = {
|
|
155
|
+
href: string | null;
|
|
156
|
+
target: string | null;
|
|
157
|
+
rel: string | null;
|
|
158
|
+
class: string | null;
|
|
159
|
+
title: string | null;
|
|
160
|
+
image: string | null;
|
|
161
|
+
} & Extra;
|
|
162
|
+
type PreviewHyperlinkOptions = {
|
|
163
|
+
editor: Editor;
|
|
164
|
+
link: HTMLAnchorElement;
|
|
165
|
+
nodePos: number;
|
|
166
|
+
attrs: HyperlinkAttributes;
|
|
167
|
+
validate?: (url: string) => boolean;
|
|
168
|
+
/** Composed XSS + `isAllowedUri` gate; BYO popovers must call this before any `window.open`. */
|
|
169
|
+
isAllowedUri?: (uri: string) => boolean;
|
|
170
|
+
};
|
|
171
|
+
type CreateHyperlinkOptions = {
|
|
172
|
+
editor: Editor;
|
|
173
|
+
extensionName: string;
|
|
174
|
+
attributes: Partial<HyperlinkAttributes>;
|
|
175
|
+
validate?: (url: string) => boolean;
|
|
176
|
+
};
|
|
177
|
+
type EditHyperlinkOptions = {
|
|
178
|
+
editor: Editor;
|
|
179
|
+
link: HTMLAnchorElement;
|
|
180
|
+
/** Optional mark position; lets edit/back recover from ProseMirror replacing duplicate link DOM. */
|
|
181
|
+
nodePos?: number;
|
|
182
|
+
validate?: (url: string) => boolean;
|
|
183
|
+
/** Composed XSS + `isAllowedUri` gate to preserve preview policy across edit/back. */
|
|
184
|
+
isAllowedUri?: (uri: string) => boolean;
|
|
185
|
+
/** Override the default Back behaviour. Default re-opens the preview popover via `openPreviewHyperlink`. */
|
|
186
|
+
onBack?: () => void;
|
|
187
|
+
/** Mark name; defaults to `HYPERLINK_MARK_NAME`. */
|
|
188
|
+
markName?: string;
|
|
189
|
+
};
|
|
190
|
+
interface HyperlinkOptions {
|
|
191
|
+
autolink: boolean;
|
|
192
|
+
protocols: Array<LinkProtocolOptions | string>;
|
|
193
|
+
openOnClick: boolean;
|
|
194
|
+
linkOnPaste: boolean;
|
|
195
|
+
HTMLAttributes: Partial<HyperlinkAttributes>;
|
|
196
|
+
popovers: {
|
|
197
|
+
previewHyperlink?: ((options: PreviewHyperlinkOptions) => HTMLElement | null) | null;
|
|
198
|
+
editHyperlink?: ((options: EditHyperlinkOptions) => HTMLElement | null) | null;
|
|
199
|
+
createHyperlink?: ((options: CreateHyperlinkOptions) => HTMLElement | null) | null;
|
|
200
|
+
};
|
|
201
|
+
validate?: (url: string) => boolean;
|
|
202
|
+
/** Scheme used by `normalizeHref` to promote bare domains. Default `'https'`. See README → Options. */
|
|
203
|
+
defaultProtocol: string;
|
|
204
|
+
/** URI policy hook — runs AFTER `isSafeHref`, BEFORE the mark is written. Mirrors `@tiptap/extension-link`. */
|
|
205
|
+
isAllowedUri?: (uri: string, ctx: IsAllowedUriContext) => boolean;
|
|
206
|
+
/** Per-link autolink veto. Return `false` to skip autolinking a specific URI (manual `setHyperlink` still works). */
|
|
207
|
+
shouldAutoLink?: (uri: string) => boolean;
|
|
208
|
+
/** Click inside a link selects the whole mark range (editable mode only). Mirrors `@tiptap/extension-link`. */
|
|
209
|
+
enableClickSelection: boolean;
|
|
210
|
+
/** ArrowRight at the right edge of a link exits the mark. Mirrors `@tiptap/extension-link`. */
|
|
211
|
+
exitable: boolean;
|
|
212
|
+
}
|
|
213
|
+
/** Extension storage; one slot per editor instance. */
|
|
214
|
+
interface HyperlinkStorage {
|
|
215
|
+
/**
|
|
216
|
+
* Cached `LinkContext`; populated on first access so all four `add*`
|
|
217
|
+
* hooks share one URL Decisions pipeline instead of allocating per hook.
|
|
218
|
+
*/
|
|
219
|
+
context: LinkContext | null;
|
|
220
|
+
}
|
|
221
|
+
declare const Hyperlink: Mark<HyperlinkOptions, HyperlinkStorage>;
|
|
222
|
+
|
|
223
|
+
interface BuildPreviewOptionsFromAnchorArgs {
|
|
224
|
+
editor: Editor;
|
|
225
|
+
link: HTMLAnchorElement;
|
|
226
|
+
/** Prefer this ProseMirror position before falling back to DOM similarity. */
|
|
227
|
+
nodePos?: number;
|
|
228
|
+
/** Forwarded onto the returned options; usually the configured `validate` option. */
|
|
229
|
+
validate?: (url: string) => boolean;
|
|
230
|
+
/** Preserve the host's composed navigation gate when rebuilding preview from edit/back. */
|
|
231
|
+
isAllowedUri?: (uri: string) => boolean;
|
|
232
|
+
/** Mark name to look up; defaults to `'hyperlink'`. Override only if the schema mark was renamed. */
|
|
233
|
+
markName?: string;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Exists so the edit popover's Back button and BYO `editHyperlink` factories
|
|
237
|
+
* share one `posAtDOM → mark.attrs` lookup. The DOM `link.href` property is
|
|
238
|
+
* never the raw-href fallback — it resolves relative hrefs against
|
|
239
|
+
* `document.baseURI`, leaking the host origin into a stored attribute.
|
|
240
|
+
*/
|
|
241
|
+
declare function buildPreviewOptionsFromAnchor({ editor, link, nodePos: preferredNodePos, validate, isAllowedUri, markName }: BuildPreviewOptionsFromAnchorArgs): PreviewHyperlinkOptions;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Open the create-hyperlink popover anchored to the current selection.
|
|
245
|
+
* Returns `false` when the host opted out (factory returned `null`).
|
|
246
|
+
*/
|
|
247
|
+
declare function openCreateHyperlink(editor: Editor, attributes?: Partial<HyperlinkAttributes>): boolean;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Open the edit popover anchored to a hyperlink. The prebuilt popover's
|
|
251
|
+
* Back button closes over `opts`, so no extra wiring is needed to
|
|
252
|
+
* return to the preview.
|
|
253
|
+
*/
|
|
254
|
+
declare function openEditHyperlink(opts: EditHyperlinkOptions): void;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Returns `false` when the host opted out (factory returned `null`, e.g. a
|
|
258
|
+
* mobile bottom sheet). The click handler gates caret placement on it —
|
|
259
|
+
* `.focus()` on an opting-out host makes iOS Safari scroll the editor.
|
|
260
|
+
*/
|
|
261
|
+
declare function openPreviewHyperlink(opts: PreviewHyperlinkOptions): boolean;
|
|
262
|
+
|
|
263
|
+
type PopoverKind = 'preview' | 'edit' | 'create' | (string & {});
|
|
264
|
+
type VirtualCoordinates = {
|
|
265
|
+
getBoundingClientRect: () => {
|
|
266
|
+
x: number;
|
|
267
|
+
y: number;
|
|
268
|
+
width: number;
|
|
269
|
+
height: number;
|
|
270
|
+
};
|
|
271
|
+
contextElement?: HTMLElement;
|
|
272
|
+
};
|
|
273
|
+
interface ManagedPopover {
|
|
274
|
+
hide: () => void;
|
|
275
|
+
destroy: () => void;
|
|
276
|
+
updateReference: (referenceElement?: HTMLElement, coordinates?: VirtualCoordinates) => void;
|
|
277
|
+
}
|
|
278
|
+
type AdoptMetadata = {
|
|
279
|
+
/** The popover's root element — what subscribers attach focus rings, scroll-freezes, or DOM observers to. */
|
|
280
|
+
element: HTMLElement;
|
|
281
|
+
/** The anchor the popover is glued to — `null` for virtual-coords popovers (e.g. selection-anchored create). */
|
|
282
|
+
referenceElement: HTMLElement | null;
|
|
283
|
+
};
|
|
284
|
+
type ControllerState = {
|
|
285
|
+
kind: 'idle';
|
|
286
|
+
} | ({
|
|
287
|
+
kind: 'mounted';
|
|
288
|
+
popoverKind: PopoverKind;
|
|
289
|
+
} & AdoptMetadata);
|
|
290
|
+
interface PopoverController {
|
|
291
|
+
adopt(popover: ManagedPopover, kind: PopoverKind, metadata: AdoptMetadata): () => void;
|
|
292
|
+
close(): void;
|
|
293
|
+
reposition(referenceElement?: HTMLElement, coordinates?: VirtualCoordinates): void;
|
|
294
|
+
getState(): ControllerState;
|
|
295
|
+
subscribe(listener: (state: ControllerState) => void): () => void;
|
|
296
|
+
}
|
|
297
|
+
declare function getDefaultController(): PopoverController;
|
|
298
|
+
|
|
299
|
+
type PopoverAnchor = {
|
|
300
|
+
referenceElement: HTMLElement;
|
|
301
|
+
coordinates?: never;
|
|
302
|
+
} | {
|
|
303
|
+
referenceElement?: never;
|
|
304
|
+
coordinates: VirtualCoordinates;
|
|
305
|
+
};
|
|
306
|
+
type PopoverShellOptions = {
|
|
307
|
+
content: HTMLElement;
|
|
308
|
+
placement?: Placement;
|
|
309
|
+
offset?: number;
|
|
310
|
+
showArrow?: boolean;
|
|
311
|
+
className?: string;
|
|
312
|
+
zIndex?: number;
|
|
313
|
+
/**
|
|
314
|
+
* ARIA has no popover role — the shell carries its content's role
|
|
315
|
+
* (`toolbar`, `dialog`, …) and stays role-less when omitted.
|
|
316
|
+
*/
|
|
317
|
+
role?: string;
|
|
318
|
+
/** Same ARIA axis as `role` — shell-level so BYO content inherits the accessible name. */
|
|
319
|
+
ariaLabel?: string;
|
|
320
|
+
/**
|
|
321
|
+
* Nodes that must not light-dismiss (toggle triggers). When set, only these
|
|
322
|
+
* are ignored — not `referenceElement` — so a larger position surface (e.g.
|
|
323
|
+
* a toolbar bar) can still dismiss on sibling clicks. When omitted, the
|
|
324
|
+
* HTMLElement `referenceElement` is ignored instead.
|
|
325
|
+
*/
|
|
326
|
+
ignoreOutsideClickOn?: HTMLElement | HTMLElement[];
|
|
327
|
+
/**
|
|
328
|
+
* When false, `shift` only moves on the main axis so end-aligned menus
|
|
329
|
+
* (e.g. toolbar overflow) stay pinned to the reference’s end edge.
|
|
330
|
+
* @default true
|
|
331
|
+
*/
|
|
332
|
+
crossAxisShift?: boolean;
|
|
333
|
+
onShow?: () => void;
|
|
334
|
+
onHide?: () => void;
|
|
335
|
+
};
|
|
336
|
+
type PopoverOptions = PopoverAnchor & PopoverShellOptions;
|
|
337
|
+
/**
|
|
338
|
+
* One-shot once opened: hiding releases the controller's ownership and nothing
|
|
339
|
+
* re-adopts, so `show()` will not reopen it. Build a new popover instead — a
|
|
340
|
+
* re-shown one would sit outside the single-popover invariant, invisible to
|
|
341
|
+
* `close()` and never evicted by the next `adopt()`.
|
|
342
|
+
*/
|
|
343
|
+
interface Popover {
|
|
344
|
+
element: HTMLElement;
|
|
345
|
+
/** No-op once the popover has been hidden or destroyed. */
|
|
346
|
+
show: () => void;
|
|
347
|
+
/** Terminal once shown. Before the first `show()` it no-ops and keeps ownership. */
|
|
348
|
+
hide: () => void;
|
|
349
|
+
destroy: () => void;
|
|
350
|
+
isVisible: () => boolean;
|
|
351
|
+
setContent: (content: HTMLElement) => void;
|
|
352
|
+
updateReference: (referenceElement?: HTMLElement, coordinates?: VirtualCoordinates) => void;
|
|
353
|
+
}
|
|
354
|
+
declare const DEFAULT_OFFSET = 8;
|
|
355
|
+
declare function createPopover(options: PopoverOptions): Popover;
|
|
356
|
+
|
|
357
|
+
/** Hide the shared tooltip bubble and cancel any pending show. */
|
|
358
|
+
declare function hideTooltip(): void;
|
|
359
|
+
/** Show `label` above `target` after a short hover/focus delay. Returns a detach function for surfaces that re-render in place. */
|
|
360
|
+
declare function attachTooltip(target: HTMLElement, label: string): () => void;
|
|
361
|
+
|
|
362
|
+
declare function createHyperlinkPopover(options: CreateHyperlinkOptions): HTMLElement;
|
|
363
|
+
|
|
364
|
+
declare function editHyperlinkPopover(options: EditHyperlinkOptions): HTMLElement;
|
|
365
|
+
|
|
366
|
+
declare function previewHyperlinkPopover(options: PreviewHyperlinkOptions): HTMLElement;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* `window.open` features string for safe navigation — every
|
|
370
|
+
* `window.open(href, '_blank', …)` call needs this explicit arg or the
|
|
371
|
+
* opened tab can read `window.opener` and the Referer leaks. Re-exported
|
|
372
|
+
* so downstream popovers pin the same value.
|
|
373
|
+
*/
|
|
374
|
+
declare const SAFE_WINDOW_FEATURES: "noopener,noreferrer";
|
|
375
|
+
|
|
376
|
+
declare const copyToClipboard: (text: string, callback?: (success: boolean) => void) => Promise<boolean>;
|
|
377
|
+
|
|
378
|
+
declare const createHTMLElement: <K extends keyof HTMLElementTagNameMap>(type: K, props?: Partial<HTMLElementTagNameMap[K]>) => HTMLElementTagNameMap[K];
|
|
379
|
+
|
|
380
|
+
interface IconProps {
|
|
381
|
+
size?: number;
|
|
382
|
+
fill?: string;
|
|
383
|
+
}
|
|
384
|
+
declare const Copy: ({ size, fill }?: IconProps) => string;
|
|
385
|
+
declare const LinkOff: ({ size, fill }?: IconProps) => string;
|
|
386
|
+
declare const Pencil: ({ size, fill }?: IconProps) => string;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Special URL schemes and well-known domains the extension classifies
|
|
390
|
+
* for the preview popover.
|
|
391
|
+
*
|
|
392
|
+
* Catalog source: https://github.com/bhagyas/app-urls
|
|
393
|
+
*/
|
|
394
|
+
/**
|
|
395
|
+
* String-literal union so consumers can declare a
|
|
396
|
+
* `Partial<Record<SpecialUrlType, …>>` icon map with exhaustive
|
|
397
|
+
* autocomplete — type-only, zero runtime bytes. Naming convention lives
|
|
398
|
+
* in this package's AGENTS.md.
|
|
399
|
+
*/
|
|
400
|
+
type SpecialUrlType = 'email' | 'phone' | 'sms' | 'facetime' | 'facetime-audio' | 'whatsapp' | 'telegram' | 'discord' | 'skype' | 'slack' | 'twitter' | 'facebook' | 'instagram' | 'linkedin' | 'snapchat' | 'reddit' | 'tiktok' | 'zoom' | 'teams' | 'webex' | 'meet' | 'calendar' | 'reminders' | 'contacts' | 'maps' | 'music' | 'apple-tv' | 'notes' | 'photos' | 'shortcuts' | 'app-store' | 'github' | 'gitlab' | 'vscode' | 'notion' | 'obsidian' | 'figma' | 'youtube' | 'spotify' | 'netflix' | 'twitch' | 'amazon' | 'uber' | 'lyft';
|
|
401
|
+
type SpecialUrlInfo = {
|
|
402
|
+
type: SpecialUrlType;
|
|
403
|
+
title: string;
|
|
404
|
+
category: 'communication' | 'social' | 'productivity' | 'entertainment' | 'shopping' | 'development' | 'apple' | 'other';
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Classify `url` against the catalog (scheme prefix or host suffix).
|
|
408
|
+
* Returns `null` for plain web URLs — the consumer should fall back to
|
|
409
|
+
* a generic favicon. Mapping `type`/`category` to an icon is the
|
|
410
|
+
* consumer's job; the extension stays brand-neutral on purpose.
|
|
411
|
+
*/
|
|
412
|
+
declare const getSpecialUrlInfo: (url: string) => SpecialUrlInfo | null;
|
|
413
|
+
|
|
414
|
+
export { type AdoptMetadata, type BuildPreviewOptionsFromAnchorArgs, type ControllerState, Copy, type CreateHyperlinkOptions, DANGEROUS_SCHEME_RE, DEFAULT_OFFSET, type EditHyperlinkAttributes, type EditHyperlinkOptions, Hyperlink, type HyperlinkAttributes, type HyperlinkOptions, type HyperlinkPublicCommands, type HyperlinkStorage, type IconProps, type IsAllowedUriContext, LinkOff, type LinkProtocolOptions, type LinkifyMatchLike, Pencil, type Popover, type PopoverController, type PopoverKind, type PopoverOptions, type PreviewHyperlinkOptions, SAFE_WINDOW_FEATURES, type SetHyperlinkAttributes, type SpecialUrlInfo, type SpecialUrlType, type ValidateURLOptions, type VirtualCoordinates, attachTooltip, buildPreviewOptionsFromAnchor, copyToClipboard, createHTMLElement, createHyperlinkPopover, createPopover, Hyperlink as default, editHyperlinkPopover, getDefaultController, getSpecialUrlInfo, hideTooltip, isSafeHref, normalizeHref, openCreateHyperlink, openEditHyperlink, openPreviewHyperlink, previewHyperlinkPopover, validateURL };
|