@quadrats/common 0.7.7 → 1.1.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/accordion/constants.d.ts +5 -0
- package/accordion/constants.js +10 -0
- package/accordion/createAccordion.d.ts +6 -0
- package/accordion/createAccordion.js +62 -0
- package/accordion/index.cjs.js +76 -0
- package/accordion/index.d.ts +3 -0
- package/accordion/index.js +2 -0
- package/accordion/package.json +7 -0
- package/accordion/typings.d.ts +18 -0
- package/align/constants.d.ts +2 -0
- package/align/constants.js +7 -0
- package/align/createAlign.d.ts +9 -0
- package/align/createAlign.js +39 -0
- package/align/index.cjs.js +46 -0
- package/align/index.d.ts +3 -0
- package/align/index.js +2 -0
- package/align/package.json +7 -0
- package/align/typings.d.ts +1 -0
- package/blockquote/createBlockquote.js +27 -10
- package/blockquote/index.cjs.js +26 -9
- package/card/constants.d.ts +6 -0
- package/card/constants.js +11 -0
- package/card/createCard.d.ts +15 -0
- package/card/createCard.js +147 -0
- package/card/getFilesFromInput.d.ts +4 -0
- package/card/index.cjs.js +163 -0
- package/card/index.d.ts +3 -0
- package/card/index.js +2 -0
- package/card/package.json +7 -0
- package/card/typings.d.ts +73 -0
- package/carousel/_virtual/_tslib.js +33 -0
- package/carousel/constants.d.ts +6 -0
- package/carousel/constants.js +11 -0
- package/carousel/createCarousel.d.ts +16 -0
- package/carousel/createCarousel.js +127 -0
- package/carousel/getFilesFromInput.d.ts +4 -0
- package/carousel/getFilesFromInput.js +30 -0
- package/carousel/index.cjs.js +202 -0
- package/carousel/index.d.ts +3 -0
- package/carousel/index.js +2 -0
- package/carousel/package.json +7 -0
- package/carousel/typings.d.ts +58 -0
- package/embed/constants.d.ts +1 -0
- package/embed/constants.js +2 -1
- package/embed/createEmbed.js +21 -4
- package/embed/index.cjs.js +26 -9
- package/embed/index.js +1 -1
- package/embed/serializeEmbedCode.d.ts +1 -1
- package/embed/serializeEmbedCode.js +5 -7
- package/embed/strategies/podcast-apple/index.cjs.js +1 -1
- package/embed/strategies/podcast-apple/index.js +1 -1
- package/embed/typings.d.ts +16 -1
- package/file-uploader/constants.d.ts +1 -0
- package/file-uploader/constants.js +2 -1
- package/file-uploader/createFileUploader.js +70 -7
- package/file-uploader/getFilesFromInput.js +3 -0
- package/file-uploader/index.cjs.js +73 -5
- package/file-uploader/index.js +1 -1
- package/file-uploader/typings.d.ts +8 -2
- package/heading/typings.d.ts +1 -0
- package/image/createImage.js +12 -11
- package/image/getImageFigureElementCommonProps.d.ts +2 -0
- package/image/getImageFigureElementCommonProps.js +28 -2
- package/image/index.cjs.js +40 -13
- package/image/typings.d.ts +2 -0
- package/list/createList.d.ts +1 -0
- package/list/createList.js +3 -0
- package/list/index.cjs.js +3 -0
- package/list/typings.d.ts +1 -0
- package/package.json +4 -4
- package/paragraph/createParagraph.d.ts +2 -0
- package/paragraph/createParagraph.js +24 -0
- package/paragraph/index.cjs.js +26 -0
- package/paragraph/index.d.ts +2 -0
- package/paragraph/index.js +1 -0
- package/paragraph/package.json +7 -0
- package/paragraph/typings.d.ts +9 -0
- package/table/constants.d.ts +14 -0
- package/table/constants.js +25 -0
- package/table/createTable.d.ts +6 -0
- package/table/createTable.js +429 -0
- package/table/index.cjs.js +714 -0
- package/table/index.d.ts +4 -0
- package/table/index.js +3 -0
- package/table/package.json +7 -0
- package/table/typings.d.ts +70 -0
- package/table/utils.d.ts +68 -0
- package/table/utils.js +243 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AccordionTypes } from './typings';
|
|
2
|
+
export declare const ACCORDION_TYPE = "accordion";
|
|
3
|
+
export declare const ACCORDION_TITLE_TYPE = "accordion-title";
|
|
4
|
+
export declare const ACCORDION_CONTENT_TYPE = "accordion-content";
|
|
5
|
+
export declare const ACCORDION_TYPES: AccordionTypes;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const ACCORDION_TYPE = 'accordion';
|
|
2
|
+
const ACCORDION_TITLE_TYPE = 'accordion-title';
|
|
3
|
+
const ACCORDION_CONTENT_TYPE = 'accordion-content';
|
|
4
|
+
const ACCORDION_TYPES = {
|
|
5
|
+
accordion: ACCORDION_TYPE,
|
|
6
|
+
accordion_title: ACCORDION_TITLE_TYPE,
|
|
7
|
+
accordion_content: ACCORDION_CONTENT_TYPE,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { ACCORDION_CONTENT_TYPE, ACCORDION_TITLE_TYPE, ACCORDION_TYPE, ACCORDION_TYPES };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Editor } from '@quadrats/core';
|
|
2
|
+
import { Accordion, AccordionTypes } from './typings';
|
|
3
|
+
export interface CreateAccordionOptions {
|
|
4
|
+
types?: Partial<AccordionTypes>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createAccordion(options?: CreateAccordionOptions): Accordion<Editor>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isNodesTypeIn, Element, Node, Transforms, Text, Editor } from '@quadrats/core';
|
|
2
|
+
import { ACCORDION_TYPES } from './constants.js';
|
|
3
|
+
|
|
4
|
+
function createAccordion(options = {}) {
|
|
5
|
+
const { types: typesOptions } = options;
|
|
6
|
+
const types = Object.assign(Object.assign({}, ACCORDION_TYPES), typesOptions);
|
|
7
|
+
const createAccordionElement = () => ({
|
|
8
|
+
type: types.accordion,
|
|
9
|
+
children: [
|
|
10
|
+
{ type: types.accordion_title, children: [{ text: '' }] },
|
|
11
|
+
{ type: types.accordion_content, children: [{ text: '' }] },
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
const isSelectionInAccordionTitle = editor => isNodesTypeIn(editor, [types.accordion_title]);
|
|
15
|
+
const isSelectionInAccordionContent = editor => isNodesTypeIn(editor, [types.accordion_content]);
|
|
16
|
+
const insertAccordion = (editor) => {
|
|
17
|
+
Transforms.insertNodes(editor, createAccordionElement());
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
types,
|
|
21
|
+
createAccordionElement,
|
|
22
|
+
isSelectionInAccordionTitle,
|
|
23
|
+
isSelectionInAccordionContent,
|
|
24
|
+
insertAccordion,
|
|
25
|
+
with(editor) {
|
|
26
|
+
editor.normalizeNode = (entry) => {
|
|
27
|
+
const [node, path] = entry;
|
|
28
|
+
if (Element.isElement(node)) {
|
|
29
|
+
const type = node.type;
|
|
30
|
+
if (type === types.accordion) {
|
|
31
|
+
for (const [child, childPath] of Node.children(editor, path)) {
|
|
32
|
+
if (Element.isElement(child) && child.type === types.accordion) {
|
|
33
|
+
Transforms.removeNodes(editor, { at: childPath });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!isNodesTypeIn(editor, [types.accordion_content], { at: path })) {
|
|
38
|
+
Transforms.removeNodes(editor, { at: path });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (type === types.accordion_title || type === types.accordion_content) {
|
|
43
|
+
if (node.children.length !== 1 || !Text.isText(node.children[0])) {
|
|
44
|
+
const mergedText = node.children.map(child => Node.string(child)).join('');
|
|
45
|
+
const mergedElement = {
|
|
46
|
+
type,
|
|
47
|
+
children: [{ text: mergedText }],
|
|
48
|
+
};
|
|
49
|
+
Transforms.removeNodes(editor, { at: path });
|
|
50
|
+
Transforms.insertNodes(editor, mergedElement, { at: path });
|
|
51
|
+
Transforms.select(editor, Editor.end(editor, path));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return editor;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { createAccordion };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@quadrats/core');
|
|
4
|
+
|
|
5
|
+
const ACCORDION_TYPE = 'accordion';
|
|
6
|
+
const ACCORDION_TITLE_TYPE = 'accordion-title';
|
|
7
|
+
const ACCORDION_CONTENT_TYPE = 'accordion-content';
|
|
8
|
+
const ACCORDION_TYPES = {
|
|
9
|
+
accordion: ACCORDION_TYPE,
|
|
10
|
+
accordion_title: ACCORDION_TITLE_TYPE,
|
|
11
|
+
accordion_content: ACCORDION_CONTENT_TYPE,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function createAccordion(options = {}) {
|
|
15
|
+
const { types: typesOptions } = options;
|
|
16
|
+
const types = Object.assign(Object.assign({}, ACCORDION_TYPES), typesOptions);
|
|
17
|
+
const createAccordionElement = () => ({
|
|
18
|
+
type: types.accordion,
|
|
19
|
+
children: [
|
|
20
|
+
{ type: types.accordion_title, children: [{ text: '' }] },
|
|
21
|
+
{ type: types.accordion_content, children: [{ text: '' }] },
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
const isSelectionInAccordionTitle = editor => core.isNodesTypeIn(editor, [types.accordion_title]);
|
|
25
|
+
const isSelectionInAccordionContent = editor => core.isNodesTypeIn(editor, [types.accordion_content]);
|
|
26
|
+
const insertAccordion = (editor) => {
|
|
27
|
+
core.Transforms.insertNodes(editor, createAccordionElement());
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
types,
|
|
31
|
+
createAccordionElement,
|
|
32
|
+
isSelectionInAccordionTitle,
|
|
33
|
+
isSelectionInAccordionContent,
|
|
34
|
+
insertAccordion,
|
|
35
|
+
with(editor) {
|
|
36
|
+
editor.normalizeNode = (entry) => {
|
|
37
|
+
const [node, path] = entry;
|
|
38
|
+
if (core.Element.isElement(node)) {
|
|
39
|
+
const type = node.type;
|
|
40
|
+
if (type === types.accordion) {
|
|
41
|
+
for (const [child, childPath] of core.Node.children(editor, path)) {
|
|
42
|
+
if (core.Element.isElement(child) && child.type === types.accordion) {
|
|
43
|
+
core.Transforms.removeNodes(editor, { at: childPath });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!core.isNodesTypeIn(editor, [types.accordion_content], { at: path })) {
|
|
48
|
+
core.Transforms.removeNodes(editor, { at: path });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (type === types.accordion_title || type === types.accordion_content) {
|
|
53
|
+
if (node.children.length !== 1 || !core.Text.isText(node.children[0])) {
|
|
54
|
+
const mergedText = node.children.map(child => core.Node.string(child)).join('');
|
|
55
|
+
const mergedElement = {
|
|
56
|
+
type,
|
|
57
|
+
children: [{ text: mergedText }],
|
|
58
|
+
};
|
|
59
|
+
core.Transforms.removeNodes(editor, { at: path });
|
|
60
|
+
core.Transforms.insertNodes(editor, mergedElement, { at: path });
|
|
61
|
+
core.Transforms.select(editor, core.Editor.end(editor, path));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return editor;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
exports.ACCORDION_CONTENT_TYPE = ACCORDION_CONTENT_TYPE;
|
|
73
|
+
exports.ACCORDION_TITLE_TYPE = ACCORDION_TITLE_TYPE;
|
|
74
|
+
exports.ACCORDION_TYPE = ACCORDION_TYPE;
|
|
75
|
+
exports.ACCORDION_TYPES = ACCORDION_TYPES;
|
|
76
|
+
exports.createAccordion = createAccordion;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Editor, QuadratsElement, Text, Withable, WithElementType } from '@quadrats/core';
|
|
2
|
+
export type AccordionTypeKey = 'accordion';
|
|
3
|
+
export type AccordionTitleTypeKey = 'accordion_title';
|
|
4
|
+
export type AccordionContentTypeKey = 'accordion_content';
|
|
5
|
+
export type AccordionTypes = Record<AccordionTypeKey | AccordionTitleTypeKey | AccordionContentTypeKey, string>;
|
|
6
|
+
export interface AccordionElement extends QuadratsElement, WithElementType {
|
|
7
|
+
children: {
|
|
8
|
+
type: string;
|
|
9
|
+
children: [Text];
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export interface Accordion<T extends Editor = Editor> extends Withable {
|
|
13
|
+
types: AccordionTypes;
|
|
14
|
+
createAccordionElement(): AccordionElement;
|
|
15
|
+
isSelectionInAccordionTitle(editor: T): boolean;
|
|
16
|
+
isSelectionInAccordionContent(editor: T): boolean;
|
|
17
|
+
insertAccordion(editor: T): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from '@quadrats/core';
|
|
2
|
+
import { AlignValue } from './typings';
|
|
3
|
+
export interface Align<E extends Editor = Editor> {
|
|
4
|
+
type: string;
|
|
5
|
+
isAlignActive: (editor: E, value: AlignValue) => boolean;
|
|
6
|
+
setAlign: (editor: E, value: AlignValue) => void;
|
|
7
|
+
removeAlign: (editor: E) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createAlign(): Align;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Transforms, Element, Editor } from '@quadrats/core';
|
|
2
|
+
import { ALIGN_TYPE, ALIGNABLE_TYPES } from './constants.js';
|
|
3
|
+
|
|
4
|
+
function createAlign() {
|
|
5
|
+
const type = ALIGN_TYPE;
|
|
6
|
+
return {
|
|
7
|
+
type,
|
|
8
|
+
isAlignActive: (editor, value) => {
|
|
9
|
+
const { selection } = editor;
|
|
10
|
+
if (!selection)
|
|
11
|
+
return false;
|
|
12
|
+
const [match] = Editor.nodes(editor, {
|
|
13
|
+
match: (n) => !!(Element.isElement(n) &&
|
|
14
|
+
n.type &&
|
|
15
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
16
|
+
});
|
|
17
|
+
if (!match)
|
|
18
|
+
return false;
|
|
19
|
+
const [node] = match;
|
|
20
|
+
return node[type] === value;
|
|
21
|
+
},
|
|
22
|
+
setAlign: (editor, value) => {
|
|
23
|
+
Transforms.setNodes(editor, { [type]: value }, {
|
|
24
|
+
match: (n) => !!(Element.isElement(n) &&
|
|
25
|
+
n.type &&
|
|
26
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
removeAlign: (editor) => {
|
|
30
|
+
Transforms.unsetNodes(editor, [type], {
|
|
31
|
+
match: (n) => !!(Element.isElement(n) &&
|
|
32
|
+
n.type &&
|
|
33
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { createAlign };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var heading = require('@quadrats/common/heading');
|
|
4
|
+
var core = require('@quadrats/core');
|
|
5
|
+
|
|
6
|
+
const ALIGN_TYPE = 'align';
|
|
7
|
+
const ALIGNABLE_TYPES = [core.PARAGRAPH_TYPE, heading.HEADING_TYPE];
|
|
8
|
+
|
|
9
|
+
function createAlign() {
|
|
10
|
+
const type = ALIGN_TYPE;
|
|
11
|
+
return {
|
|
12
|
+
type,
|
|
13
|
+
isAlignActive: (editor, value) => {
|
|
14
|
+
const { selection } = editor;
|
|
15
|
+
if (!selection)
|
|
16
|
+
return false;
|
|
17
|
+
const [match] = core.Editor.nodes(editor, {
|
|
18
|
+
match: (n) => !!(core.Element.isElement(n) &&
|
|
19
|
+
n.type &&
|
|
20
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
21
|
+
});
|
|
22
|
+
if (!match)
|
|
23
|
+
return false;
|
|
24
|
+
const [node] = match;
|
|
25
|
+
return node[type] === value;
|
|
26
|
+
},
|
|
27
|
+
setAlign: (editor, value) => {
|
|
28
|
+
core.Transforms.setNodes(editor, { [type]: value }, {
|
|
29
|
+
match: (n) => !!(core.Element.isElement(n) &&
|
|
30
|
+
n.type &&
|
|
31
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
removeAlign: (editor) => {
|
|
35
|
+
core.Transforms.unsetNodes(editor, [type], {
|
|
36
|
+
match: (n) => !!(core.Element.isElement(n) &&
|
|
37
|
+
n.type &&
|
|
38
|
+
ALIGNABLE_TYPES.includes(n.type)),
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
exports.ALIGNABLE_TYPES = ALIGNABLE_TYPES;
|
|
45
|
+
exports.ALIGN_TYPE = ALIGN_TYPE;
|
|
46
|
+
exports.createAlign = createAlign;
|
package/align/index.d.ts
ADDED
package/align/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AlignValue = 'left' | 'center' | 'right';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { isNodesTypeIn, wrapNodesWithUnhangRange, unwrapNodesByTypes } from '@quadrats/core';
|
|
1
|
+
import { isNodesTypeIn, Editor, wrapNodesWithUnhangRange, unwrapNodesByTypes } from '@quadrats/core';
|
|
2
2
|
import { BLOCKQUOTE_TYPE } from './constants.js';
|
|
3
|
+
import { TABLE_CELL_TYPE } from '@quadrats/common/table';
|
|
3
4
|
|
|
4
5
|
function createBlockquote({ type = BLOCKQUOTE_TYPE } = {}) {
|
|
5
6
|
const unwrapBlockquote = (editor) => {
|
|
@@ -12,21 +13,37 @@ function createBlockquote({ type = BLOCKQUOTE_TYPE } = {}) {
|
|
|
12
13
|
};
|
|
13
14
|
wrapNodesWithUnhangRange(editor, element, { split: true });
|
|
14
15
|
};
|
|
15
|
-
const isSelectionInBlockquote = editor =>
|
|
16
|
+
const isSelectionInBlockquote = (editor) => isNodesTypeIn(editor, [type], { mode: 'highest' });
|
|
16
17
|
return {
|
|
17
18
|
type,
|
|
18
19
|
unwrapBlockquote,
|
|
19
20
|
wrapBlockquote,
|
|
20
21
|
isSelectionInBlockquote,
|
|
21
22
|
toggleBlockquote: (editor) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
if (!editor.selection) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// 檢查是否在不合法範圍中,如果是則不執行 toggle
|
|
27
|
+
try {
|
|
28
|
+
const invalidEntry = Editor.above(editor, {
|
|
29
|
+
at: editor.selection,
|
|
30
|
+
match: (n) => {
|
|
31
|
+
const element = n;
|
|
32
|
+
return element.type === TABLE_CELL_TYPE;
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
if (invalidEntry)
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const active = isSelectionInBlockquote(editor);
|
|
42
|
+
if (active) {
|
|
43
|
+
unwrapBlockquote(editor);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
wrapBlockquote(editor);
|
|
30
47
|
}
|
|
31
48
|
},
|
|
32
49
|
with(editor) {
|
package/blockquote/index.cjs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@quadrats/core');
|
|
4
|
+
var table = require('@quadrats/common/table');
|
|
4
5
|
|
|
5
6
|
const BLOCKQUOTE_TYPE = 'blockquote';
|
|
6
7
|
|
|
@@ -15,21 +16,37 @@ function createBlockquote({ type = BLOCKQUOTE_TYPE } = {}) {
|
|
|
15
16
|
};
|
|
16
17
|
core.wrapNodesWithUnhangRange(editor, element, { split: true });
|
|
17
18
|
};
|
|
18
|
-
const isSelectionInBlockquote = editor =>
|
|
19
|
+
const isSelectionInBlockquote = (editor) => core.isNodesTypeIn(editor, [type], { mode: 'highest' });
|
|
19
20
|
return {
|
|
20
21
|
type,
|
|
21
22
|
unwrapBlockquote,
|
|
22
23
|
wrapBlockquote,
|
|
23
24
|
isSelectionInBlockquote,
|
|
24
25
|
toggleBlockquote: (editor) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
if (!editor.selection) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// 檢查是否在不合法範圍中,如果是則不執行 toggle
|
|
30
|
+
try {
|
|
31
|
+
const invalidEntry = core.Editor.above(editor, {
|
|
32
|
+
at: editor.selection,
|
|
33
|
+
match: (n) => {
|
|
34
|
+
const element = n;
|
|
35
|
+
return element.type === table.TABLE_CELL_TYPE;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
if (invalidEntry)
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const active = isSelectionInBlockquote(editor);
|
|
45
|
+
if (active) {
|
|
46
|
+
unwrapBlockquote(editor);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
wrapBlockquote(editor);
|
|
33
50
|
}
|
|
34
51
|
},
|
|
35
52
|
with(editor) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CardTypes } from './typings';
|
|
2
|
+
export declare const CARD_TYPE = "card";
|
|
3
|
+
export declare const CARD_IMAGE_TYPE = "card_image";
|
|
4
|
+
export declare const CARD_CONTENTS_TYPE = "card_contents";
|
|
5
|
+
export declare const CARD_PLACEHOLDER_TYPE = "card_placeholder";
|
|
6
|
+
export declare const CARD_TYPES: CardTypes;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const CARD_TYPE = 'card';
|
|
2
|
+
const CARD_IMAGE_TYPE = 'card_image';
|
|
3
|
+
const CARD_CONTENTS_TYPE = 'card_contents';
|
|
4
|
+
const CARD_PLACEHOLDER_TYPE = 'card_placeholder';
|
|
5
|
+
const CARD_TYPES = {
|
|
6
|
+
card: CARD_TYPE,
|
|
7
|
+
card_image: CARD_IMAGE_TYPE,
|
|
8
|
+
card_contents: CARD_CONTENTS_TYPE,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { CARD_CONTENTS_TYPE, CARD_IMAGE_TYPE, CARD_PLACEHOLDER_TYPE, CARD_TYPE, CARD_TYPES };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Editor } from '@quadrats/core';
|
|
2
|
+
import { ImageAccept, FileUploaderGetBody, FileUploaderGetHeaders, FileUploaderGetUrl, FileUploaderImplement } from '@quadrats/common/file-uploader';
|
|
3
|
+
import { Card, CardTypes } from './typings';
|
|
4
|
+
export interface CreateCardOptions {
|
|
5
|
+
types?: Partial<CardTypes>;
|
|
6
|
+
accept?: ImageAccept[];
|
|
7
|
+
ratio?: [number, number];
|
|
8
|
+
limitSize?: number;
|
|
9
|
+
confirmModal?: boolean;
|
|
10
|
+
getBody: FileUploaderGetBody;
|
|
11
|
+
getHeaders?: FileUploaderGetHeaders;
|
|
12
|
+
getUrl: FileUploaderGetUrl;
|
|
13
|
+
uploader?: FileUploaderImplement;
|
|
14
|
+
}
|
|
15
|
+
export declare function createCard(options: CreateCardOptions): Card<Editor>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Element, Node, Transforms, Editor, createParagraphElement } from '@quadrats/core';
|
|
2
|
+
import { CARD_TYPES, CARD_PLACEHOLDER_TYPE } from './constants.js';
|
|
3
|
+
|
|
4
|
+
function createCard(options) {
|
|
5
|
+
const { types: typesOptions, accept: acceptOptions, ratio, limitSize: limitSizeOptions, confirmModal = true, getBody, getHeaders, getUrl, uploader, } = options;
|
|
6
|
+
const types = Object.assign(Object.assign({}, CARD_TYPES), typesOptions);
|
|
7
|
+
const limitSize = limitSizeOptions || 5;
|
|
8
|
+
const accept = acceptOptions || ['image/jpeg', 'image/jpg', 'image/png'];
|
|
9
|
+
const insertCardPlaceholder = (editor) => {
|
|
10
|
+
const cardPlaceholderElement = {
|
|
11
|
+
type: CARD_PLACEHOLDER_TYPE,
|
|
12
|
+
ratio,
|
|
13
|
+
children: [{ text: '' }],
|
|
14
|
+
};
|
|
15
|
+
Editor.withoutNormalizing(editor, () => {
|
|
16
|
+
Transforms.insertNodes(editor, cardPlaceholderElement);
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const removeCardPlaceholder = (editor) => {
|
|
20
|
+
Transforms.removeNodes(editor, {
|
|
21
|
+
match: (node) => Element.isElement(node) && node.type === CARD_PLACEHOLDER_TYPE,
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
const createCardElement = (cardValues) => {
|
|
25
|
+
var _a;
|
|
26
|
+
const cardImageElement = {
|
|
27
|
+
type: types.card_image,
|
|
28
|
+
src: ((_a = cardValues.imageItem) === null || _a === void 0 ? void 0 : _a.url) || '',
|
|
29
|
+
ratio,
|
|
30
|
+
children: [{ text: '' }],
|
|
31
|
+
};
|
|
32
|
+
const cardContentsElement = {
|
|
33
|
+
type: types.card_contents,
|
|
34
|
+
children: [{ text: '' }],
|
|
35
|
+
alignment: cardValues.alignment,
|
|
36
|
+
title: cardValues.title,
|
|
37
|
+
description: cardValues.description,
|
|
38
|
+
remark: cardValues.remark,
|
|
39
|
+
haveLink: cardValues.haveLink,
|
|
40
|
+
linkText: cardValues.linkText,
|
|
41
|
+
linkUrl: cardValues.linkUrl,
|
|
42
|
+
};
|
|
43
|
+
return Object.assign(Object.assign({ type: types.card, confirmModal }, cardValues), { children: [cardImageElement, cardContentsElement] });
|
|
44
|
+
};
|
|
45
|
+
const insertCard = ({ editor, cardValues }) => {
|
|
46
|
+
Transforms.insertNodes(editor, [createCardElement(cardValues), createParagraphElement()]);
|
|
47
|
+
};
|
|
48
|
+
const updateCardElement = ({ editor, cardValues, path }) => {
|
|
49
|
+
var _a;
|
|
50
|
+
Transforms.setNodes(editor, cardValues, { at: path });
|
|
51
|
+
const imageEntries = Editor.nodes(editor, {
|
|
52
|
+
at: path,
|
|
53
|
+
match: (node) => Element.isElement(node) && node.type === types.card_image,
|
|
54
|
+
mode: 'all',
|
|
55
|
+
});
|
|
56
|
+
const imageNode = imageEntries.next().value;
|
|
57
|
+
const contentsEntries = Editor.nodes(editor, {
|
|
58
|
+
at: path,
|
|
59
|
+
match: (node) => Element.isElement(node) && node.type === types.card_contents,
|
|
60
|
+
mode: 'all',
|
|
61
|
+
});
|
|
62
|
+
const contentsNode = contentsEntries.next().value;
|
|
63
|
+
if (imageNode) {
|
|
64
|
+
const [, imagePath] = imageNode;
|
|
65
|
+
Transforms.setNodes(editor, { src: ((_a = cardValues.imageItem) === null || _a === void 0 ? void 0 : _a.url) || '' }, { at: imagePath });
|
|
66
|
+
}
|
|
67
|
+
if (contentsNode) {
|
|
68
|
+
const [, contentsPath] = contentsNode;
|
|
69
|
+
Transforms.setNodes(editor, {
|
|
70
|
+
alignment: cardValues.alignment,
|
|
71
|
+
title: cardValues.title,
|
|
72
|
+
description: cardValues.description,
|
|
73
|
+
remark: cardValues.remark,
|
|
74
|
+
haveLink: cardValues.haveLink,
|
|
75
|
+
linkText: cardValues.linkText,
|
|
76
|
+
linkUrl: cardValues.linkUrl,
|
|
77
|
+
}, {
|
|
78
|
+
at: contentsPath,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const updateCardAlignment = ({ editor, alignment, path }) => {
|
|
83
|
+
Transforms.setNodes(editor, { alignment }, { at: path });
|
|
84
|
+
const contentsEntries = Editor.nodes(editor, {
|
|
85
|
+
at: path,
|
|
86
|
+
match: (node) => Element.isElement(node) && node.type === types.card_contents,
|
|
87
|
+
mode: 'all',
|
|
88
|
+
});
|
|
89
|
+
const contentsNode = contentsEntries.next().value;
|
|
90
|
+
if (contentsNode) {
|
|
91
|
+
const [, contentsPath] = contentsNode;
|
|
92
|
+
Transforms.setNodes(editor, {
|
|
93
|
+
alignment,
|
|
94
|
+
}, {
|
|
95
|
+
at: contentsPath,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
types,
|
|
101
|
+
createCardElement,
|
|
102
|
+
insertCard,
|
|
103
|
+
updateCardElement,
|
|
104
|
+
updateCardAlignment,
|
|
105
|
+
accept,
|
|
106
|
+
ratio,
|
|
107
|
+
limitSize,
|
|
108
|
+
confirmModal,
|
|
109
|
+
insertCardPlaceholder,
|
|
110
|
+
removeCardPlaceholder,
|
|
111
|
+
getBody,
|
|
112
|
+
getHeaders,
|
|
113
|
+
getUrl,
|
|
114
|
+
uploader,
|
|
115
|
+
with(editor) {
|
|
116
|
+
const { normalizeNode } = editor;
|
|
117
|
+
editor.normalizeNode = (entry) => {
|
|
118
|
+
const [node, path] = entry;
|
|
119
|
+
if (Element.isElement(node)) {
|
|
120
|
+
const type = node.type;
|
|
121
|
+
if (type === types.card) {
|
|
122
|
+
for (const [child, childPath] of Node.children(editor, path)) {
|
|
123
|
+
if (Element.isElement(child) &&
|
|
124
|
+
child.type !== types.card_contents &&
|
|
125
|
+
child.type !== types.card_image) {
|
|
126
|
+
Transforms.removeNodes(editor, { at: childPath });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (type === types.card_contents || type === types.card_image) {
|
|
132
|
+
for (const [child, childPath] of Node.children(editor, path)) {
|
|
133
|
+
if (Element.isElement(child)) {
|
|
134
|
+
Transforms.removeNodes(editor, { at: childPath });
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
normalizeNode(entry);
|
|
141
|
+
};
|
|
142
|
+
return editor;
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { createCard };
|