@prosekit/web 0.7.12 → 0.8.0-beta.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/dist/{get-default-state-BzBimBWi.js → get-default-state.js} +2 -3
- package/dist/get-default-state.js.map +1 -0
- package/dist/{get-safe-editor-view-Dt9Amrcn.js → get-safe-editor-view.js} +2 -2
- package/dist/get-safe-editor-view.js.map +1 -0
- package/dist/prosekit-web-autocomplete.d.ts.map +1 -1
- package/dist/prosekit-web-autocomplete.js +7 -22
- package/dist/prosekit-web-autocomplete.js.map +1 -1
- package/dist/prosekit-web-block-handle.js +53 -80
- package/dist/prosekit-web-block-handle.js.map +1 -1
- package/dist/prosekit-web-drop-indicator.js +3 -6
- package/dist/prosekit-web-drop-indicator.js.map +1 -1
- package/dist/prosekit-web-inline-popover.js +2 -9
- package/dist/prosekit-web-inline-popover.js.map +1 -1
- package/dist/prosekit-web-popover.js +1 -4
- package/dist/prosekit-web-popover.js.map +1 -1
- package/dist/prosekit-web-resizable.d.ts.map +1 -1
- package/dist/prosekit-web-resizable.js +30 -13
- package/dist/prosekit-web-resizable.js.map +1 -1
- package/dist/prosekit-web-table-handle.js +76 -48
- package/dist/prosekit-web-table-handle.js.map +1 -1
- package/dist/prosekit-web-tooltip.js +1 -4
- package/dist/prosekit-web-tooltip.js.map +1 -1
- package/dist/prosekit-web.js +1 -1
- package/dist/prosekit-web.js.map +1 -1
- package/dist/{use-editor-extension-B2WuUfnd.js → use-editor-extension.js} +2 -3
- package/dist/use-editor-extension.js.map +1 -0
- package/dist/{use-scrolling-BjVzAkiZ.js → use-scrolling.js} +2 -4
- package/dist/use-scrolling.js.map +1 -0
- package/package.json +11 -11
- package/src/components/autocomplete/autocomplete-list/setup.ts +3 -2
- package/src/components/autocomplete/autocomplete-popover/setup.ts +2 -2
- package/src/components/block-handle/block-handle-draggable/set-drag-preview.ts +9 -10
- package/src/components/block-handle/block-handle-draggable/setup.ts +5 -10
- package/src/components/block-handle/block-handle-popover/pointer-move.ts +2 -10
- package/src/components/block-handle/block-handle-popover/setup.ts +1 -3
- package/src/components/resizable/resizable-root/types.ts +37 -3
- package/src/constants.ts +1 -0
- package/src/utils/get-client-rect.ts +47 -9
- package/dist/get-default-state-BzBimBWi.js.map +0 -1
- package/dist/get-safe-editor-view-Dt9Amrcn.js.map +0 -1
- package/dist/inject-style-BaFaVQvj.js +0 -76
- package/dist/inject-style-BaFaVQvj.js.map +0 -1
- package/dist/use-editor-extension-B2WuUfnd.js.map +0 -1
- package/dist/use-scrolling-BjVzAkiZ.js.map +0 -1
- package/src/utils/get-box-element.ts +0 -20
- package/src/utils/throttle.ts +0 -17
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '@aria-ui/core'
|
|
12
12
|
import { useOverlayPositionerState } from '@aria-ui/overlay/elements'
|
|
13
13
|
import { usePresence } from '@aria-ui/presence'
|
|
14
|
-
import { defineKeymap,
|
|
14
|
+
import { defineKeymap, withPriority, type Editor, type Priority } from '@prosekit/core'
|
|
15
15
|
import { AutocompleteRule, defineAutocomplete, type MatchHandler } from '@prosekit/extensions/autocomplete'
|
|
16
16
|
|
|
17
17
|
import { useEditorExtension } from '../../../hooks/use-editor-extension.ts'
|
|
@@ -164,6 +164,6 @@ function useEscapeKeydown(
|
|
|
164
164
|
handler: () => boolean,
|
|
165
165
|
): void {
|
|
166
166
|
const keymap = { Escape: handler }
|
|
167
|
-
const extension = withPriority(defineKeymap(keymap), Priority.highest)
|
|
167
|
+
const extension = withPriority(defineKeymap(keymap), 4 satisfies typeof Priority.highest)
|
|
168
168
|
useEditorExtension(host, editor, extension)
|
|
169
169
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { DRAGGING_CLASS_NAME } from '../../../constants.ts'
|
|
1
2
|
import { assignStyles } from '../../../utils/assign-styles.ts'
|
|
2
|
-
import { deepCloneElement } from '../../../utils/clone-element.ts'
|
|
3
3
|
import { getClientRect } from '../../../utils/get-client-rect.ts'
|
|
4
|
-
import { injectStyle } from '../../../utils/inject-style.ts'
|
|
5
4
|
import { maxZIndex } from '../../../utils/max-z-index.ts'
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -16,7 +15,7 @@ import { maxZIndex } from '../../../utils/max-z-index.ts'
|
|
|
16
15
|
* - Removes the container from the document body after the next frame.
|
|
17
16
|
*/
|
|
18
17
|
export function setDragPreview(event: DragEvent, element: HTMLElement): void {
|
|
19
|
-
const { top, bottom, left, right } = getClientRect(element)
|
|
18
|
+
const { top, bottom, left, right } = getClientRect(element, { left: true, right: true, top: true, bottom: true })
|
|
20
19
|
const width = right - left
|
|
21
20
|
const height = bottom - top
|
|
22
21
|
const elementX = left
|
|
@@ -28,6 +27,10 @@ export function setDragPreview(event: DragEvent, element: HTMLElement): void {
|
|
|
28
27
|
|
|
29
28
|
const container = document.createElement('div')
|
|
30
29
|
|
|
30
|
+
// Add some class names so that all styles applied to
|
|
31
|
+
// given class names can also be applied to the drag preview.
|
|
32
|
+
container.classList.add('ProseMirror', DRAGGING_CLASS_NAME)
|
|
33
|
+
|
|
31
34
|
// If outsideX is positive, the point is at the left side of the element.
|
|
32
35
|
const outsideX = Math.round(elementX - clientX)
|
|
33
36
|
// If outsideY is positive, the point is above the element.
|
|
@@ -66,19 +69,15 @@ export function setDragPreview(event: DragEvent, element: HTMLElement): void {
|
|
|
66
69
|
height: `${height + borderY}px`,
|
|
67
70
|
})
|
|
68
71
|
|
|
69
|
-
const
|
|
72
|
+
const clonedElement = element.cloneNode(true) as HTMLElement
|
|
70
73
|
|
|
71
74
|
// A hardcoded opacity.
|
|
72
|
-
clonedElement.style.setProperty('opacity', '0.
|
|
73
|
-
// The bounding client rect doesn't include the margin, so we need to remove
|
|
74
|
-
// the margin too from the cloned element so that it can fit the container.
|
|
75
|
-
clonedElement.style.setProperty('margin', '0', 'important')
|
|
75
|
+
clonedElement.style.setProperty('opacity', '0.8', 'important')
|
|
76
76
|
// Hide the outline of the cloned element.
|
|
77
77
|
clonedElement.style.setProperty('outline-color', 'transparent', 'important')
|
|
78
78
|
|
|
79
|
-
document.body.appendChild(container)
|
|
80
79
|
container.appendChild(clonedElement)
|
|
81
|
-
|
|
80
|
+
document.body.appendChild(container)
|
|
82
81
|
|
|
83
82
|
event.dataTransfer?.setDragImage(container, Math.max(-outsideX, 0), Math.max(-outsideY, 0))
|
|
84
83
|
|
|
@@ -6,7 +6,7 @@ import { Fragment, Slice } from '@prosekit/pm/model'
|
|
|
6
6
|
import { NodeSelection } from '@prosekit/pm/state'
|
|
7
7
|
import type { EditorView } from '@prosekit/pm/view'
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { DRAGGING_CLASS_NAME } from '../../../constants.ts'
|
|
10
10
|
import { getSafeEditorView } from '../../../utils/get-safe-editor-view.ts'
|
|
11
11
|
import { blockPopoverContext, draggingContext, type BlockPopoverContext, type HoverState } from '../context.ts'
|
|
12
12
|
|
|
@@ -36,7 +36,7 @@ export function useBlockHandleDraggable(
|
|
|
36
36
|
const hoverState = context.get()
|
|
37
37
|
|
|
38
38
|
if (view && hoverState) {
|
|
39
|
-
view.dom.classList.add(
|
|
39
|
+
view.dom.classList.add(DRAGGING_CLASS_NAME)
|
|
40
40
|
createDraggingPreview(view, hoverState, event)
|
|
41
41
|
setViewDragging(view, hoverState)
|
|
42
42
|
}
|
|
@@ -47,7 +47,7 @@ export function useBlockHandleDraggable(
|
|
|
47
47
|
|
|
48
48
|
const view = getSafeEditorView(state.editor.get())
|
|
49
49
|
if (view) {
|
|
50
|
-
view.dom.classList.remove(
|
|
50
|
+
view.dom.classList.remove(DRAGGING_CLASS_NAME)
|
|
51
51
|
}
|
|
52
52
|
})
|
|
53
53
|
|
|
@@ -92,15 +92,10 @@ function createDraggingPreview(view: EditorView, hoverState: HoverState, event:
|
|
|
92
92
|
return
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
const boxElement = getBoxElement(element)
|
|
96
|
-
if (!boxElement || !isHTMLElement(boxElement)) {
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
|
|
100
95
|
event.dataTransfer.clearData()
|
|
101
|
-
event.dataTransfer.setData('text/html',
|
|
96
|
+
event.dataTransfer.setData('text/html', element.outerHTML)
|
|
102
97
|
event.dataTransfer.effectAllowed = 'copyMove'
|
|
103
|
-
setDragPreview(event,
|
|
98
|
+
setDragPreview(event, element)
|
|
104
99
|
|
|
105
100
|
return
|
|
106
101
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { VirtualElement } from '@floating-ui/dom'
|
|
2
|
-
import { isElement, isHTMLElement, isTextNode } from '@ocavue/utils'
|
|
2
|
+
import { isElement, isHTMLElement, isTextNode, throttle } from '@ocavue/utils'
|
|
3
3
|
import { defineDOMEventHandler, union, type PlainExtension } from '@prosekit/core'
|
|
4
4
|
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
5
5
|
import type { EditorView } from '@prosekit/pm/view'
|
|
6
6
|
|
|
7
7
|
import { getClientRect } from '../../../utils/get-client-rect.ts'
|
|
8
|
-
import { throttle } from '../../../utils/throttle.ts'
|
|
9
8
|
import type { HoverState } from '../context.ts'
|
|
10
9
|
|
|
11
10
|
export type ElementHoverHandler = (
|
|
@@ -186,14 +185,7 @@ function findOuterRect(node: Node): Rect | undefined {
|
|
|
186
185
|
return
|
|
187
186
|
}
|
|
188
187
|
|
|
189
|
-
|
|
190
|
-
const style = node.ownerDocument.defaultView?.getComputedStyle(node)
|
|
191
|
-
const marginLeft = style && Number.parseInt(style.marginLeft, 10) || 0
|
|
192
|
-
const marginRight = style && Number.parseInt(style.marginRight, 10) || 0
|
|
193
|
-
const left = rect.left - marginLeft
|
|
194
|
-
const right = rect.right + marginRight
|
|
195
|
-
|
|
196
|
-
return { top: rect.top, bottom: rect.bottom, left, right }
|
|
188
|
+
return getClientRect(node, { left: true, right: true })
|
|
197
189
|
}
|
|
198
190
|
|
|
199
191
|
function findFirstLineRectInNode(node: Node): Rect | undefined {
|
|
@@ -64,7 +64,5 @@ function useHoverExtension(
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function isHoverStateEqual(a: HoverState | null, b: HoverState | null) {
|
|
67
|
-
|
|
68
|
-
if (!a || !b) return false
|
|
69
|
-
return a.pos === b.pos && a.node.eq(b.node)
|
|
67
|
+
return (!a && !b) || (a && b && a.pos === b.pos && a.node.eq(b.node))
|
|
70
68
|
}
|
|
@@ -1,16 +1,50 @@
|
|
|
1
1
|
import type { EventDeclarations, PropDeclarations } from '@aria-ui/core'
|
|
2
2
|
|
|
3
|
+
import { isFinitePositiveNumber } from '../../../utils/is-finite-positive-number.ts'
|
|
4
|
+
|
|
3
5
|
export interface ResizableRootProps {
|
|
4
6
|
width: number | null
|
|
5
7
|
height: number | null
|
|
6
8
|
aspectRatio: number | null
|
|
7
9
|
}
|
|
8
10
|
|
|
11
|
+
function fromNumberAttribute(value: string | null): number | null {
|
|
12
|
+
if (typeof value === 'string') {
|
|
13
|
+
const number = Number.parseFloat(value)
|
|
14
|
+
if (isFinitePositiveNumber(number)) {
|
|
15
|
+
return number
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function toNumberAttribute(value: number | null): string | null {
|
|
22
|
+
if (typeof value === 'number') {
|
|
23
|
+
return `${value}`
|
|
24
|
+
}
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
9
28
|
/** @internal */
|
|
10
29
|
export const resizableRootProps: PropDeclarations<ResizableRootProps> = {
|
|
11
|
-
width: {
|
|
12
|
-
|
|
13
|
-
|
|
30
|
+
width: {
|
|
31
|
+
default: null,
|
|
32
|
+
attribute: 'data-width',
|
|
33
|
+
fromAttribute: fromNumberAttribute,
|
|
34
|
+
toAttribute: toNumberAttribute,
|
|
35
|
+
},
|
|
36
|
+
height: {
|
|
37
|
+
default: null,
|
|
38
|
+
attribute: 'data-height',
|
|
39
|
+
fromAttribute: fromNumberAttribute,
|
|
40
|
+
toAttribute: toNumberAttribute,
|
|
41
|
+
},
|
|
42
|
+
aspectRatio: {
|
|
43
|
+
default: null,
|
|
44
|
+
attribute: 'data-aspect-ratio',
|
|
45
|
+
fromAttribute: fromNumberAttribute,
|
|
46
|
+
toAttribute: toNumberAttribute,
|
|
47
|
+
},
|
|
14
48
|
}
|
|
15
49
|
|
|
16
50
|
export interface ResizableRootEvents {
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DRAGGING_CLASS_NAME = 'prosekit-dragging'
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
* Similar to `element.getBoundingClientRect`, but handles `display: contents` elements.
|
|
3
|
-
*/
|
|
4
|
-
export function getClientRect(element: Element): {
|
|
1
|
+
interface Rect {
|
|
5
2
|
top: number
|
|
6
|
-
right: number
|
|
7
3
|
bottom: number
|
|
4
|
+
right: number
|
|
8
5
|
left: number
|
|
9
|
-
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface IncludeExtraOptions {
|
|
9
|
+
top?: boolean
|
|
10
|
+
bottom?: boolean
|
|
11
|
+
right?: boolean
|
|
12
|
+
left?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Similar to `element.getBoundingClientRect`, but handles `display: contents` CSS
|
|
17
|
+
* property and optionally includes margins and outlines.
|
|
18
|
+
*/
|
|
19
|
+
export function getClientRect(element: Element, includeExtra?: IncludeExtraOptions | false): Rect {
|
|
10
20
|
const rect = element.getBoundingClientRect()
|
|
11
21
|
if (rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0) {
|
|
12
22
|
// Suspiciously rect, probably an element with `display: contents`, in
|
|
13
23
|
// which case `element.getClientRects()` will return an empty array.
|
|
14
24
|
if (element.getClientRects().length === 0) {
|
|
15
|
-
const children =
|
|
16
|
-
const rects = children.map(child => getClientRect(child))
|
|
25
|
+
const children = [...element.children]
|
|
26
|
+
const rects = children.map(child => getClientRect(child, includeExtra))
|
|
17
27
|
if (rects.length === 0) {
|
|
18
28
|
return rect
|
|
19
29
|
}
|
|
@@ -31,5 +41,33 @@ export function getClientRect(element: Element): {
|
|
|
31
41
|
return { top, bottom, left, right }
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
|
-
return rect
|
|
44
|
+
return includeExtra ? addExtra(element, rect, includeExtra) : rect
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function addExtra(element: Element, rect: Rect, options: IncludeExtraOptions): Rect {
|
|
48
|
+
const view = element.ownerDocument?.defaultView
|
|
49
|
+
if (!view) {
|
|
50
|
+
return rect
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const style = view.getComputedStyle(element)
|
|
54
|
+
const marginTop = options.top ? Number.parseFloat(style.marginTop) || 0 : 0
|
|
55
|
+
const marginBottom = options.bottom ? Number.parseFloat(style.marginBottom) || 0 : 0
|
|
56
|
+
const marginRight = options.right ? Number.parseFloat(style.marginRight) || 0 : 0
|
|
57
|
+
const marginLeft = options.left ? Number.parseFloat(style.marginLeft) || 0 : 0
|
|
58
|
+
|
|
59
|
+
const outlineWidth = Number.parseFloat(style.outlineWidth) || 0
|
|
60
|
+
const outlineOffset = Number.parseFloat(style.outlineOffset) || 0
|
|
61
|
+
const outline = Math.max(outlineWidth + outlineOffset, 0)
|
|
62
|
+
const outlineTop = options.top ? outline : 0
|
|
63
|
+
const outlineBottom = options.bottom ? outline : 0
|
|
64
|
+
const outlineRight = options.right ? outline : 0
|
|
65
|
+
const outlineLeft = options.left ? outline : 0
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
top: rect.top - Math.max(marginTop, outlineTop),
|
|
69
|
+
bottom: rect.bottom + Math.max(marginBottom, outlineBottom),
|
|
70
|
+
right: rect.right + Math.max(marginRight, outlineRight),
|
|
71
|
+
left: rect.left - Math.max(marginLeft, outlineLeft),
|
|
72
|
+
}
|
|
35
73
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-default-state-BzBimBWi.js","names":[],"sources":["../src/utils/get-default-state.ts"],"sourcesContent":["import { createSignal, type PropDeclarations, type SignalState } from '@aria-ui/core'\n\nexport function getStateWithDefaults<\n Props extends Record<string, any> = Record<string, any>,\n>(\n state: Partial<SignalState<Props>>,\n props: PropDeclarations<Props>,\n): SignalState<Props> {\n const merged = { ...state } as SignalState<Props>\n\n for (const key of Object.keys(props) as (keyof Props)[]) {\n if (!merged[key]) {\n merged[key] = createSignal(props[key].default)\n }\n }\n\n return merged\n}\n"],"mappings":";;;AAEA,SAAgB,qBAGd,OACA,OACoB;CACpB,MAAM,SAAS,EAAE,GAAG,OAAO;AAE3B,MAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAClC,KAAI,CAAC,OAAO,KACV,QAAO,OAAO,aAAa,MAAM,KAAK,QAAQ;AAIlD,QAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-safe-editor-view-Dt9Amrcn.js","names":[],"sources":["../src/utils/get-safe-editor-view.ts"],"sourcesContent":["import type { Editor } from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\n/**\n * @internal\n */\nexport function getSafeEditorView(editor?: Editor | null): EditorView | undefined {\n if (!editor || !editor.mounted) return\n return editor.view\n}\n"],"mappings":";;;;AAMA,SAAgB,kBAAkB,QAAgD;AAChF,KAAI,CAAC,UAAU,CAAC,OAAO,QAAS;AAChC,QAAO,OAAO"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { getDocument, getId } from "@ocavue/utils";
|
|
2
|
-
|
|
3
|
-
//#region src/utils/clone-element.ts
|
|
4
|
-
/**
|
|
5
|
-
* Creates a deep clone of an Element, including all computed styles so that
|
|
6
|
-
* it looks almost exactly the same as the original element.
|
|
7
|
-
*/
|
|
8
|
-
function deepCloneElement(element, important = false) {
|
|
9
|
-
const clonedElement = element.cloneNode(true);
|
|
10
|
-
return [clonedElement, deepCopyStyles(element, clonedElement, important)];
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Creates a clone of an Element, including all computed styles so that
|
|
14
|
-
* it looks similar enough to the original element.
|
|
15
|
-
*/
|
|
16
|
-
function cloneElement(element, important = false) {
|
|
17
|
-
const clonedElement = element.cloneNode();
|
|
18
|
-
return [clonedElement, copyStyles(element, clonedElement, important)];
|
|
19
|
-
}
|
|
20
|
-
function deepCopyStyles(source, target, important) {
|
|
21
|
-
const sources = [source];
|
|
22
|
-
const targets = [target];
|
|
23
|
-
const styles = [];
|
|
24
|
-
while (sources.length > 0 && sources.length === targets.length) {
|
|
25
|
-
const source = sources.pop();
|
|
26
|
-
const target = targets.pop();
|
|
27
|
-
if (!source || !target) break;
|
|
28
|
-
const style = copyStyles(source, target, important);
|
|
29
|
-
if (style) styles.push(style);
|
|
30
|
-
sources.push(...source.children);
|
|
31
|
-
targets.push(...target.children);
|
|
32
|
-
}
|
|
33
|
-
return styles.join("\n");
|
|
34
|
-
}
|
|
35
|
-
function copyStyles(source, target, important) {
|
|
36
|
-
if (!source || !target) return "";
|
|
37
|
-
const view = source.ownerDocument?.defaultView;
|
|
38
|
-
if (!view) return "";
|
|
39
|
-
const sourceStyle = view.getComputedStyle(source);
|
|
40
|
-
const targetStyle = target.style;
|
|
41
|
-
if (!sourceStyle || !targetStyle) return "";
|
|
42
|
-
for (const key of sourceStyle) targetStyle.setProperty(key, sourceStyle.getPropertyValue(key), important ? "important" : sourceStyle.getPropertyPriority(key) || "");
|
|
43
|
-
const styles = [];
|
|
44
|
-
for (const pseudoSelector of [":before", ":after"]) {
|
|
45
|
-
const sourcePseudoStyle = view.getComputedStyle(source, pseudoSelector);
|
|
46
|
-
const targetPseudoStyle = view.getComputedStyle(target, pseudoSelector);
|
|
47
|
-
if (!sourcePseudoStyle) continue;
|
|
48
|
-
const content = sourcePseudoStyle.getPropertyValue("content");
|
|
49
|
-
if (!(content && content !== "none" && content !== "normal")) continue;
|
|
50
|
-
const cssProps = [];
|
|
51
|
-
for (const property of sourcePseudoStyle) {
|
|
52
|
-
const sourceValue = sourcePseudoStyle.getPropertyValue(property);
|
|
53
|
-
const sourcePriority = sourcePseudoStyle.getPropertyPriority(property);
|
|
54
|
-
const targetValue = targetPseudoStyle.getPropertyValue(property);
|
|
55
|
-
const targetPriority = targetPseudoStyle.getPropertyPriority(property);
|
|
56
|
-
if (sourceValue !== targetValue || sourcePriority !== targetPriority) cssProps.push(`${property}: ${sourceValue}${sourcePriority ? " !important" : ""};`);
|
|
57
|
-
}
|
|
58
|
-
const uniqueClassName = `clone-pseudo-element-${getId()}`;
|
|
59
|
-
target.classList.add(uniqueClassName);
|
|
60
|
-
styles.push(`.${uniqueClassName}${pseudoSelector} { ${cssProps.join(" ")} }`);
|
|
61
|
-
}
|
|
62
|
-
return styles.join("\n");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
//#endregion
|
|
66
|
-
//#region src/utils/inject-style.ts
|
|
67
|
-
function injectStyle(container, styleText) {
|
|
68
|
-
if (!styleText) return;
|
|
69
|
-
const style = getDocument(container).createElement("style");
|
|
70
|
-
style.textContent = styleText;
|
|
71
|
-
container.appendChild(style);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
//#endregion
|
|
75
|
-
export { cloneElement as n, deepCloneElement as r, injectStyle as t };
|
|
76
|
-
//# sourceMappingURL=inject-style-BaFaVQvj.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inject-style-BaFaVQvj.js","names":[],"sources":["../src/utils/clone-element.ts","../src/utils/inject-style.ts"],"sourcesContent":["import { getId } from '@ocavue/utils'\n\n/**\n * Creates a deep clone of an Element, including all computed styles so that\n * it looks almost exactly the same as the original element.\n */\nexport function deepCloneElement<T extends Element>(element: T, important = false): [T, string] {\n const clonedElement = element.cloneNode(true) as T\n const style = deepCopyStyles(element, clonedElement, important)\n return [clonedElement, style]\n}\n\n/**\n * Creates a clone of an Element, including all computed styles so that\n * it looks similar enough to the original element.\n */\nexport function cloneElement<T extends Element>(element: T, important = false): [T, string] {\n const clonedElement = element.cloneNode() as T\n const style = copyStyles(element, clonedElement, important)\n return [clonedElement, style]\n}\n\nfunction deepCopyStyles(source: Element, target: Element, important: boolean): string {\n const sources = [source]\n const targets = [target]\n const styles: string[] = []\n\n while (sources.length > 0 && sources.length === targets.length) {\n const source = sources.pop()\n const target = targets.pop()\n\n if (!source || !target) {\n break\n }\n\n const style = copyStyles(source, target, important)\n if (style) {\n styles.push(style)\n }\n\n sources.push(...source.children)\n targets.push(...target.children)\n }\n\n return styles.join('\\n')\n}\n\nfunction copyStyles(source: Element, target: Element, important: boolean): string {\n if (!source || !target) {\n return ''\n }\n\n const view = source.ownerDocument?.defaultView\n if (!view) {\n return ''\n }\n\n // Known issue: pseudo styles are not copied.\n const sourceStyle = view.getComputedStyle(source)\n const targetStyle = (target as HTMLElement | SVGElement | MathMLElement).style\n\n if (!sourceStyle || !targetStyle) {\n return ''\n }\n\n for (const key of sourceStyle) {\n targetStyle.setProperty(\n key,\n sourceStyle.getPropertyValue(key),\n // Enforce important to avoid the style being overridden when the element\n // is connected to the page.\n // See https://github.com/prosekit/prosekit/issues/1185 for more details.\n important ? 'important' : (sourceStyle.getPropertyPriority(key) || ''),\n )\n }\n\n const styles: string[] = []\n for (const pseudoSelector of [':before', ':after']) {\n const sourcePseudoStyle = view.getComputedStyle(source, pseudoSelector)\n const targetPseudoStyle = view.getComputedStyle(target, pseudoSelector)\n\n if (!sourcePseudoStyle) {\n continue\n }\n\n const content = sourcePseudoStyle.getPropertyValue('content')\n const hasPseudoElement = content && content !== 'none' && content !== 'normal'\n\n if (!hasPseudoElement) {\n continue\n }\n\n const cssProps: string[] = []\n for (const property of sourcePseudoStyle) {\n const sourceValue = sourcePseudoStyle.getPropertyValue(property)\n const sourcePriority = sourcePseudoStyle.getPropertyPriority(property)\n const targetValue = targetPseudoStyle.getPropertyValue(property)\n const targetPriority = targetPseudoStyle.getPropertyPriority(property)\n if (sourceValue !== targetValue || sourcePriority !== targetPriority) {\n cssProps.push(`${property}: ${sourceValue}${sourcePriority ? ' !important' : ''};`)\n }\n }\n\n const uniqueClassName = `clone-pseudo-element-${getId()}`\n target.classList.add(uniqueClassName)\n styles.push(`.${uniqueClassName}${pseudoSelector} { ${cssProps.join(' ')} }`)\n }\n\n return styles.join('\\n')\n}\n","import { getDocument } from '@ocavue/utils'\n\nexport function injectStyle(container: HTMLElement, styleText: string): void {\n if (!styleText) {\n return\n }\n const document = getDocument(container)\n const style = document.createElement('style')\n style.textContent = styleText\n container.appendChild(style)\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,iBAAoC,SAAY,YAAY,OAAoB;CAC9F,MAAM,gBAAgB,QAAQ,UAAU,KAAK;AAE7C,QAAO,CAAC,eADM,eAAe,SAAS,eAAe,UAAU,CAClC;;;;;;AAO/B,SAAgB,aAAgC,SAAY,YAAY,OAAoB;CAC1F,MAAM,gBAAgB,QAAQ,WAAW;AAEzC,QAAO,CAAC,eADM,WAAW,SAAS,eAAe,UAAU,CAC9B;;AAG/B,SAAS,eAAe,QAAiB,QAAiB,WAA4B;CACpF,MAAM,UAAU,CAAC,OAAO;CACxB,MAAM,UAAU,CAAC,OAAO;CACxB,MAAM,SAAmB,EAAE;AAE3B,QAAO,QAAQ,SAAS,KAAK,QAAQ,WAAW,QAAQ,QAAQ;EAC9D,MAAM,SAAS,QAAQ,KAAK;EAC5B,MAAM,SAAS,QAAQ,KAAK;AAE5B,MAAI,CAAC,UAAU,CAAC,OACd;EAGF,MAAM,QAAQ,WAAW,QAAQ,QAAQ,UAAU;AACnD,MAAI,MACF,QAAO,KAAK,MAAM;AAGpB,UAAQ,KAAK,GAAG,OAAO,SAAS;AAChC,UAAQ,KAAK,GAAG,OAAO,SAAS;;AAGlC,QAAO,OAAO,KAAK,KAAK;;AAG1B,SAAS,WAAW,QAAiB,QAAiB,WAA4B;AAChF,KAAI,CAAC,UAAU,CAAC,OACd,QAAO;CAGT,MAAM,OAAO,OAAO,eAAe;AACnC,KAAI,CAAC,KACH,QAAO;CAIT,MAAM,cAAc,KAAK,iBAAiB,OAAO;CACjD,MAAM,cAAe,OAAoD;AAEzE,KAAI,CAAC,eAAe,CAAC,YACnB,QAAO;AAGT,MAAK,MAAM,OAAO,YAChB,aAAY,YACV,KACA,YAAY,iBAAiB,IAAI,EAIjC,YAAY,cAAe,YAAY,oBAAoB,IAAI,IAAI,GACpE;CAGH,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,kBAAkB,CAAC,WAAW,SAAS,EAAE;EAClD,MAAM,oBAAoB,KAAK,iBAAiB,QAAQ,eAAe;EACvE,MAAM,oBAAoB,KAAK,iBAAiB,QAAQ,eAAe;AAEvE,MAAI,CAAC,kBACH;EAGF,MAAM,UAAU,kBAAkB,iBAAiB,UAAU;AAG7D,MAAI,EAFqB,WAAW,YAAY,UAAU,YAAY,UAGpE;EAGF,MAAM,WAAqB,EAAE;AAC7B,OAAK,MAAM,YAAY,mBAAmB;GACxC,MAAM,cAAc,kBAAkB,iBAAiB,SAAS;GAChE,MAAM,iBAAiB,kBAAkB,oBAAoB,SAAS;GACtE,MAAM,cAAc,kBAAkB,iBAAiB,SAAS;GAChE,MAAM,iBAAiB,kBAAkB,oBAAoB,SAAS;AACtE,OAAI,gBAAgB,eAAe,mBAAmB,eACpD,UAAS,KAAK,GAAG,SAAS,IAAI,cAAc,iBAAiB,gBAAgB,GAAG,GAAG;;EAIvF,MAAM,kBAAkB,wBAAwB,OAAO;AACvD,SAAO,UAAU,IAAI,gBAAgB;AACrC,SAAO,KAAK,IAAI,kBAAkB,eAAe,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI;;AAG/E,QAAO,OAAO,KAAK,KAAK;;;;;AC1G1B,SAAgB,YAAY,WAAwB,WAAyB;AAC3E,KAAI,CAAC,UACH;CAGF,MAAM,QADW,YAAY,UAAU,CAChB,cAAc,QAAQ;AAC7C,OAAM,cAAc;AACpB,WAAU,YAAY,MAAM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-editor-extension-B2WuUfnd.js","names":[],"sources":["../src/hooks/use-editor-extension.ts"],"sourcesContent":["import { useEffect, type ConnectableElement, type ReadonlySignal } from '@aria-ui/core'\nimport type { Editor, Extension } from '@prosekit/core'\n\nexport function useEditorExtension(\n host: ConnectableElement,\n editor: ReadonlySignal<Editor | null>,\n extension: Extension,\n): void {\n useEffect(host, () => {\n return editor.get()?.use(extension)\n })\n}\n"],"mappings":";;;AAGA,SAAgB,mBACd,MACA,QACA,WACM;AACN,WAAU,YAAY;AACpB,SAAO,OAAO,KAAK,EAAE,IAAI,UAAU;GACnC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-scrolling-BjVzAkiZ.js","names":[],"sources":["../src/utils/assign-styles.ts","../src/hooks/use-scrolling.ts"],"sourcesContent":["import type { ConditionalPick } from 'type-fest'\n\n// Only include CSS properties whose value type is `string`\ntype StringStyleDeclaration = Partial<ConditionalPick<CSSStyleDeclaration, string>>\n\n/**\n * A type-safe version of `Object.assign` for `element.style`.\n */\nexport function assignStyles(\n element: HTMLElement | SVGElement | MathMLElement,\n styles: StringStyleDeclaration,\n): void {\n Object.assign(element.style, styles)\n}\n","import { createSignal, useEffect, type ConnectableElement, type ReadonlySignal } from '@aria-ui/core'\nimport { getNearestOverflowAncestor } from '@zag-js/dom-query'\n\nexport function useScrolling(host: ConnectableElement): ReadonlySignal<boolean> {\n const scrolling = createSignal(false)\n\n useEffect(host, () => {\n const scrollableParent = getNearestOverflowAncestor(host)\n\n const handleScroll = () => {\n scrolling.set(true)\n }\n\n const handleMouseMove = () => {\n scrolling.set(false)\n }\n\n scrollableParent.addEventListener('scroll', handleScroll, { passive: true })\n window.addEventListener('mousemove', handleMouseMove, { passive: true })\n window.addEventListener('pointermove', handleMouseMove, { passive: true })\n\n return () => {\n scrollableParent.removeEventListener('scroll', handleScroll)\n window.removeEventListener('mousemove', handleMouseMove)\n window.removeEventListener('pointermove', handleMouseMove)\n }\n })\n\n return scrolling\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,aACd,SACA,QACM;AACN,QAAO,OAAO,QAAQ,OAAO,OAAO;;;;;ACTtC,SAAgB,aAAa,MAAmD;CAC9E,MAAM,YAAY,aAAa,MAAM;AAErC,WAAU,YAAY;EACpB,MAAM,mBAAmB,2BAA2B,KAAK;EAEzD,MAAM,qBAAqB;AACzB,aAAU,IAAI,KAAK;;EAGrB,MAAM,wBAAwB;AAC5B,aAAU,IAAI,MAAM;;AAGtB,mBAAiB,iBAAiB,UAAU,cAAc,EAAE,SAAS,MAAM,CAAC;AAC5E,SAAO,iBAAiB,aAAa,iBAAiB,EAAE,SAAS,MAAM,CAAC;AACxE,SAAO,iBAAiB,eAAe,iBAAiB,EAAE,SAAS,MAAM,CAAC;AAE1E,eAAa;AACX,oBAAiB,oBAAoB,UAAU,aAAa;AAC5D,UAAO,oBAAoB,aAAa,gBAAgB;AACxD,UAAO,oBAAoB,eAAe,gBAAgB;;GAE5D;AAEF,QAAO"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the element that has a box.
|
|
3
|
-
*/
|
|
4
|
-
export function getBoxElement(element: Element): Element | null | undefined {
|
|
5
|
-
const window = element.ownerDocument.defaultView
|
|
6
|
-
if (!window) {
|
|
7
|
-
return
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const style = window.getComputedStyle(element)
|
|
11
|
-
const display = style.display
|
|
12
|
-
|
|
13
|
-
if (display === 'contents' && element.childElementCount === 1) {
|
|
14
|
-
return element.firstElementChild
|
|
15
|
-
} else if (display === 'none') {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return element
|
|
20
|
-
}
|
package/src/utils/throttle.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @internal
|
|
3
|
-
*/
|
|
4
|
-
export function throttle<Args extends any[]>(
|
|
5
|
-
callback: (...args: Args) => void,
|
|
6
|
-
wait: number,
|
|
7
|
-
): (...args: Args) => void {
|
|
8
|
-
let lastTime = 0
|
|
9
|
-
|
|
10
|
-
return (...args: Args) => {
|
|
11
|
-
const now = Date.now()
|
|
12
|
-
if (now - lastTime >= wait) {
|
|
13
|
-
callback(...args)
|
|
14
|
-
lastTime = now
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|