@atlaskit/adf-schema 19.3.0 → 20.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/CHANGELOG.md +45 -0
- package/dist/cjs/index.js +366 -360
- package/dist/cjs/schema/create-schema.js +7 -4
- package/dist/cjs/schema/default-schema.js +8 -14
- package/dist/cjs/schema/groups.js +1 -1
- package/dist/cjs/schema/index.js +244 -238
- package/dist/cjs/schema/jira-schema.js +8 -8
- package/dist/cjs/schema/marks/alignment.js +1 -1
- package/dist/cjs/schema/marks/annotation.js +1 -1
- package/dist/cjs/schema/marks/fragment.js +77 -0
- package/dist/cjs/schema/marks/index.js +63 -49
- package/dist/cjs/schema/marks/link.js +2 -55
- package/dist/cjs/schema/marks/text-color.js +18 -3
- package/dist/cjs/schema/marks/unsupported-mark.js +1 -0
- package/dist/cjs/schema/nodes/bodied-extension.js +1 -1
- package/dist/cjs/schema/nodes/bullet-list.js +1 -1
- package/dist/cjs/schema/nodes/caption.js +0 -1
- package/dist/cjs/schema/nodes/decision-list.js +1 -1
- package/dist/cjs/schema/nodes/doc.js +1 -1
- package/dist/cjs/schema/nodes/expand.js +1 -1
- package/dist/cjs/schema/nodes/index.js +146 -152
- package/dist/cjs/schema/nodes/layout-column.js +1 -1
- package/dist/cjs/schema/nodes/media-single.js +1 -1
- package/dist/cjs/schema/nodes/media.js +1 -1
- package/dist/cjs/schema/nodes/ordered-list.js +1 -1
- package/dist/cjs/schema/nodes/panel.js +2 -28
- package/dist/cjs/schema/nodes/paragraph.js +168 -25
- package/dist/cjs/schema/nodes/tableNodes.js +4 -4
- package/dist/cjs/schema/nodes/task-list.js +1 -1
- package/dist/cjs/steps/analytics.js +1 -1
- package/dist/cjs/steps/table/sort-column.js +1 -1
- package/dist/cjs/steps/table/utils/cell-step.js +1 -1
- package/dist/cjs/steps/table/utils/table-map.js +2 -2
- package/dist/cjs/steps/type-ahead.js +1 -1
- package/dist/cjs/steps.js +10 -10
- package/dist/cjs/utils/colors.js +4 -4
- package/dist/cjs/utils/confluence/emoji.js +1 -1
- package/dist/cjs/utils/extensions.js +1 -1
- package/dist/cjs/utils/index.js +48 -48
- package/dist/cjs/utils/url.js +9 -2
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/schema/create-schema.js +7 -4
- package/dist/es2019/schema/default-schema.js +7 -11
- package/dist/es2019/schema/index.js +2 -2
- package/dist/es2019/schema/jira-schema.js +1 -1
- package/dist/es2019/schema/marks/fragment.js +59 -0
- package/dist/es2019/schema/marks/index.js +2 -1
- package/dist/es2019/schema/marks/link.js +3 -51
- package/dist/es2019/schema/marks/text-color.js +15 -1
- package/dist/es2019/schema/marks/unsupported-mark.js +1 -0
- package/dist/es2019/schema/nodes/bodied-extension.js +1 -1
- package/dist/es2019/schema/nodes/caption.js +0 -1
- package/dist/es2019/schema/nodes/doc.js +1 -1
- package/dist/es2019/schema/nodes/expand.js +1 -1
- package/dist/es2019/schema/nodes/index.js +1 -1
- package/dist/es2019/schema/nodes/layout-column.js +1 -1
- package/dist/es2019/schema/nodes/media-single.js +1 -1
- package/dist/es2019/schema/nodes/panel.js +1 -28
- package/dist/es2019/schema/nodes/paragraph.js +163 -25
- package/dist/es2019/schema/nodes/tableNodes.js +3 -3
- package/dist/es2019/utils/url.js +7 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/schema/create-schema.js +7 -4
- package/dist/esm/schema/default-schema.js +7 -11
- package/dist/esm/schema/index.js +2 -2
- package/dist/esm/schema/jira-schema.js +1 -1
- package/dist/esm/schema/marks/fragment.js +64 -0
- package/dist/esm/schema/marks/index.js +2 -1
- package/dist/esm/schema/marks/link.js +3 -55
- package/dist/esm/schema/marks/text-color.js +17 -3
- package/dist/esm/schema/marks/unsupported-mark.js +1 -0
- package/dist/esm/schema/nodes/bodied-extension.js +1 -1
- package/dist/esm/schema/nodes/caption.js +0 -1
- package/dist/esm/schema/nodes/doc.js +1 -1
- package/dist/esm/schema/nodes/expand.js +1 -1
- package/dist/esm/schema/nodes/index.js +1 -1
- package/dist/esm/schema/nodes/layout-column.js +1 -1
- package/dist/esm/schema/nodes/media-single.js +1 -1
- package/dist/esm/schema/nodes/panel.js +1 -26
- package/dist/esm/schema/nodes/paragraph.js +167 -25
- package/dist/esm/schema/nodes/tableNodes.js +3 -3
- package/dist/esm/utils/url.js +7 -1
- package/dist/esm/version.json +1 -1
- package/dist/json-schema/v1/full.json +108 -73
- package/dist/json-schema/v1/stage-0.json +63 -26
- package/dist/types/index.d.ts +2 -2
- package/dist/types/schema/index.d.ts +3 -3
- package/dist/types/schema/marks/fragment.d.ts +30 -0
- package/dist/types/schema/marks/index.d.ts +2 -0
- package/dist/types/schema/marks/link.d.ts +3 -0
- package/dist/types/schema/nodes/block-card.d.ts +3 -0
- package/dist/types/schema/nodes/bodied-extension.d.ts +7 -5
- package/dist/types/schema/nodes/caption.d.ts +0 -1
- package/dist/types/schema/nodes/embed-card.d.ts +3 -0
- package/dist/types/schema/nodes/extension.d.ts +7 -5
- package/dist/types/schema/nodes/index.d.ts +1 -1
- package/dist/types/schema/nodes/inline-card.d.ts +0 -9
- package/dist/types/schema/nodes/inline-extension.d.ts +7 -5
- package/dist/types/schema/nodes/media-single.d.ts +0 -1
- package/dist/types/schema/nodes/panel.d.ts +1 -11
- package/json-schema/v1/full.json +108 -73
- package/json-schema/v1/stage-0.json +63 -26
- package/package.json +11 -8
- package/test-helpers/schema.ts +1 -0
@@ -1,12 +1,10 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import { allowCustomPanel, createSchema } from './create-schema';
|
5
|
-
import { mediaSingleWithCaption } from './nodes';
|
1
|
+
import { layoutSectionWithSingleColumn } from './nodes';
|
2
|
+
import { dataConsumer, fragment } from './marks';
|
3
|
+
import { createSchema } from './create-schema';
|
6
4
|
|
7
5
|
const getDefaultSchemaConfig = () => {
|
8
6
|
let defaultSchemaConfig = {
|
9
|
-
nodes: ['doc', 'paragraph', 'text', 'bulletList', 'orderedList', 'listItem', 'heading', 'blockquote', 'codeBlock', 'panel', 'rule', 'image', 'mention', 'media', 'mediaGroup', 'mediaSingle', 'mediaInline', 'confluenceUnsupportedBlock', 'confluenceUnsupportedInline', 'confluenceJiraIssue', 'expand', 'nestedExpand', 'extension', 'inlineExtension', 'bodiedExtension', 'hardBreak', 'emoji', 'table', 'tableCell', 'tableHeader', 'tableRow', 'decisionList', 'decisionItem', 'taskList', 'taskItem', 'unknownBlock', 'date', 'status', 'placeholder', 'layoutSection', 'layoutColumn', 'inlineCard', 'blockCard', 'embedCard', 'unsupportedBlock', 'unsupportedInline'],
|
7
|
+
nodes: ['doc', 'paragraph', 'text', 'bulletList', 'orderedList', 'listItem', 'heading', 'blockquote', 'codeBlock', 'panel', 'rule', 'image', 'caption', 'mention', 'media', 'mediaGroup', 'mediaSingle', 'mediaInline', 'confluenceUnsupportedBlock', 'confluenceUnsupportedInline', 'confluenceJiraIssue', 'expand', 'nestedExpand', 'extension', 'inlineExtension', 'bodiedExtension', 'hardBreak', 'emoji', 'table', 'tableCell', 'tableHeader', 'tableRow', 'decisionList', 'decisionItem', 'taskList', 'taskItem', 'unknownBlock', 'date', 'status', 'placeholder', 'layoutSection', 'layoutColumn', 'inlineCard', 'blockCard', 'embedCard', 'unsupportedBlock', 'unsupportedInline'],
|
10
8
|
marks: ['link', 'em', 'strong', 'strike', 'subsup', 'underline', 'code', 'textColor', 'confluenceInlineComment', 'breakout', 'alignment', 'indentation', 'annotation', 'unsupportedMark', 'unsupportedNodeAttribute', 'typeAheadQuery' // https://product-fabric.atlassian.net/browse/ED-10214,
|
11
9
|
]
|
12
10
|
};
|
@@ -15,18 +13,16 @@ const getDefaultSchemaConfig = () => {
|
|
15
13
|
|
16
14
|
export const defaultSchemaConfig = getDefaultSchemaConfig();
|
17
15
|
export const getSchemaBasedOnStage = (stage = 'final') => {
|
18
|
-
const defaultSchemaConfig = getDefaultSchemaConfig();
|
16
|
+
const defaultSchemaConfig = getDefaultSchemaConfig();
|
19
17
|
|
20
18
|
if (stage === 'stage0') {
|
21
19
|
defaultSchemaConfig.customNodeSpecs = {
|
22
|
-
panel: customPanel(allowCustomPanel),
|
23
|
-
mediaSingle: mediaSingleWithCaption,
|
24
20
|
layoutSection: layoutSectionWithSingleColumn
|
25
21
|
};
|
26
22
|
defaultSchemaConfig.customMarkSpecs = {
|
27
|
-
dataConsumer: dataConsumer
|
23
|
+
dataConsumer: dataConsumer,
|
24
|
+
fragment
|
28
25
|
};
|
29
|
-
defaultSchemaConfig.nodes.push('caption');
|
30
26
|
defaultSchemaConfig.nodes.push('mediaInline');
|
31
27
|
}
|
32
28
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
export { PanelType, blockCard, blockquote, bodiedExtension, bulletList, bulletListSelector, caption, codeBlock, codeBlockToJSON, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, date, decisionItem, decisionList, decisionListSelector, doc, embedCard, emoji, expand, expandToJSON, extension, hardBreak, heading, image, inlineCard, inlineExtension, layoutColumn, layoutSection, layoutSectionWithSingleColumn, listItem, media, mediaGroup, mediaSingle, mediaInline, mediaSingleWithCaption, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, orderedList, orderedListSelector, panel,
|
2
|
-
export { AnnotationTypes, alignment, alignmentPositionMap, annotation, breakout, code, colorPalette, colorPaletteExtended, confluenceInlineComment, dataConsumer, dataConsumerToJSON, em, indentation, link, linkToJSON, strike, strong, subsup, textColor, typeAheadQuery, underline, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute } from './marks';
|
1
|
+
export { PanelType, blockCard, blockquote, bodiedExtension, bulletList, bulletListSelector, caption, codeBlock, codeBlockToJSON, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, date, decisionItem, decisionList, decisionListSelector, doc, embedCard, emoji, expand, expandToJSON, extension, hardBreak, heading, image, inlineCard, inlineExtension, layoutColumn, layoutSection, layoutSectionWithSingleColumn, listItem, media, mediaGroup, mediaSingle, mediaInline, mediaSingleWithCaption, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, orderedList, orderedListSelector, panel, paragraph, placeholder, rule, getCellAttrs, getCellDomAttrs, status, table, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, toJSONTableCell, toJSONTableHeader, unknownBlock, unsupportedBlock, unsupportedInline } from './nodes';
|
2
|
+
export { AnnotationTypes, alignment, alignmentPositionMap, annotation, breakout, code, colorPalette, colorPaletteExtended, confluenceInlineComment, dataConsumer, dataConsumerToJSON, em, fragment, fragmentToJSON, indentation, link, linkToJSON, strike, strong, subsup, textColor, typeAheadQuery, underline, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute } from './marks';
|
3
3
|
export { unsupportedNodeTypesForMediaCards } from './unsupported';
|
4
4
|
export { inlineNodes } from './inline-nodes';
|
5
5
|
export { sanitizeNodes, createSchema } from './create-schema';
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import { isDOMElement } from '../../utils/parseDOM';
|
2
|
+
|
3
|
+
const parseFragment = maybeValue => {
|
4
|
+
var _maybeValue$getAttrib;
|
5
|
+
|
6
|
+
if (!isDOMElement(maybeValue)) {
|
7
|
+
return false;
|
8
|
+
}
|
9
|
+
|
10
|
+
const name = (_maybeValue$getAttrib = maybeValue.getAttribute('data-name')) !== null && _maybeValue$getAttrib !== void 0 ? _maybeValue$getAttrib : undefined;
|
11
|
+
const localId = maybeValue.getAttribute('data-localId');
|
12
|
+
|
13
|
+
if (!localId) {
|
14
|
+
return false;
|
15
|
+
}
|
16
|
+
|
17
|
+
return {
|
18
|
+
localId,
|
19
|
+
name
|
20
|
+
};
|
21
|
+
};
|
22
|
+
|
23
|
+
export const fragment = {
|
24
|
+
inclusive: false,
|
25
|
+
excludes: '',
|
26
|
+
attrs: {
|
27
|
+
localId: {
|
28
|
+
default: ''
|
29
|
+
},
|
30
|
+
name: {
|
31
|
+
default: null
|
32
|
+
}
|
33
|
+
},
|
34
|
+
parseDOM: [{
|
35
|
+
tag: '[data-mark-type="fragment"]',
|
36
|
+
getAttrs: maybeValue => parseFragment(maybeValue)
|
37
|
+
}],
|
38
|
+
|
39
|
+
toDOM(mark, inline) {
|
40
|
+
const wrapperStyle = inline ? 'span' : 'div';
|
41
|
+
return [wrapperStyle, {
|
42
|
+
'data-mark-type': 'fragment',
|
43
|
+
'data-name': mark.attrs.name,
|
44
|
+
'data-localId': mark.attrs.localId
|
45
|
+
}];
|
46
|
+
}
|
47
|
+
|
48
|
+
};
|
49
|
+
export const toJSON = mark => {
|
50
|
+
return {
|
51
|
+
type: mark.type.name,
|
52
|
+
attrs: {
|
53
|
+
localId: mark.attrs.localId,
|
54
|
+
...(mark.attrs.name ? {
|
55
|
+
name: mark.attrs.name
|
56
|
+
} : {})
|
57
|
+
}
|
58
|
+
};
|
59
|
+
};
|
@@ -14,4 +14,5 @@ export { indentation } from './indentation';
|
|
14
14
|
export { annotation, AnnotationMarkStates, buildDataAttributes as buildAnnotationMarkDataAttributes, AnnotationTypes } from './annotation';
|
15
15
|
export { unsupportedMark } from './unsupported-mark';
|
16
16
|
export { unsupportedNodeAttribute } from './unsupported-node-attributes';
|
17
|
-
export { dataConsumer, toJSON as dataConsumerToJSON } from './data-consumer';
|
17
|
+
export { dataConsumer, toJSON as dataConsumerToJSON } from './data-consumer';
|
18
|
+
export { fragment, toJSON as fragmentToJSON } from './fragment';
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
import { LINK, COLOR } from '../groups';
|
1
|
+
import { LINK } from '../groups';
|
3
2
|
import { isSafeUrl, normalizeUrl } from '../../utils/url';
|
4
3
|
|
5
4
|
const getLinkAttrs = attribute => domNode => {
|
@@ -18,30 +17,8 @@ const getLinkAttrs = attribute => domNode => {
|
|
18
17
|
return attrs;
|
19
18
|
};
|
20
19
|
|
21
|
-
const getLinkAttrsWithCheck = attribute => domNode => {
|
22
|
-
const dom = domNode;
|
23
|
-
const hasTextOnlyChildren = Array.from(dom.childNodes).every(node => node.nodeType === Node.TEXT_NODE || node.nodeName === 'SPAN');
|
24
|
-
|
25
|
-
if (hasTextOnlyChildren) {
|
26
|
-
const href = dom.getAttribute(attribute) || '';
|
27
|
-
const attrs = {
|
28
|
-
__confluenceMetadata: dom.hasAttribute('__confluenceMetadata') ? JSON.parse(dom.getAttribute('__confluenceMetadata') || '') : undefined
|
29
|
-
};
|
30
|
-
|
31
|
-
if (isSafeUrl(href)) {
|
32
|
-
attrs.href = normalizeUrl(href);
|
33
|
-
} else {
|
34
|
-
return false;
|
35
|
-
}
|
36
|
-
|
37
|
-
return attrs;
|
38
|
-
}
|
39
|
-
|
40
|
-
return false;
|
41
|
-
};
|
42
|
-
|
43
20
|
export const link = {
|
44
|
-
excludes: `${LINK}
|
21
|
+
excludes: `${LINK}`,
|
45
22
|
// ED-5844 No multiple links in media node
|
46
23
|
group: LINK,
|
47
24
|
attrs: {
|
@@ -57,39 +34,14 @@ export const link = {
|
|
57
34
|
contentElement: node => {
|
58
35
|
const clone = node.cloneNode(true);
|
59
36
|
clone.removeAttribute('data-block-link');
|
37
|
+
clone.setAttribute('data-skip-paste', 'true');
|
60
38
|
const wrapper = document.createElement('div');
|
61
39
|
wrapper.appendChild(clone);
|
62
40
|
return wrapper;
|
63
41
|
}
|
64
42
|
}, {
|
65
43
|
tag: 'a[href]',
|
66
|
-
context: 'mediaSingle/|taskItem/|decisionItem/',
|
67
44
|
getAttrs: getLinkAttrs('href')
|
68
|
-
}, {
|
69
|
-
tag: 'a[href]',
|
70
|
-
getAttrs: getLinkAttrsWithCheck('href')
|
71
|
-
}, {
|
72
|
-
/**
|
73
|
-
* When links aren't wrapped in a paragraph and due to
|
74
|
-
* the odd nature of how our schema is set up, prosemirror will
|
75
|
-
* add the link to the paragraph node itself where it should be on
|
76
|
-
* the text node, this satisfies our schema because link is allowed
|
77
|
-
* in many places (e.g. listitem)
|
78
|
-
* This change comes through via prosemirror-model@1.9.1
|
79
|
-
*/
|
80
|
-
tag: 'a[href]',
|
81
|
-
getAttrs: getLinkAttrsWithCheck('href'),
|
82
|
-
getContent: (node, schema) => {
|
83
|
-
if (node instanceof HTMLAnchorElement) {
|
84
|
-
const href = node.getAttribute('href');
|
85
|
-
const text = node.innerText;
|
86
|
-
return Fragment.from(schema.nodes.paragraph.createChecked(undefined, schema.text(text, [schema.marks.link.create({
|
87
|
-
href
|
88
|
-
})])));
|
89
|
-
}
|
90
|
-
|
91
|
-
return Fragment.empty;
|
92
|
-
}
|
93
45
|
}],
|
94
46
|
|
95
47
|
toDOM(node, isInline) {
|
@@ -52,6 +52,18 @@ export const textColor = {
|
|
52
52
|
} // else handle other colour formats
|
53
53
|
|
54
54
|
|
55
|
+
return hexColor && (colorPalette.has(hexColor) || colorPaletteExtended.has(hexColor)) ? {
|
56
|
+
color: hexColor
|
57
|
+
} : false;
|
58
|
+
}
|
59
|
+
}, {
|
60
|
+
tag: '.fabric-text-color-mark',
|
61
|
+
getAttrs: maybeElement => {
|
62
|
+
if (!(maybeElement instanceof HTMLElement)) {
|
63
|
+
return false;
|
64
|
+
}
|
65
|
+
|
66
|
+
const hexColor = maybeElement.dataset.textCustomColor;
|
55
67
|
return hexColor && (colorPalette.has(hexColor) || colorPaletteExtended.has(hexColor)) ? {
|
56
68
|
color: hexColor
|
57
69
|
} : false;
|
@@ -60,7 +72,9 @@ export const textColor = {
|
|
60
72
|
|
61
73
|
toDOM(mark) {
|
62
74
|
return ['span', {
|
63
|
-
|
75
|
+
class: 'fabric-text-color-mark',
|
76
|
+
style: `--custom-text-color: ${mark.attrs.color}`,
|
77
|
+
['data-text-custom-color']: mark.attrs.color
|
64
78
|
}];
|
65
79
|
}
|
66
80
|
|
@@ -4,7 +4,7 @@ const createBodiedExtensionNodeSpec = () => {
|
|
4
4
|
const nodeSpec = {
|
5
5
|
inline: false,
|
6
6
|
group: 'block',
|
7
|
-
marks: 'link dataConsumer',
|
7
|
+
marks: 'link dataConsumer fragment',
|
8
8
|
content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaGroup | mediaSingle | decisionList | taskList | table | blockCard | extension | unsupportedBlock | embedCard)+',
|
9
9
|
defining: true,
|
10
10
|
selectable: true,
|
@@ -3,5 +3,5 @@
|
|
3
3
|
*/
|
4
4
|
export const doc = {
|
5
5
|
content: '(block|layoutSection)+',
|
6
|
-
marks: 'alignment breakout dataConsumer indentation link unsupportedMark unsupportedNodeAttribute'
|
6
|
+
marks: 'alignment breakout dataConsumer fragment indentation link unsupportedMark unsupportedNodeAttribute'
|
7
7
|
};
|
@@ -20,7 +20,7 @@ function getExpandAttrs(domNode) {
|
|
20
20
|
export const expand = {
|
21
21
|
inline: false,
|
22
22
|
group: 'block',
|
23
|
-
marks: 'link dataConsumer unsupportedMark unsupportedNodeAttribute',
|
23
|
+
marks: 'link dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
|
24
24
|
content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaGroup | mediaSingle | decisionList | taskList | table | blockCard | embedCard | extension | unsupportedBlock)+',
|
25
25
|
isolating: true,
|
26
26
|
selectable: true,
|
@@ -15,7 +15,7 @@ export { emoji } from './emoji';
|
|
15
15
|
export { image } from './image';
|
16
16
|
export { mention, toJSON as mentionToJSON } from './mention';
|
17
17
|
export { listItem } from './list-item';
|
18
|
-
export { panel,
|
18
|
+
export { panel, PanelType } from './panel';
|
19
19
|
export { text } from './text';
|
20
20
|
export { default as unknownBlock } from './unknown-block';
|
21
21
|
export { caption } from './caption';
|
@@ -4,7 +4,7 @@
|
|
4
4
|
export const layoutColumn = {
|
5
5
|
content: '(block|unsupportedBlock)+',
|
6
6
|
isolating: true,
|
7
|
-
marks: 'link alignment indentation dataConsumer unsupportedMark unsupportedNodeAttribute',
|
7
|
+
marks: 'link alignment indentation dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
|
8
8
|
selectable: false,
|
9
9
|
attrs: {
|
10
10
|
width: {
|
@@ -17,7 +17,6 @@
|
|
17
17
|
|
18
18
|
/**
|
19
19
|
* @name mediaSingle_caption_node
|
20
|
-
* @stage 0
|
21
20
|
*/
|
22
21
|
export const defaultAttrs = {
|
23
22
|
width: {
|
@@ -64,6 +63,7 @@ export const mediaSingle = {
|
|
64
63
|
|
65
64
|
};
|
66
65
|
export const mediaSingleWithCaption = { ...mediaSingle,
|
66
|
+
atom: false,
|
67
67
|
content: 'media|unsupportedBlock+|media (caption|unsupportedBlock) unsupportedBlock*'
|
68
68
|
};
|
69
69
|
export const toJSON = node => ({
|
@@ -51,7 +51,7 @@ const getParseDOMAttrs = (allowCustomPanel, dom) => {
|
|
51
51
|
return parseDOMAttrs;
|
52
52
|
};
|
53
53
|
|
54
|
-
export const
|
54
|
+
export const panel = allowCustomPanel => {
|
55
55
|
const panelNodeSpec = {
|
56
56
|
group: 'block',
|
57
57
|
content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
|
@@ -69,31 +69,4 @@ export const customPanel = allowCustomPanel => {
|
|
69
69
|
|
70
70
|
};
|
71
71
|
return panelNodeSpec;
|
72
|
-
};
|
73
|
-
export const panel = {
|
74
|
-
group: 'block',
|
75
|
-
content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
|
76
|
-
marks: 'unsupportedMark unsupportedNodeAttribute',
|
77
|
-
attrs: {
|
78
|
-
panelType: {
|
79
|
-
default: 'info'
|
80
|
-
}
|
81
|
-
},
|
82
|
-
parseDOM: [{
|
83
|
-
tag: 'div[data-panel-type]',
|
84
|
-
getAttrs: dom => ({
|
85
|
-
panelType: dom.getAttribute('data-panel-type')
|
86
|
-
})
|
87
|
-
}],
|
88
|
-
|
89
|
-
toDOM(node) {
|
90
|
-
const {
|
91
|
-
panelType
|
92
|
-
} = node.attrs;
|
93
|
-
const attrs = {
|
94
|
-
'data-panel-type': panelType
|
95
|
-
};
|
96
|
-
return ['div', attrs, ['div', {}, 0]];
|
97
|
-
}
|
98
|
-
|
99
72
|
};
|
@@ -1,35 +1,173 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
2
|
+
import { isSafeUrl } from '../../utils/url';
|
3
|
+
|
4
|
+
const getLinkContent = (node, schema) => {
|
5
|
+
if (!(node instanceof HTMLAnchorElement)) {
|
6
|
+
return Fragment.empty;
|
7
|
+
}
|
8
|
+
|
9
|
+
const href = node.getAttribute('href') || '';
|
10
|
+
const text = node.innerText;
|
11
|
+
|
12
|
+
if (!text || text.length === 0) {
|
13
|
+
return Fragment.empty;
|
14
|
+
}
|
15
|
+
|
16
|
+
const marks = isSafeUrl(href) ? [schema.marks.link.create({
|
17
|
+
href
|
18
|
+
})] : [];
|
19
|
+
const textNode = schema.text(text, marks);
|
20
|
+
return Fragment.from(textNode);
|
21
|
+
};
|
22
|
+
|
23
|
+
const blockTags = {
|
24
|
+
address: true,
|
25
|
+
article: true,
|
26
|
+
aside: true,
|
27
|
+
blockquote: true,
|
28
|
+
canvas: true,
|
29
|
+
dd: true,
|
30
|
+
div: true,
|
31
|
+
dl: true,
|
32
|
+
fieldset: true,
|
33
|
+
figcaption: true,
|
34
|
+
figure: true,
|
35
|
+
footer: true,
|
36
|
+
form: true,
|
37
|
+
h1: true,
|
38
|
+
h2: true,
|
39
|
+
h3: true,
|
40
|
+
h4: true,
|
41
|
+
h5: true,
|
42
|
+
h6: true,
|
43
|
+
header: true,
|
44
|
+
hgroup: true,
|
45
|
+
hr: true,
|
46
|
+
li: true,
|
47
|
+
noscript: true,
|
48
|
+
ol: true,
|
49
|
+
output: true,
|
50
|
+
p: true,
|
51
|
+
pre: true,
|
52
|
+
section: true,
|
53
|
+
table: true,
|
54
|
+
tfoot: true,
|
55
|
+
ul: true
|
56
|
+
};
|
57
|
+
|
58
|
+
const isListItemNode = node => {
|
59
|
+
return Boolean(node && node.nodeName.toLowerCase() === 'li');
|
60
|
+
};
|
61
|
+
|
62
|
+
const isTextNode = node => {
|
63
|
+
return Boolean(node && node.nodeType === Node.TEXT_NODE);
|
64
|
+
};
|
65
|
+
|
66
|
+
const isImageNode = node => {
|
67
|
+
return Boolean(node && node.nodeName.toLowerCase() === 'img');
|
68
|
+
};
|
69
|
+
|
70
|
+
const hasInlineImage = node => {
|
71
|
+
if (!node) {
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
|
75
|
+
return Array.from(node.childNodes).some(child => {
|
76
|
+
const isImage = isImageNode(child);
|
77
|
+
|
78
|
+
if (!isImage && child.childNodes) {
|
79
|
+
return Array.from(node.childNodes).some(node => hasInlineImage(node));
|
80
|
+
}
|
81
|
+
|
82
|
+
return isImage;
|
83
|
+
});
|
84
|
+
};
|
85
|
+
|
86
|
+
const hasWhiteSpacePre = node => {
|
87
|
+
return Boolean(node instanceof HTMLElement && node.style.whiteSpace === 'pre');
|
88
|
+
};
|
89
|
+
|
90
|
+
const hasFontFamilyMonospace = node => {
|
91
|
+
return Boolean(node instanceof HTMLElement && node.style.fontFamily.includes('monospace'));
|
92
|
+
};
|
93
|
+
|
94
|
+
const isBlockLevelNode = node => {
|
95
|
+
return Boolean(node && blockTags.hasOwnProperty(node.nodeName.toLowerCase()));
|
96
|
+
};
|
97
|
+
|
98
|
+
const NOT_INTERNAL_LINKS = [':not([data-inline-card])', ':not([data-block-card])', ':not([data-block-link])', ':not([data-skip-paste])'].join('');
|
99
|
+
const ANCHOR_LINK = `a[href]${NOT_INTERNAL_LINKS}`;
|
100
|
+
const NOT_INTERNAL_ELEMENTS = [':not(.code-block)', ':not([data-node-type])', ':not([data-embed-card])', ':not([data-layout-section])', ':not([data-task-local-id])', ':not([data-task-state])', ':not([data-pm-slice])', ':not([data-mark-type])'].join('');
|
25
101
|
const pDOM = ['p', 0];
|
26
102
|
export const paragraph = {
|
27
103
|
selectable: false,
|
28
104
|
content: 'inline*',
|
29
105
|
group: 'block',
|
30
|
-
marks: 'strong code em link strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer',
|
106
|
+
marks: 'strong code em link strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment',
|
31
107
|
parseDOM: [{
|
32
108
|
tag: 'p'
|
109
|
+
}, {
|
110
|
+
tag: `div${NOT_INTERNAL_ELEMENTS}, li:not([data-pm-slice])`,
|
111
|
+
priority: 100,
|
112
|
+
getAttrs: node => {
|
113
|
+
if (!(node instanceof Node)) {
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
|
117
|
+
const isCodeBlock = hasWhiteSpacePre(node) || hasFontFamilyMonospace(node);
|
118
|
+
|
119
|
+
if (isCodeBlock || !node.hasChildNodes()) {
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
|
123
|
+
const hasInlineChildren = Array.from(node.childNodes).every(child => !isBlockLevelNode(child) && // IMG is considered block for mediaSingle
|
124
|
+
!isImageNode(child));
|
125
|
+
|
126
|
+
if (!hasInlineChildren) {
|
127
|
+
return false;
|
128
|
+
}
|
129
|
+
|
130
|
+
if ( // We can skip this rule for pure list items
|
131
|
+
isListItemNode(node) && Array.from(node.childNodes).every(isTextNode)) {
|
132
|
+
return false;
|
133
|
+
}
|
134
|
+
|
135
|
+
return null;
|
136
|
+
}
|
137
|
+
}, {
|
138
|
+
tag: `:not(span) + ${ANCHOR_LINK}`,
|
139
|
+
priority: 100,
|
140
|
+
getContent: getLinkContent
|
141
|
+
}, {
|
142
|
+
tag: `:not(span) > ${ANCHOR_LINK}:first-child`,
|
143
|
+
getAttrs: node => {
|
144
|
+
if (!(node instanceof Node)) {
|
145
|
+
return false;
|
146
|
+
}
|
147
|
+
|
148
|
+
if (isBlockLevelNode(node.firstChild)) {
|
149
|
+
return null;
|
150
|
+
}
|
151
|
+
|
152
|
+
if (hasInlineImage(node)) {
|
153
|
+
return false;
|
154
|
+
}
|
155
|
+
|
156
|
+
const isNextSiblingValid = node.nextSibling === null || node.nextSibling instanceof Text && (node.nextSibling.textContent || '').trim().length === 0;
|
157
|
+
|
158
|
+
if (isNextSiblingValid) {
|
159
|
+
return null;
|
160
|
+
} // This rule should not match when there is any sibling after the anchor
|
161
|
+
|
162
|
+
|
163
|
+
if (!isBlockLevelNode(node.nextSibling)) {
|
164
|
+
return false;
|
165
|
+
}
|
166
|
+
|
167
|
+
return null;
|
168
|
+
},
|
169
|
+
priority: 100,
|
170
|
+
getContent: getLinkContent
|
33
171
|
}],
|
34
172
|
|
35
173
|
toDOM() {
|
@@ -103,7 +103,7 @@ const createTableSpec = () => {
|
|
103
103
|
const tableNodeSpec = {
|
104
104
|
content: 'tableRow+',
|
105
105
|
attrs: attrs,
|
106
|
-
marks: 'unsupportedMark unsupportedNodeAttribute',
|
106
|
+
marks: 'fragment unsupportedMark unsupportedNodeAttribute',
|
107
107
|
tableRole: 'table',
|
108
108
|
isolating: true,
|
109
109
|
selectable: false,
|
@@ -183,7 +183,7 @@ export const tableCell = {
|
|
183
183
|
content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaSingle | mediaGroup | decisionList | taskList | blockCard | embedCard | extension | nestedExpand | unsupportedBlock)+',
|
184
184
|
attrs: cellAttrs,
|
185
185
|
tableRole: 'cell',
|
186
|
-
marks: 'link alignment dataConsumer unsupportedMark unsupportedNodeAttribute',
|
186
|
+
marks: 'link alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
|
187
187
|
isolating: true,
|
188
188
|
parseDOM: [// Ignore number cell copied from renderer
|
189
189
|
{
|
@@ -210,7 +210,7 @@ export const tableHeader = {
|
|
210
210
|
attrs: cellAttrs,
|
211
211
|
tableRole: 'header_cell',
|
212
212
|
isolating: true,
|
213
|
-
marks: 'link alignment dataConsumer unsupportedMark unsupportedNodeAttribute',
|
213
|
+
marks: 'link alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
|
214
214
|
parseDOM: [{
|
215
215
|
tag: 'th',
|
216
216
|
getAttrs: dom => getCellAttrs(dom, {
|
package/dist/es2019/utils/url.js
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
import LinkifyIt from 'linkify-it';
|
2
2
|
const whitelistedURLPatterns = [/^https?:\/\//im, /^ftps?:\/\//im, /^\//im, /^mailto:/im, /^skype:/im, /^callto:/im, /^facetime:/im, /^git:/im, /^irc6?:/im, /^news:/im, /^nntp:/im, /^feed:/im, /^cvs:/im, /^svn:/im, /^mvn:/im, /^ssh:/im, /^scp:\/\//im, /^sftp:\/\//im, /^itms:/im, /^notes:/im, /^hipchat:\/\//im, /^sourcetree:/im, /^urn:/im, /^tel:/im, /^xmpp:/im, /^telnet:/im, /^vnc:/im, /^rdp:/im, /^whatsapp:/im, /^slack:/im, /^sips?:/im, /^magnet:/im, /^#/im];
|
3
3
|
export const isSafeUrl = url => {
|
4
|
-
|
4
|
+
const urlTrimmed = url.trim();
|
5
|
+
|
6
|
+
if (urlTrimmed.length === 0) {
|
7
|
+
return true;
|
8
|
+
}
|
9
|
+
|
10
|
+
return whitelistedURLPatterns.some(p => p.test(urlTrimmed));
|
5
11
|
};
|
6
12
|
export const linkify = LinkifyIt();
|
7
13
|
linkify.add('sourcetree:', 'http:');
|
package/dist/es2019/version.json
CHANGED
package/dist/esm/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export { AnnotationTypes, PanelType, alignment, alignmentPositionMap, annotation, bitbucketSchema, blockCard, blockquote, bodiedExtension, breakout, bulletList, bulletListSelector, caption, code, codeBlock, codeBlockToJSON, colorPalette, colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceSchema, confluenceSchemaWithMediaSingle, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createJIRASchema, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, defaultSchema, defaultSchemaConfig, doc, em, embedCard, emoji, expand, expandToJSON, extension, getSchemaBasedOnStage, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, isSchemaWithAdvancedTextFormattingMarks, isSchemaWithBlockQuotes, isSchemaWithCodeBlock, isSchemaWithEmojis, isSchemaWithLinks, isSchemaWithLists, isSchemaWithMedia, isSchemaWithMentions, isSchemaWithSubSupMark, isSchemaWithTables, isSchemaWithTextColor, layoutColumn, layoutSection, link, linkToJSON, listItem, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, orderedList, orderedListSelector, panel,
|
1
|
+
export { AnnotationTypes, PanelType, alignment, alignmentPositionMap, annotation, bitbucketSchema, blockCard, blockquote, bodiedExtension, breakout, bulletList, bulletListSelector, caption, code, codeBlock, codeBlockToJSON, colorPalette, colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceSchema, confluenceSchemaWithMediaSingle, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createJIRASchema, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, defaultSchema, defaultSchemaConfig, doc, em, embedCard, emoji, expand, expandToJSON, extension, fragment, fragmentToJSON, getSchemaBasedOnStage, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, isSchemaWithAdvancedTextFormattingMarks, isSchemaWithBlockQuotes, isSchemaWithCodeBlock, isSchemaWithEmojis, isSchemaWithLinks, isSchemaWithLists, isSchemaWithMedia, isSchemaWithMentions, isSchemaWithSubSupMark, isSchemaWithTables, isSchemaWithTextColor, layoutColumn, layoutSection, link, linkToJSON, listItem, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, orderedList, orderedListSelector, panel, paragraph, placeholder, rule, sanitizeNodes, getCellAttrs, getCellDomAttrs, status, strike, strong, subsup, table, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, textColor, toJSONTableCell, toJSONTableHeader, typeAheadQuery, underline, unknownBlock, unsupportedBlock, unsupportedInline, unsupportedNodeTypesForMediaCards, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute } from './schema';
|
2
2
|
export { B100, B400, B50, B500, B75, G200, G300, G400, G50, G500, G75, N0, N20, N200, N30, N300, N40, N50, N500, N60, N80, N800, N90, P100, P300, P400, P50, P500, P75, R100, R300, R400, R50, R500, R75, T100, T300, T50, T500, T75, Y200, Y400, Y50, Y500, Y75, acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, generateUuid, getEmojiAcName, getLinkMatch, hexToRgb, hexToRgba, isHex, isRgb, isSafeUrl, linkify, linkifyMatch, normalizeHexColor, normalizeUrl, rgbToHex, uuid } from './utils';
|