@atlaskit/adf-schema 19.2.3 → 20.0.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/cjs/index.js +24 -6
  3. package/dist/cjs/schema/create-schema.js +10 -3
  4. package/dist/cjs/schema/default-schema.js +7 -13
  5. package/dist/cjs/schema/index.js +12 -6
  6. package/dist/cjs/schema/jira-schema.js +1 -1
  7. package/dist/cjs/schema/marks/fragment.js +77 -0
  8. package/dist/cjs/schema/marks/index.js +15 -1
  9. package/dist/cjs/schema/marks/link.js +1 -54
  10. package/dist/cjs/schema/marks/unsupported-mark.js +1 -0
  11. package/dist/cjs/schema/nodes/bodied-extension.js +1 -1
  12. package/dist/cjs/schema/nodes/caption.js +0 -1
  13. package/dist/cjs/schema/nodes/doc.js +1 -1
  14. package/dist/cjs/schema/nodes/emoji.js +4 -0
  15. package/dist/cjs/schema/nodes/expand.js +1 -1
  16. package/dist/cjs/schema/nodes/index.js +0 -6
  17. package/dist/cjs/schema/nodes/layout-column.js +1 -1
  18. package/dist/cjs/schema/nodes/media-single.js +1 -1
  19. package/dist/cjs/schema/nodes/panel.js +58 -53
  20. package/dist/cjs/schema/nodes/paragraph.js +168 -25
  21. package/dist/cjs/schema/nodes/tableNodes.js +3 -3
  22. package/dist/cjs/utils/index.js +12 -0
  23. package/dist/cjs/utils/url.js +62 -4
  24. package/dist/cjs/version.json +1 -1
  25. package/dist/es2019/index.js +2 -2
  26. package/dist/es2019/schema/create-schema.js +10 -5
  27. package/dist/es2019/schema/default-schema.js +6 -10
  28. package/dist/es2019/schema/index.js +2 -2
  29. package/dist/es2019/schema/jira-schema.js +1 -1
  30. package/dist/es2019/schema/marks/fragment.js +59 -0
  31. package/dist/es2019/schema/marks/index.js +2 -1
  32. package/dist/es2019/schema/marks/link.js +1 -49
  33. package/dist/es2019/schema/marks/unsupported-mark.js +1 -0
  34. package/dist/es2019/schema/nodes/bodied-extension.js +1 -1
  35. package/dist/es2019/schema/nodes/caption.js +0 -1
  36. package/dist/es2019/schema/nodes/doc.js +1 -1
  37. package/dist/es2019/schema/nodes/emoji.js +4 -0
  38. package/dist/es2019/schema/nodes/expand.js +1 -1
  39. package/dist/es2019/schema/nodes/index.js +1 -1
  40. package/dist/es2019/schema/nodes/layout-column.js +1 -1
  41. package/dist/es2019/schema/nodes/media-single.js +1 -1
  42. package/dist/es2019/schema/nodes/panel.js +42 -49
  43. package/dist/es2019/schema/nodes/paragraph.js +163 -25
  44. package/dist/es2019/schema/nodes/tableNodes.js +3 -3
  45. package/dist/es2019/utils/index.js +1 -1
  46. package/dist/es2019/utils/url.js +57 -4
  47. package/dist/es2019/version.json +1 -1
  48. package/dist/esm/index.js +2 -2
  49. package/dist/esm/schema/create-schema.js +10 -5
  50. package/dist/esm/schema/default-schema.js +6 -10
  51. package/dist/esm/schema/index.js +2 -2
  52. package/dist/esm/schema/jira-schema.js +1 -1
  53. package/dist/esm/schema/marks/fragment.js +64 -0
  54. package/dist/esm/schema/marks/index.js +2 -1
  55. package/dist/esm/schema/marks/link.js +1 -53
  56. package/dist/esm/schema/marks/unsupported-mark.js +1 -0
  57. package/dist/esm/schema/nodes/bodied-extension.js +1 -1
  58. package/dist/esm/schema/nodes/caption.js +0 -1
  59. package/dist/esm/schema/nodes/doc.js +1 -1
  60. package/dist/esm/schema/nodes/emoji.js +4 -0
  61. package/dist/esm/schema/nodes/expand.js +1 -1
  62. package/dist/esm/schema/nodes/index.js +1 -1
  63. package/dist/esm/schema/nodes/layout-column.js +1 -1
  64. package/dist/esm/schema/nodes/media-single.js +1 -1
  65. package/dist/esm/schema/nodes/panel.js +53 -51
  66. package/dist/esm/schema/nodes/paragraph.js +167 -25
  67. package/dist/esm/schema/nodes/tableNodes.js +3 -3
  68. package/dist/esm/utils/index.js +1 -1
  69. package/dist/esm/utils/url.js +57 -4
  70. package/dist/esm/version.json +1 -1
  71. package/dist/json-schema/v1/full.json +108 -73
  72. package/dist/json-schema/v1/stage-0.json +63 -26
  73. package/dist/types/index.d.ts +3 -3
  74. package/dist/types/schema/create-schema.d.ts +1 -0
  75. package/dist/types/schema/index.d.ts +3 -3
  76. package/dist/types/schema/marks/fragment.d.ts +30 -0
  77. package/dist/types/schema/marks/index.d.ts +2 -0
  78. package/dist/types/schema/marks/link.d.ts +3 -0
  79. package/dist/types/schema/nodes/block-card.d.ts +3 -0
  80. package/dist/types/schema/nodes/bodied-extension.d.ts +7 -5
  81. package/dist/types/schema/nodes/caption.d.ts +0 -1
  82. package/dist/types/schema/nodes/embed-card.d.ts +3 -0
  83. package/dist/types/schema/nodes/extension.d.ts +7 -5
  84. package/dist/types/schema/nodes/index.d.ts +1 -1
  85. package/dist/types/schema/nodes/inline-card.d.ts +0 -9
  86. package/dist/types/schema/nodes/inline-extension.d.ts +7 -5
  87. package/dist/types/schema/nodes/media-single.d.ts +0 -1
  88. package/dist/types/schema/nodes/panel.d.ts +1 -11
  89. package/dist/types/utils/index.d.ts +1 -1
  90. package/dist/types/utils/url.d.ts +7 -2
  91. package/json-schema/v1/full.json +108 -73
  92. package/json-schema/v1/stage-0.json +63 -26
  93. package/package.json +11 -8
  94. package/test-helpers/schema.ts +1 -0
