@blocksuite/global
Advanced tools
Comparing version 0.5.0-alpha.0 to 0.5.0-alpha.1
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
type AnyFunction = (...args: any[]) => any; | ||
declare module 'quill' { | ||
import quill = require('quill/index'); | ||
export type * from 'quill/index' assert { 'resolution-mode': 'require' }; | ||
declare const quillDefault: typeof quill.default; | ||
export default quillDefault; | ||
} | ||
declare module 'y-protocols/awareness.js' { | ||
@@ -72,2 +65,3 @@ export class Awareness< | ||
enable_slash_menu: boolean; | ||
/** | ||
@@ -77,2 +71,4 @@ * Block selection can trigger format bar | ||
enable_block_selection_format_bar: boolean; | ||
enable_toggle_block: boolean; | ||
enable_edgeless_toolbar: boolean; | ||
@@ -96,3 +92,3 @@ readonly: Record<string, boolean>; | ||
declare type EmbedType = 'image' | 'video' | 'audio' | 'file'; | ||
declare type ListType = 'bulleted' | 'numbered' | 'todo'; | ||
declare type ListType = 'bulleted' | 'numbered' | 'todo' | 'toggle'; | ||
declare type ParagraphType = | ||
@@ -107,58 +103,1 @@ | 'text' | ||
| 'h6'; | ||
declare namespace BlockSuiteModelProps { | ||
import type { Text } from '@blocksuite/store'; | ||
interface CodeBlockModel { | ||
language: string; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
interface DividerBlockModel {} | ||
interface EmbedBlockModel { | ||
type: EmbedType; | ||
sourceId: string; | ||
width?: number; | ||
height?: number; | ||
caption?: string; | ||
} | ||
interface FrameBlockModel { | ||
xywh: string; | ||
} | ||
interface ListBlockModel { | ||
type: ListType; | ||
checked: boolean; | ||
} | ||
interface PageBlockModel { | ||
title: Text; | ||
} | ||
interface ParagraphBlockModel { | ||
type: ParagraphType; | ||
} | ||
import type { ColorStyle, TDShapeType } from '@blocksuite/blocks'; | ||
interface DatabaseBlockModel { | ||
columns: BlockSuiteInternal.ColumnTypes[]; | ||
title: string; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
interface SurfaceBlockModel {} | ||
export type ALL = { | ||
'affine:database': DatabaseBlockModel; | ||
'affine:paragraph': ParagraphBlockModel; | ||
'affine:page': PageBlockModel; | ||
'affine:list': ListBlockModel; | ||
'affine:frame': FrameBlockModel; | ||
'affine:code': CodeBlockModel; | ||
'affine:divider': DividerBlockModel; | ||
'affine:embed': EmbedBlockModel; | ||
'affine:surface': SurfaceBlockModel; | ||
}; | ||
} |
{ | ||
"name": "@blocksuite/global", | ||
"version": "0.5.0-alpha.0", | ||
"version": "0.5.0-alpha.1", | ||
"types": "./index.d.ts", | ||
"type": "module", | ||
"scripts": { | ||
"test:unit": "vitest --run", | ||
"test:unit:coverage": "vitest run --coverage", | ||
"test:unit:ui": "vitest --ui", | ||
"build": "tsc" | ||
}, | ||
"sideEffects": false, | ||
"exports": { | ||
".": "./index.d.ts", | ||
"./database": "./src/database.ts", | ||
"./types": "./src/types.ts", | ||
"./utils": "./src/utils.ts", | ||
"./debug": "./src/debug.ts", | ||
"./config": "./src/config/index.ts", | ||
"./error": "./src/error.ts" | ||
"./database": "./dist/database.js", | ||
"./utils": "./dist/utils.js", | ||
"./debug": "./dist/debug.js", | ||
"./error": "./dist/error.js", | ||
"./config": "./dist/config/index.js" | ||
}, | ||
@@ -26,10 +19,2 @@ "author": "toeverything", | ||
"access": "public", | ||
"exports": { | ||
".": "./index.d.ts", | ||
"./database": "./dist/database.js", | ||
"./utils": "./dist/utils.js", | ||
"./debug": "./dist/debug.js", | ||
"./error": "./dist/error.js", | ||
"./config": "./dist/config/index.js" | ||
}, | ||
"files": [ | ||
@@ -54,3 +39,9 @@ "dist", | ||
} | ||
}, | ||
"scripts": { | ||
"test:unit": "vitest --run", | ||
"test:unit:coverage": "vitest run --coverage", | ||
"test:unit:ui": "vitest --ui", | ||
"build": "tsc" | ||
} | ||
} | ||
} |
export * from './consts/affine-style-consts.js'; | ||
export * from './consts/blockhub.js'; | ||
export * from './consts/block-hub.js'; | ||
@@ -4,0 +4,0 @@ export const BLOCK_ID_ATTR = 'data-block-id'; |
import type { | ||
CodeBlockModelSchema, | ||
DatabaseBlockModelSchema, | ||
DividerBlockModelSchema, | ||
EmbedBlockModelSchema, | ||
FrameBlockModelSchema, | ||
ListBlockModelSchema, | ||
PageBlockModelSchema, | ||
ParagraphBlockModelSchema, | ||
SurfaceBlockModelSchema, | ||
} from '@blocksuite/blocks'; | ||
import type { | ||
// Model | ||
@@ -14,2 +25,14 @@ CodeBlockModel, | ||
export type BlockSchemas = { | ||
'affine:paragraph': typeof ParagraphBlockModelSchema; | ||
'affine:page': typeof PageBlockModelSchema; | ||
'affine:list': typeof ListBlockModelSchema; | ||
'affine:frame': typeof FrameBlockModelSchema; | ||
'affine:code': typeof CodeBlockModelSchema; | ||
'affine:divider': typeof DividerBlockModelSchema; | ||
'affine:embed': typeof EmbedBlockModelSchema; | ||
'affine:surface': typeof SurfaceBlockModelSchema; | ||
'affine:database': typeof DatabaseBlockModelSchema; | ||
}; | ||
export type BlockModels = { | ||
@@ -26,1 +49,5 @@ 'affine:paragraph': ParagraphBlockModel; | ||
}; | ||
export type BlockModelProps = { | ||
[K in keyof BlockSchemas]: ReturnType<BlockSchemas[K]['model']['props']>; | ||
}; |
@@ -6,4 +6,4 @@ import type { BaseBlockModel } from '@blocksuite/store'; | ||
export type { Disposable } from './utils/disposable.js'; | ||
export { DisposableGroup, flattenDisposable } from './utils/disposable.js'; | ||
export { Signal } from './utils/signal.js'; | ||
export { DisposableGroup } from './utils/disposable.js'; | ||
export { Slot } from './utils/slot.js'; | ||
export { caretRangeFromPoint, isFirefox, isWeb } from './utils/web.js'; | ||
@@ -19,8 +19,20 @@ export const SYS_KEYS = new Set(['id', 'flavour', 'children']); | ||
export function assertExists<T>(val: T | null | undefined): asserts val is T { | ||
export function assertExists<T>( | ||
val: T | null | undefined, | ||
message = 'val does not exist' | ||
): asserts val is T { | ||
if (val === null || val === undefined) { | ||
throw new Error('val does not exist'); | ||
throw new Error(message); | ||
} | ||
} | ||
export function assertNotExists<T>( | ||
val: T | null | undefined, | ||
message = 'val exists' | ||
): asserts val is null | undefined { | ||
if (val !== null && val !== undefined) { | ||
throw new Error(message); | ||
} | ||
} | ||
export function assertFlavours(model: { flavour: string }, allowed: string[]) { | ||
@@ -76,6 +88,7 @@ if (!allowed.includes(model.flavour)) { | ||
val: T, | ||
expected: U | ||
expected: U, | ||
message = 'val is not same as expected' | ||
): asserts val is U { | ||
if (!isEqual(val, expected)) { | ||
throw new Error('val is not same as expected'); | ||
throw new Error(message); | ||
} | ||
@@ -119,2 +132,3 @@ } | ||
export const getDefaultPlaygroundURL = (isE2E: boolean): URL => | ||
new URL(`http://localhost:${isE2E ? 4173 : 5173}/`); | ||
new URL(`http://localhost:5173/`); | ||
// new URL(`http://localhost:${isE2E ? 4173 : 5173}/`); |
@@ -0,26 +1,64 @@ | ||
type DisposeCallback = () => void; | ||
export interface Disposable { | ||
dispose(): void; | ||
dispose: DisposeCallback; | ||
} | ||
type DisposeLogic = Disposable | (() => void); | ||
export class DisposableGroup implements Disposable { | ||
private _disposed = false; | ||
private _disposables: Disposable[] = []; | ||
get disposed() { | ||
return this._disposed; | ||
} | ||
constructor(private _disposables: DisposeLogic[] = []) {} | ||
/** | ||
* Add to group to be disposed with others. | ||
* | ||
* This will be immediately disposed if this group has already been disposed. | ||
*/ | ||
add(disposable: DisposeLogic | undefined | null | false): void { | ||
if (disposable) { | ||
if (this._disposed) execDisposeLogic(disposable); | ||
else this._disposables.push(disposable); | ||
add(d: Disposable | DisposeCallback) { | ||
if (typeof d === 'function') { | ||
if (this._disposed) d(); | ||
else this._disposables.push({ dispose: d }); | ||
} else { | ||
if (this._disposed) d.dispose(); | ||
else this._disposables.push(d); | ||
} | ||
} | ||
dispose(): void { | ||
disposeAllAndClearArray(this._disposables); | ||
addFromEvent<N extends keyof WindowEventMap>( | ||
element: Window, | ||
eventName: N, | ||
handler: (e: WindowEventMap[N]) => void, | ||
options?: boolean | AddEventListenerOptions | ||
): void; | ||
addFromEvent<N extends keyof DocumentEventMap>( | ||
element: Document, | ||
eventName: N, | ||
handler: (e: DocumentEventMap[N]) => void, | ||
eventOptions?: boolean | AddEventListenerOptions | ||
): void; | ||
addFromEvent<N extends keyof HTMLElementEventMap>( | ||
element: HTMLElement, | ||
eventName: N, | ||
handler: (e: HTMLElementEventMap[N]) => void, | ||
eventOptions?: boolean | AddEventListenerOptions | ||
): void; | ||
addFromEvent( | ||
target: HTMLElement | Window | Document, | ||
type: string, | ||
handler: (e: Event) => void, | ||
eventOptions?: boolean | AddEventListenerOptions | ||
) { | ||
this.add({ | ||
dispose: () => { | ||
target.removeEventListener(type, handler as () => void, eventOptions); | ||
}, | ||
}); | ||
target.addEventListener(type, handler as () => void, eventOptions); | ||
} | ||
dispose() { | ||
disposeAll(this._disposables); | ||
this._disposables = []; | ||
this._disposed = true; | ||
@@ -30,13 +68,12 @@ } | ||
export function flattenDisposable(disposables: Disposable[]): Disposable { | ||
export function flattenDisposables(disposables: Disposable[]): Disposable { | ||
return { | ||
dispose: disposeAllAndClearArray.bind(null, disposables), | ||
dispose: () => disposeAll(disposables), | ||
}; | ||
} | ||
/** @internal */ | ||
function disposeAllAndClearArray(disposables: DisposeLogic[]) { | ||
function disposeAll(disposables: Disposable[]) { | ||
for (const disposable of disposables) { | ||
try { | ||
execDisposeLogic(disposable); | ||
disposable.dispose(); | ||
} catch (err) { | ||
@@ -46,9 +83,2 @@ console.error(err); | ||
} | ||
disposables.length = 0; | ||
} | ||
/** @internal */ | ||
function execDisposeLogic(disposable: DisposeLogic) { | ||
if (typeof disposable === 'function') disposable(); | ||
else disposable.dispose(); | ||
} |
@@ -45,6 +45,24 @@ export const isWeb = typeof window !== 'undefined'; | ||
} | ||
const range = document.caretRangeFromPoint(clientX, clientY); | ||
if (!range) { | ||
return null; | ||
} | ||
// See https://github.com/toeverything/blocksuite/issues/1382 | ||
const rangeRects = range?.getClientRects(); | ||
if ( | ||
rangeRects && | ||
rangeRects.length === 2 && | ||
range.startOffset === range.endOffset && | ||
clientY < rangeRects[0].y + rangeRects[0].height | ||
) { | ||
const deltaX = (rangeRects[0].x | 0) - (rangeRects[1].x | 0); | ||
if (deltaX > 0) { | ||
range.setStart(range.startContainer, range.startOffset - 1); | ||
range.setEnd(range.endContainer, range.endOffset - 1); | ||
} | ||
} | ||
// This is a workaround | ||
@@ -51,0 +69,0 @@ // Sometimes the point be covered by the format bar, |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
434547
84
4554
1