feat(editor): edgeless clipboard config extension (#11168)

This commit is contained in:
Saul-Mirone
2025-03-25 12:09:23 +00:00
parent 1bb324eeed
commit df057b4c12
10 changed files with 648 additions and 532 deletions

View File

@@ -2,7 +2,7 @@ import rehypeParse from 'rehype-parse';
import { unified } from 'unified';
import { describe, expect, test } from 'vitest';
import { onlyContainImgElement } from '../clipboard/index.js';
import { onlyContainImgElement } from '../clipboard/utils.js';
describe('only contains img elements', () => {
test('normal with head', () => {

View File

@@ -9,12 +9,12 @@ import type {
TransformerMiddleware,
} from '@blocksuite/store';
import DOMPurify from 'dompurify';
import type { RootContentMap } from 'hast';
import * as lz from 'lz-string';
import rehypeParse from 'rehype-parse';
import { unified } from 'unified';
import { LifeCycleWatcher } from '../extension/index.js';
import { onlyContainImgElement } from './utils.js';
type AdapterConstructor<T extends BaseAdapter> =
| { new (job: Transformer): T }
@@ -28,38 +28,6 @@ type AdapterMap = Map<
}
>;
type HastUnionType<
K extends keyof RootContentMap,
V extends RootContentMap[K],
> = V;
export function onlyContainImgElement(
ast: HastUnionType<keyof RootContentMap, RootContentMap[keyof RootContentMap]>
): 'yes' | 'no' | 'maybe' {
if (ast.type === 'element') {
switch (ast.tagName) {
case 'html':
case 'body':
return ast.children.map(onlyContainImgElement).reduce((a, b) => {
if (a === 'no' || b === 'no') {
return 'no';
}
if (a === 'maybe' && b === 'maybe') {
return 'maybe';
}
return 'yes';
}, 'maybe');
case 'img':
return 'yes';
case 'head':
return 'maybe';
default:
return 'no';
}
}
return 'maybe';
}
export class Clipboard extends LifeCycleWatcher {
static override readonly key = 'clipboard';

View File

@@ -0,0 +1,33 @@
import type { RootContentMap } from 'hast';
type HastUnionType<
K extends keyof RootContentMap,
V extends RootContentMap[K],
> = V;
export function onlyContainImgElement(
ast: HastUnionType<keyof RootContentMap, RootContentMap[keyof RootContentMap]>
): 'yes' | 'no' | 'maybe' {
if (ast.type === 'element') {
switch (ast.tagName) {
case 'html':
case 'body':
return ast.children.map(onlyContainImgElement).reduce((a, b) => {
if (a === 'no' || b === 'no') {
return 'no';
}
if (a === 'maybe' && b === 'maybe') {
return 'maybe';
}
return 'yes';
}, 'maybe');
case 'img':
return 'yes';
case 'head':
return 'maybe';
default:
return 'no';
}
}
return 'maybe';
}