@@ -5,38 +5,181 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.paragraph = void 0;
7
7
 
8
- /**
9
- * @name paragraph_node
10
- */
11
-
12
- /**
13
- * @name paragraph_with_no_marks_node
14
- */
15
-
16
- /**
17
- * NOTE: Need this because TS is too smart and inline everything.
18
- * So we need to give them separate identity.
19
- * Probably there's a way to solve it but that will need time and exploration.
20
- * // http://bit.ly/2raXFX5
21
- * type T1 = X | Y
22
- * type T2 = A | T1 | B // T2 = A | X | Y | B
23
- */
24
-
25
- /**
26
- * @name paragraph_with_alignment_node
27
- */
28
-
29
- /**
30
- * @name paragraph_with_indentation_node
31
- */
8
+ var _prosemirrorModel = require("prosemirror-model");
9
+
10
+ var _url = require("../../utils/url");
11
+
12
+ var getLinkContent = function getLinkContent(node, schema) {
13
+ if (!(node instanceof HTMLAnchorElement)) {
14
+ return _prosemirrorModel.Fragment.empty;
15
+ }
16
+
17
+ var href = node.getAttribute('href') || '';
18
+ var text = node.innerText;
19
+
20
+ if (!text || text.length === 0) {
21
+ return _prosemirrorModel.Fragment.empty;
22
+ }
23
+
24
+ var marks = (0, _url.isSafeUrl)(href) ? [schema.marks.link.create({
25
+ href: href
26
+ })] : [];
27
+ var textNode = schema.text(text, marks);
28
+ return _prosemirrorModel.Fragment.from(textNode);
29
+ };
30
+
31
+ var blockTags = {
32
+ address: true,
33
+ article: true,
34
+ aside: true,
35
+ blockquote: true,
36
+ canvas: true,
37
+ dd: true,
38
+ div: true,
39
+ dl: true,
40
+ fieldset: true,
41
+ figcaption: true,
42
+ figure: true,
43
+ footer: true,
44
+ form: true,
45
+ h1: true,
46
+ h2: true,
47
+ h3: true,
48
+ h4: true,
49
+ h5: true,
50
+ h6: true,
51
+ header: true,
52
+ hgroup: true,
53
+ hr: true,
54
+ li: true,
55
+ noscript: true,
56
+ ol: true,
57
+ output: true,
58
+ p: true,
59
+ pre: true,
60
+ section: true,
61
+ table: true,
62
+ tfoot: true,
63
+ ul: true
64
+ };
65
+
66
+ var isListItemNode = function isListItemNode(node) {
67
+ return Boolean(node && node.nodeName.toLowerCase() === 'li');
68
+ };
69
+
70
+ var isTextNode = function isTextNode(node) {
71
+ return Boolean(node && node.nodeType === Node.TEXT_NODE);
72
+ };
73
+
74
+ var isImageNode = function isImageNode(node) {
75
+ return Boolean(node && node.nodeName.toLowerCase() === 'img');
76
+ };
77
+
78
+ var hasInlineImage = function hasInlineImage(node) {
79
+ if (!node) {
80
+ return false;
81
+ }
82
+
83
+ return Array.from(node.childNodes).some(function (child) {
84
+ var isImage = isImageNode(child);
85
+
86
+ if (!isImage && child.childNodes) {
87
+ return Array.from(node.childNodes).some(function (node) {
88
+ return hasInlineImage(node);
89
+ });
90
+ }
91
+
92
+ return isImage;
93
+ });
94
+ };
95
+
96
+ var hasWhiteSpacePre = function hasWhiteSpacePre(node) {
97
+ return Boolean(node instanceof HTMLElement && node.style.whiteSpace === 'pre');
98
+ };
99
+
100
+ var hasFontFamilyMonospace = function hasFontFamilyMonospace(node) {
101
+ return Boolean(node instanceof HTMLElement && node.style.fontFamily.includes('monospace'));
102
+ };
103
+
104
+ var isBlockLevelNode = function isBlockLevelNode(node) {
105
+ return Boolean(node && blockTags.hasOwnProperty(node.nodeName.toLowerCase()));
106
+ };
107
+
108
+ var NOT_INTERNAL_LINKS = [':not([data-inline-card])', ':not([data-block-card])', ':not([data-block-link])', ':not([data-skip-paste])'].join('');
109
+ var ANCHOR_LINK = "a[href]".concat(NOT_INTERNAL_LINKS);
110
+ var 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('');
32
111
  var pDOM = ['p', 0];
