@atlaskit/adf-schema 19.2.3 → 19.3.2

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/index.js +12 -0
  3. package/dist/cjs/schema/create-schema.js +5 -1
  4. package/dist/cjs/schema/default-schema.js +4 -8
  5. package/dist/cjs/schema/marks/link.js +1 -54
  6. package/dist/cjs/schema/nodes/emoji.js +4 -0
  7. package/dist/cjs/schema/nodes/panel.js +59 -28
  8. package/dist/cjs/schema/nodes/paragraph.js +167 -24
  9. package/dist/cjs/utils/index.js +12 -0
  10. package/dist/cjs/utils/url.js +55 -3
  11. package/dist/cjs/version.json +1 -1
  12. package/dist/es2019/index.js +1 -1
  13. package/dist/es2019/schema/create-schema.js +3 -1
  14. package/dist/es2019/schema/default-schema.js +5 -8
  15. package/dist/es2019/schema/marks/link.js +1 -49
  16. package/dist/es2019/schema/nodes/emoji.js +4 -0
  17. package/dist/es2019/schema/nodes/panel.js +45 -25
  18. package/dist/es2019/schema/nodes/paragraph.js +162 -24
  19. package/dist/es2019/utils/index.js +1 -1
  20. package/dist/es2019/utils/url.js +50 -3
  21. package/dist/es2019/version.json +1 -1
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/schema/create-schema.js +3 -1
  24. package/dist/esm/schema/default-schema.js +5 -8
  25. package/dist/esm/schema/marks/link.js +1 -53
  26. package/dist/esm/schema/nodes/emoji.js +4 -0
  27. package/dist/esm/schema/nodes/panel.js +55 -28
  28. package/dist/esm/schema/nodes/paragraph.js +166 -24
  29. package/dist/esm/utils/index.js +1 -1
  30. package/dist/esm/utils/url.js +50 -3
  31. package/dist/esm/version.json +1 -1
  32. package/dist/types/index.d.ts +1 -1
  33. package/dist/types/schema/create-schema.d.ts +1 -0
  34. package/dist/types/schema/default-schema.d.ts +1 -1
  35. package/dist/types/schema/nodes/panel.d.ts +1 -1
  36. package/dist/types/utils/index.d.ts +1 -1
  37. package/dist/types/utils/url.d.ts +7 -2
  38. package/package.json +2 -2
@@ -1,4 +1,3 @@
1
- import { Fragment } from 'prosemirror-model';
2
1
  import { LINK, COLOR } from '../groups';
3
2
  import { isSafeUrl, normalizeUrl } from '../../utils/url';
4
3
 
@@ -18,28 +17,6 @@ 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
21
  excludes: `${LINK} ${COLOR}`,
45
22
  // ED-5844 No multiple links in media node
@@ -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) {
@@ -28,6 +28,10 @@ export const emoji = {
28
28
  text: dom.getAttribute('data-emoji-text') || emoji.attrs.text.default
29
29
  };
30
30
  }
31
+ }, // Handle copy/paste beautiful panel from renderer />
32
+ {
33
+ tag: 'div.ak-editor-panel__icon',
34
+ ignore: true
31
35
  }, // Handle copy/paste from old <ac:emoticon />
32
36
  {
33
37
  tag: 'img[data-emoticon-name]',
@@ -10,12 +10,8 @@ export let PanelType;
10
10
  PanelType["CUSTOM"] = "custom";
11
11
  })(PanelType || (PanelType = {}));
12
12
 
13
- //TODO: ED-10445 rename to panel and merge with the other panel node spec, after emoji panels moved to full schema
14
- export const customPanel = {
15
- group: 'block',
16
- content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
17
- marks: 'unsupportedMark unsupportedNodeAttribute',
18
- attrs: {
13
+ const getDefaultAttrs = () => {
14
+ let attrs = {
19
15
  panelType: {
20
16
  default: 'info'
21
17
  },
@@ -25,30 +21,54 @@ export const customPanel = {
25
21
  panelColor: {
26
22
  default: null
27
23
  }
28
- },
29
- parseDOM: [{
30
- tag: 'div[data-panel-type]',
31
- getAttrs: dom => ({
32
- panelType: dom.getAttribute('data-panel-type'),
24
+ };
25
+ return attrs;
26
+ };
27
+
28
+ const getDomAttrs = nodeAttrs => {
29
+ let attrs = {
30
+ 'data-panel-type': nodeAttrs.panelType,
31
+ 'data-panel-icon': nodeAttrs.panelIcon,
32
+ 'data-panel-color': nodeAttrs.panelColor
33
+ };
34
+ return attrs;
35
+ };
36
+
37
+ const getParseDOMAttrs = (allowCustomPanel, dom) => {
38
+ let parseDOMAttrs = {
39
+ panelType: dom.getAttribute('data-panel-type')
40
+ };
41
+
42
+ if (allowCustomPanel) {
43
+ parseDOMAttrs = { ...parseDOMAttrs,
33
44
  panelIcon: dom.getAttribute('data-panel-icon'),
34
45
  panelColor: dom.getAttribute('data-panel-color')
35
- })
36
- }],
37
-
38
- toDOM(node) {
39
- const {
40
- panelType,
41
- panelIcon,
42
- panelColor
43
- } = node.attrs;
44
- const attrs = {
45
- 'data-panel-type': panelType,
46
- 'data-panel-icon': panelIcon,
47
- 'data-panel-color': panelColor
48
46
  };
49
- return ['div', attrs, ['div', {}, 0]];
47
+ } else {
48
+ parseDOMAttrs.panelType = parseDOMAttrs.panelType === PanelType.CUSTOM ? PanelType.INFO : parseDOMAttrs.panelType;
50
49
  }
51
50
 
51
+ return parseDOMAttrs;
52
+ };
53
+
54
+ export const customPanel = allowCustomPanel => {
55
+ const panelNodeSpec = {
56
+ group: 'block',
57
+ content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
58
+ marks: 'unsupportedMark unsupportedNodeAttribute',
59
+ attrs: getDefaultAttrs(),
60
+ parseDOM: [{
61
+ tag: 'div[data-panel-type]',
62
+ getAttrs: dom => getParseDOMAttrs(allowCustomPanel, dom)
63
+ }],
64
+
65
+ toDOM(node) {
66
+ const attrs = getDomAttrs(node.attrs);
67
+ return ['div', attrs, ['div', {}, 0]];
68
+ }
69
+
70
+ };
71
+ return panelNodeSpec;
52
72
  };
53
73
  export const panel = {
54
74
  group: 'block',
@@ -1,27 +1,103 @@
1
- /**
2
- * @name paragraph_node
3
- */
4
-
5
- /**
6
- * @name paragraph_with_no_marks_node
7
- */
8
-
9
- /**
10
- * NOTE: Need this because TS is too smart and inline everything.
11
- * So we need to give them separate identity.
12
- * Probably there's a way to solve it but that will need time and exploration.
13
- * // http://bit.ly/2raXFX5
14
- * type T1 = X | Y
15
- * type T2 = A | T1 | B // T2 = A | X | Y | B
16
- */
17
-
18
- /**
19
- * @name paragraph_with_alignment_node
20
- */
21
-
22
- /**
23
- * @name paragraph_with_indentation_node
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-pm-slice])', ':not([data-mark-type])'].join('');
25
101
  const pDOM = ['p', 0];
26
102
  export const paragraph = {
27
103
  selectable: false,
@@ -30,6 +106,68 @@ export const paragraph = {
30
106
  marks: 'strong code em link strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer',
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() {
@@ -1,4 +1,4 @@
1
1
  export { acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, getEmojiAcName } from './confluence/emoji';
2
2
  export { generateUuid, uuid } from './uuid';
3
3
  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, hexToRgb, hexToRgba, isHex, isRgb, normalizeHexColor, rgbToHex } from './colors';
4
- export { getLinkMatch, isSafeUrl, normalizeUrl } from './url';
4
+ export { getLinkMatch, isSafeUrl, normalizeUrl, linkify, linkifyMatch } from './url';
@@ -3,10 +3,57 @@ const whitelistedURLPatterns = [/^https?:\/\//im, /^ftps?:\/\//im, /^\//im, /^ma
3
3
  export const isSafeUrl = url => {
4
4
  return whitelistedURLPatterns.some(p => p.test(url.trim()) === true);
5
5
  };
6
- const linkify = LinkifyIt();
6
+ export const linkify = LinkifyIt();
7
7
  linkify.add('sourcetree:', 'http:');
8
+ const tlds = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
9
+ const tlds2Char = 'a[cdefgilmnoqrtuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrtuvwxyz]|n[acefgilopruz]|om|p[aefghkmnrtw]|qa|r[eosuw]|s[abcdegijklmnrtuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]';
10
+ tlds.push(tlds2Char);
11
+ linkify.tlds(tlds, false);
12
+ export const LINK_REGEXP = /(https?|ftp):\/\/[^\s]+/;
13
+ export const linkifyMatch = text => {
14
+ const matches = [];
15
+
16
+ if (!LINK_REGEXP.test(text)) {
17
+ return matches;
18
+ }
19
+
20
+ let startpos = 0;
21
+ let substr;
22
+
23
+ while (substr = text.substr(startpos)) {
24
+ const link = (substr.match(LINK_REGEXP) || [''])[0];
25
+
26
+ if (link) {
27
+ const index = substr.search(LINK_REGEXP);
28
+ const start = index >= 0 ? index + startpos : index;
29
+ const end = start + link.length;
30
+ matches.push({
31
+ index: start,
32
+ lastIndex: end,
33
+ raw: link,
34
+ url: link,
35
+ text: link,
36
+ schema: ''
37
+ });
38
+ startpos += end;
39
+ } else {
40
+ break;
41
+ }
42
+ }
43
+
44
+ return matches;
45
+ };
8
46
  export function getLinkMatch(str) {
9
- const match = str && linkify.match(str);
47
+ if (!str) {
48
+ return null;
49
+ }
50
+
51
+ let match = linkifyMatch(str);
52
+
53
+ if (!match.length) {
54
+ match = linkify.match(str);
55
+ }
56
+
10
57
  return match && match[0];
11
58
  }
12
59
  /**
@@ -15,5 +62,5 @@ export function getLinkMatch(str) {
15
62
 
16
63
  export function normalizeUrl(url) {
17
64
  const match = getLinkMatch(url);
18
- return match && match.url || url;
65
+ return match && match.url || '';
19
66
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/adf-schema",
3
- "version": "19.2.3",
3
+ "version": "19.3.2",
4
4
  "sideEffects": false
5
5
  }
package/dist/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
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, customPanel, 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
- 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, normalizeHexColor, normalizeUrl, rgbToHex, uuid } from './utils';
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';
@@ -335,4 +335,6 @@ function isContentSupported(nodes, contentKey) {
335
335
  }
336
336
 
337
337
  return false;
338
- }
338
+ }
339
+
340
+ export var allowCustomPanel = true;
@@ -1,14 +1,13 @@
1
1
  import { customPanel } from './nodes/panel';
2
2
  import { layoutSectionWithSingleColumn } from './nodes/layout-section';
3
- import { dataConsumer } from './marks/data-consumer';
4
- import { createSchema } from './create-schema';
3
+ import { allowCustomPanel, createSchema } from './create-schema';
5
4
  import { mediaSingleWithCaption } from './nodes';
6
5
 
7
6
  var getDefaultSchemaConfig = function getDefaultSchemaConfig() {
8
7
  var defaultSchemaConfig = {
9
8
  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'],
10
- 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
+ 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,
10
+ 'dataConsumer']
12
11
  };
13
12
  return defaultSchemaConfig;
14
13
  };
@@ -20,13 +19,11 @@ export var getSchemaBasedOnStage = function getSchemaBasedOnStage() {
20
19
 
21
20
  if (stage === 'stage0') {
22
21
  defaultSchemaConfig.customNodeSpecs = {
23
- panel: customPanel,
22
+ panel: customPanel(allowCustomPanel),
24
23
  mediaSingle: mediaSingleWithCaption,
25
24
  layoutSection: layoutSectionWithSingleColumn
26
25
  };
27
- defaultSchemaConfig.customMarkSpecs = {
28
- dataConsumer: dataConsumer
29
- };
26
+ defaultSchemaConfig.customMarkSpecs = {};
30
27
  defaultSchemaConfig.nodes.push('caption');
31
28
  defaultSchemaConfig.nodes.push('mediaInline');
32
29
  }
@@ -4,7 +4,6 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
4
4
 
5
5
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
6
6
 
7
- import { Fragment } from 'prosemirror-model';
8
7
  import { LINK, COLOR } from '../groups';
9
8
  import { isSafeUrl, normalizeUrl } from '../../utils/url';
10
9
 
@@ -26,32 +25,6 @@ var getLinkAttrs = function getLinkAttrs(attribute) {
26
25
  };
27
26
  };
28
27
 
29
- var getLinkAttrsWithCheck = function getLinkAttrsWithCheck(attribute) {
30
- return function (domNode) {
31
- var dom = domNode;
32
- var hasTextOnlyChildren = Array.from(dom.childNodes).every(function (node) {
33
- return node.nodeType === Node.TEXT_NODE || node.nodeName === 'SPAN';
34
- });
35
-
36
- if (hasTextOnlyChildren) {
37
- var href = dom.getAttribute(attribute) || '';
38
- var attrs = {
39
- __confluenceMetadata: dom.hasAttribute('__confluenceMetadata') ? JSON.parse(dom.getAttribute('__confluenceMetadata') || '') : undefined
40
- };
41
-
42
- if (isSafeUrl(href)) {
43
- attrs.href = normalizeUrl(href);
44
- } else {
45
- return false;
46
- }
47
-
48
- return attrs;
49
- }
50
-
51
- return false;
52
- };
53
- };
54
-
55
28
  export var link = {
56
29
  excludes: "".concat(LINK, " ").concat(COLOR),
57
30
  // ED-5844 No multiple links in media node
@@ -69,39 +42,14 @@ export var link = {
69
42
  contentElement: function contentElement(node) {
70
43
  var clone = node.cloneNode(true);
71
44
  clone.removeAttribute('data-block-link');
45
+ clone.setAttribute('data-skip-paste', 'true');
72
46
  var wrapper = document.createElement('div');
73
47
  wrapper.appendChild(clone);
74
48
  return wrapper;
75
49
  }
76
50
  }, {
77
51
  tag: 'a[href]',
78
- context: 'mediaSingle/|taskItem/|decisionItem/',
79
52
  getAttrs: getLinkAttrs('href')
80
- }, {
81
- tag: 'a[href]',
82
- getAttrs: getLinkAttrsWithCheck('href')
83
- }, {
84
- /**
85
- * When links aren't wrapped in a paragraph and due to
86
- * the odd nature of how our schema is set up, prosemirror will
87
- * add the link to the paragraph node itself where it should be on
88
- * the text node, this satisfies our schema because link is allowed
89
- * in many places (e.g. listitem)
90
- * This change comes through via prosemirror-model@1.9.1
91
- */
92
- tag: 'a[href]',
93
- getAttrs: getLinkAttrsWithCheck('href'),
94
- getContent: function getContent(node, schema) {
95
- if (node instanceof HTMLAnchorElement) {
96
- var href = node.getAttribute('href');
97
- var text = node.innerText;
98
- return Fragment.from(schema.nodes.paragraph.createChecked(undefined, schema.text(text, [schema.marks.link.create({
99
- href: href
100
- })])));
101
- }
102
-
103
- return Fragment.empty;
104
- }
105
53
  }],
106
54
  toDOM: function toDOM(node, isInline) {
107
55
  var attrs = Object.keys(node.attrs).reduce(function (attrs, key) {
@@ -28,6 +28,10 @@ export var emoji = {
28
28
  text: dom.getAttribute('data-emoji-text') || emoji.attrs.text.default
29
29
  };
30
30
  }
31
+ }, // Handle copy/paste beautiful panel from renderer />
32
+ {
33
+ tag: 'div.ak-editor-panel__icon',
34
+ ignore: true
31
35
  }, // Handle copy/paste from old <ac:emoticon />
32
36
  {
33
37
  tag: 'img[data-emoticon-name]',