33
112
  var paragraph = {
34
113
  selectable: false,
35
114
  content: 'inline*',
36
115
  group: 'block',
37
- marks: 'strong code em link strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer',
116
+ marks: 'strong code em link strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment',
38
117
  parseDOM: [{
39
118
  tag: 'p'
119
+ }, {
120
+ tag: "div".concat(NOT_INTERNAL_ELEMENTS, ", li:not([data-pm-slice])"),
121
+ priority: 100,
122
+ getAttrs: function getAttrs(node) {
123
+ if (!(node instanceof Node)) {
124
+ return false;
125
+ }
126
+
127
+ var isCodeBlock = hasWhiteSpacePre(node) || hasFontFamilyMonospace(node);
128
+
129
+ if (isCodeBlock || !node.hasChildNodes()) {
130
+ return false;
131
+ }
132
+
133
+ var hasInlineChildren = Array.from(node.childNodes).every(function (child) {
134
+ return !isBlockLevelNode(child) && // IMG is considered block for mediaSingle
135
+ !isImageNode(child);
136
+ });
137
+
138
+ if (!hasInlineChildren) {
139
+ return false;
140
+ }
141
+
142
+ if ( // We can skip this rule for pure list items
143
+ isListItemNode(node) && Array.from(node.childNodes).every(isTextNode)) {
144
+ return false;
145
+ }
146
+
147
+ return null;
148
+ }
149
+ }, {
150
+ tag: ":not(span) + ".concat(ANCHOR_LINK),
151
+ priority: 100,
152
+ getContent: getLinkContent
153
+ }, {
154
+ tag: ":not(span) > ".concat(ANCHOR_LINK, ":first-child"),
155
+ getAttrs: function getAttrs(node) {
156
+ if (!(node instanceof Node)) {
157
+ return false;
158
+ }
159
+
160
+ if (isBlockLevelNode(node.firstChild)) {
161
+ return null;
162
+ }
163
+
164
+ if (hasInlineImage(node)) {
165
+ return false;
166
+ }
167
+
168
+ var isNextSiblingValid = node.nextSibling === null || node.nextSibling instanceof Text && (node.nextSibling.textContent || '').trim().length === 0;
169
+
170
+ if (isNextSiblingValid) {
171
+ return null;
172
+ } // This rule should not match when there is any sibling after the anchor
173
+
174
+
175
+ if (!isBlockLevelNode(node.nextSibling)) {
176
+ return false;
177
+ }
178
+
179
+ return null;
180
+ },
181
+ priority: 100,
182
+ getContent: getLinkContent
40
183
  }],
41
184
  toDOM: function toDOM() {
42
185
  return pDOM;
@@ -135,7 +135,7 @@ var createTableSpec = function createTableSpec() {
135
135
  var tableNodeSpec = {
136
136
  content: 'tableRow+',
137
137
  attrs: attrs,
138
- marks: 'unsupportedMark unsupportedNodeAttribute',
138
+ marks: 'fragment unsupportedMark unsupportedNodeAttribute',
139
139
  tableRole: 'table',
140
140
  isolating: true,
141
141
  selectable: false,
@@ -221,7 +221,7 @@ var tableCell = {
221
221
  content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaSingle | mediaGroup | decisionList | taskList | blockCard | embedCard | extension | nestedExpand | unsupportedBlock)+',
222
222
  attrs: cellAttrs,
223
223
  tableRole: 'cell',
224
- marks: 'link alignment dataConsumer unsupportedMark unsupportedNodeAttribute',
224
+ marks: 'link alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
225
225
  isolating: true,
226
226
  parseDOM: [// Ignore number cell copied from renderer
227
227
  {
@@ -258,7 +258,7 @@ var tableHeader = {
258
258
  attrs: cellAttrs,
259
259
  tableRole: 'header_cell',
260
260
  isolating: true,
261
- marks: 'link alignment dataConsumer unsupportedMark unsupportedNodeAttribute',
261
+ marks: 'link alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
262
262
  parseDOM: [{
263
263
  tag: 'th',
264
264
  getAttrs: function getAttrs(dom) {
@@ -363,6 +363,18 @@ Object.defineProperty(exports, "normalizeUrl", {
363
363
  return _url.normalizeUrl;
364
364
  }
365
365
  });
366
+ Object.defineProperty(exports, "linkify", {
367
+ enumerable: true,
368
+ get: function get() {
369
+ return _url.linkify;
370
+ }
371
+ });
372
+ Object.defineProperty(exports, "linkifyMatch", {
373
+ enumerable: true,
374
+ get: function get() {
375
+ return _url.linkifyMatch;
376
+ }
377
+ });
366
378
 
367
379
  var _emoji = require("./confluence/emoji");
368
380
 
@@ -7,24 +7,82 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.getLinkMatch = getLinkMatch;
9
9
  exports.normalizeUrl = normalizeUrl;
10
- exports.isSafeUrl = void 0;
10
+ exports.linkifyMatch = exports.LINK_REGEXP = exports.linkify = exports.isSafeUrl = void 0;
11
11
 
12
12
  var _linkifyIt = _interopRequireDefault(require("linkify-it"));
13
13
 
14
14
  var 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];
15
15
 
16
16
  var isSafeUrl = function isSafeUrl(url) {
17
+ var urlTrimmed = url.trim();
18
+
19
+ if (urlTrimmed.length === 0) {
20
+ return true;
21
+ }
22
+
17
23
  return whitelistedURLPatterns.some(function (p) {
18
- return p.test(url.trim()) === true;
24
+ return p.test(urlTrimmed);
19
25
  });
20
26
  };
21
27
 
22
28
  exports.isSafeUrl = isSafeUrl;
23
29
  var linkify = (0, _linkifyIt.default)();
30
+ exports.linkify = linkify;
24
31
  linkify.add('sourcetree:', 'http:');
32
+ var tlds = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
33
+ var 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]';
34
+ tlds.push(tlds2Char);
35
+ linkify.tlds(tlds, false);
36
+ var LINK_REGEXP = /(https?|ftp):\/\/[^\s]+/;
37
+ exports.LINK_REGEXP = LINK_REGEXP;
38
+
39
+ var linkifyMatch = function linkifyMatch(text) {
40
+ var matches = [];
41
+
42
+ if (!LINK_REGEXP.test(text)) {
43
+ return matches;
44
+ }
45
+
46
+ var startpos = 0;
47
+ var substr;
48
+
49
+ while (substr = text.substr(startpos)) {
50
+ var link = (substr.match(LINK_REGEXP) || [''])[0];
51
+
52
+ if (link) {
53
+ var index = substr.search(LINK_REGEXP);
54
+ var start = index >= 0 ? index + startpos : index;
55
+ var end = start + link.length;
56
+ matches.push({
57
+ index: start,
58
+ lastIndex: end,
59
+ raw: link,
60
+ url: link,
61
+ text: link,
62
+ schema: ''
63
+ });
64
+ startpos += end;
65
+ } else {
66
+ break;
67
+ }
68
+ }
69
+
70
+ return matches;
71
+ };
72
+
73
+ exports.linkifyMatch = linkifyMatch;
25
74
 
26
75
  function getLinkMatch(str) {
27
- var match = str && linkify.match(str);
76
+ if (!str) {
77
+ return null;
78
+ }
79
+
80
+ var match = linkifyMatch(str);
81
+
82
+ if (!match.length) {
83
+ match = linkify.match(str);
84
+ }
85
+
28
86
  return match && match[0];
29
87
  }
30
88
  /**
@@ -34,5 +92,5 @@ function getLinkMatch(str) {
34
92
 
35
93
  function normalizeUrl(url) {
36
94
  var match = getLinkMatch(url);
37
- return match && match.url || url;
95
+ return match && match.url || '';
38
96
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/adf-schema",
3
- "version": "19.2.3",
3
+ "version": "20.0.0",
4
4
  "sideEffects": false
5
5
  }
@@ -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, 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';
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
+ 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';
@@ -1,7 +1,7 @@
1
1
  import { Schema } from 'prosemirror-model';
2
2
  import { COLOR, FONT_STYLE, SEARCH_QUERY, LINK } from './groups';
3
- import { link, em, strong, textColor, strike, subsup, underline, code, typeAheadQuery, confluenceInlineComment, breakout, alignment, indentation, annotation, unsupportedMark, unsupportedNodeAttribute, dataConsumer } from './marks';
4
- import { confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, doc, paragraph, text, bulletList, orderedList, listItem, heading, blockquote, codeBlock, panel, rule, image, mention, media, mediaInline, mediaGroup, mediaSingle, hardBreak, emoji, table, tableCell, tableHeader, tableRow, decisionList, decisionItem, taskList, taskItem, unknownBlock, extension, inlineExtension, bodiedExtension, date, placeholder, layoutSection, layoutColumn, inlineCard, blockCard, unsupportedBlock, unsupportedInline, status, expand, nestedExpand, embedCard, caption } from './nodes';
3
+ import { link, em, strong, textColor, strike, subsup, underline, code, typeAheadQuery, confluenceInlineComment, breakout, alignment, indentation, annotation, unsupportedMark, unsupportedNodeAttribute, dataConsumer, fragment } from './marks';
4
+ import { confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, doc, paragraph, text, bulletList, orderedList, listItem, heading, blockquote, codeBlock, panel, rule, image, mention, media, mediaInline, mediaGroup, mediaSingleWithCaption, hardBreak, emoji, table, tableCell, tableHeader, tableRow, decisionList, decisionItem, taskList, taskItem, unknownBlock, extension, inlineExtension, bodiedExtension, date, placeholder, layoutSection, layoutColumn, inlineCard, blockCard, unsupportedBlock, unsupportedInline, status, expand, nestedExpand, embedCard, caption } from './nodes';
5
5
 
6
6
  function addItems(builtInItems, config, customSpecs = {}) {
7
7
  if (!config) {
@@ -83,7 +83,7 @@ const nodesInOrder = [{
83
83
  spec: codeBlock
84
84
  }, {
85
85
  name: 'panel',
86
- spec: panel
86
+ spec: panel(true)
87
87
  }, {
88
88
  name: 'rule',
89
89
  spec: rule
@@ -104,7 +104,7 @@ const nodesInOrder = [{
104
104
  spec: mediaGroup
105
105
  }, {
106
106
  name: 'mediaSingle',
107
- spec: mediaSingle
107
+ spec: mediaSingleWithCaption
108
108
  }, {
109
109
  name: 'mediaInline',
110
110
  spec: mediaInline
@@ -238,6 +238,9 @@ const marksInOrder = [{
238
238
  }, {
239
239
  name: 'dataConsumer',
240
240
  spec: dataConsumer
241
+ }, {
242
+ name: 'fragment',
243
+ spec: fragment
241
244
  }, {
242
245
  name: 'indentation',
243
246
  spec: indentation
@@ -322,4 +325,6 @@ function isContentSupported(nodes, contentKey) {
322
325
  }
323
326
 
324
327
  return false;
325
- }
328
+ }
329
+
330
+ export const allowCustomPanel = true;
@@ -1,12 +1,10 @@
1
- import { customPanel } from './nodes/panel';
2
- import { layoutSectionWithSingleColumn } from './nodes/layout-section';
3
- import { dataConsumer } from './marks/data-consumer';
1
+ import { layoutSectionWithSingleColumn } from './nodes';
2
+ import { dataConsumer, fragment } from './marks';
4
3
  import { createSchema } from './create-schema';
5
- import { mediaSingleWithCaption } from './nodes';
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(); // TODO: ED-10445 remove stage0 check after panels with emoji are on full schema AND image captions are on full schema
16
+ const defaultSchemaConfig = getDefaultSchemaConfig();
19
17
 
20
18
  if (stage === 'stage0') {
21
19
  defaultSchemaConfig.customNodeSpecs = {
22
- panel: customPanel,
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, customPanel, 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, 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';
@@ -37,7 +37,7 @@ export default function makeSchema(config) {
37
37
  }
38
38
 
39
39
  if (config.allowMedia) {
40
- nodes.push('mediaGroup', 'mediaSingle', 'media');
40
+ nodes.push('mediaGroup', 'mediaSingle', 'media', 'caption');
41
41
  }
42
42
 
43
43
  if (config.allowTextColor) {
@@ -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,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) {
@@ -3,6 +3,7 @@ export const unsupportedMark = {
3
3
  return ['span'];
4
4
  },
5
5
 
6
+ excludes: '',
6
7
  attrs: {
7
8
  originalValue: {}
8
9
  }
@@ -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,
@@ -1,5 +1,4 @@
1
1
  /**
2
- * @stage 0
3
2
  * @name caption_node
4
3
  */
5
4
  export const caption = {
@@ -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
  };
@@ -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]',