@atlaskit/adf-schema 19.2.0 → 19.3.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 (38) hide show
  1. package/CHANGELOG.md +26 -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 +1 -1
  5. package/dist/cjs/schema/marks/link.js +31 -2
  6. package/dist/cjs/schema/nodes/emoji.js +4 -0
  7. package/dist/cjs/schema/nodes/layout-section.js +2 -2
  8. package/dist/cjs/schema/nodes/panel.js +59 -28
  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 +2 -2
  15. package/dist/es2019/schema/marks/link.js +27 -2
  16. package/dist/es2019/schema/nodes/emoji.js +4 -0
  17. package/dist/es2019/schema/nodes/layout-section.js +2 -2
  18. package/dist/es2019/schema/nodes/panel.js +45 -25
  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 +2 -2
  25. package/dist/esm/schema/marks/link.js +31 -2
  26. package/dist/esm/schema/nodes/emoji.js +4 -0
  27. package/dist/esm/schema/nodes/layout-section.js +2 -2
  28. package/dist/esm/schema/nodes/panel.js +55 -28
  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/nodes/layout-section.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 +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @atlaskit/adf-schema
2
2
 
3
+ ## 19.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`93da0afefce`](https://bitbucket.org/atlassian/atlassian-frontend/commits/93da0afefce) - CETI-78 Change panel nodeSpec to handle paste when feature flag is off
8
+ - [`971845eac0d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/971845eac0d) - CETI-96 Added new rule to emoji to solve the duplicate icon issue when we copy from renderer
9
+ - [`e856b56fd31`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e856b56fd31) - ED-13669 reuse same links normalization method in plugin and adf schema
10
+
11
+ ## 19.2.3
12
+
13
+ ### Patch Changes
14
+
15
+ - [`a80f50a843c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/a80f50a843c) - [HOT-97158] Fix paste link heading issue
16
+
17
+ ## 19.2.2
18
+
19
+ ### Patch Changes
20
+
21
+ - [`b85e7ce12cd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b85e7ce12cd) - Internal upgrade of memoize-one to 6.0.0
22
+
23
+ ## 19.2.1
24
+
25
+ ### Patch Changes
26
+
27
+ - [`a55dbcb3ecd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/a55dbcb3ecd) - [ED-13882] Fix layout section ProseMirror Schema content
28
+
3
29
  ## 19.2.0
4
30
 
5
31
  ### Minor Changes
package/dist/cjs/index.js CHANGED
@@ -1059,6 +1059,18 @@ Object.defineProperty(exports, "isSafeUrl", {
1059
1059
  return _utils.isSafeUrl;
1060
1060
  }
1061
1061
  });
1062
+ Object.defineProperty(exports, "linkify", {
1063
+ enumerable: true,
1064
+ get: function get() {
1065
+ return _utils.linkify;
1066
+ }
1067
+ });
1068
+ Object.defineProperty(exports, "linkifyMatch", {
1069
+ enumerable: true,
1070
+ get: function get() {
1071
+ return _utils.linkifyMatch;
1072
+ }
1073
+ });
1062
1074
  Object.defineProperty(exports, "normalizeHexColor", {
1063
1075
  enumerable: true,
1064
1076
  get: function get() {
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.createSchema = createSchema;
9
9
  exports.sanitizeNodes = sanitizeNodes;
10
10
  exports.sanitizeNodeSpecContent = sanitizeNodeSpecContent;
11
+ exports.allowCustomPanel = void 0;
11
12
 
12
13
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
14
 
@@ -351,4 +352,7 @@ function isContentSupported(nodes, contentKey) {
351
352
  }
352
353
 
353
354
  return false;
354
- }
355
+ }
356
+
357
+ var allowCustomPanel = true;
358
+ exports.allowCustomPanel = allowCustomPanel;
@@ -33,7 +33,7 @@ var getSchemaBasedOnStage = function getSchemaBasedOnStage() {
33
33
 
34
34
  if (stage === 'stage0') {
35
35
  defaultSchemaConfig.customNodeSpecs = {
36
- panel: _panel.customPanel,
36
+ panel: (0, _panel.customPanel)(_createSchema.allowCustomPanel),
37
37
  mediaSingle: _nodes.mediaSingleWithCaption,
38
38
  layoutSection: _layoutSection.layoutSectionWithSingleColumn
39
39
  };
@@ -37,6 +37,32 @@ var getLinkAttrs = function getLinkAttrs(attribute) {
37
37
  };
38
38
  };
39
39
 
40
+ var getLinkAttrsWithCheck = function getLinkAttrsWithCheck(attribute) {
41
+ return function (domNode) {
42
+ var dom = domNode;
43
+ var hasTextOnlyChildren = Array.from(dom.childNodes).every(function (node) {
44
+ return node.nodeType === Node.TEXT_NODE || node.nodeName === 'SPAN';
45
+ });
46
+
47
+ if (hasTextOnlyChildren) {
48
+ var href = dom.getAttribute(attribute) || '';
49
+ var attrs = {
50
+ __confluenceMetadata: dom.hasAttribute('__confluenceMetadata') ? JSON.parse(dom.getAttribute('__confluenceMetadata') || '') : undefined
51
+ };
52
+
53
+ if ((0, _url.isSafeUrl)(href)) {
54
+ attrs.href = (0, _url.normalizeUrl)(href);
55
+ } else {
56
+ return false;
57
+ }
58
+
59
+ return attrs;
60
+ }
61
+
62
+ return false;
63
+ };
64
+ };
65
+
40
66
  var link = {
41
67
  excludes: "".concat(_groups.LINK, " ").concat(_groups.COLOR),
42
68
  // ED-5844 No multiple links in media node
@@ -60,8 +86,11 @@ var link = {
60
86
  }
61
87
  }, {
62
88
  tag: 'a[href]',
63
- context: 'paragraph/|heading/|mediaSingle/|taskItem/|decisionItem/',
89
+ context: 'mediaSingle/|taskItem/|decisionItem/',
64
90
  getAttrs: getLinkAttrs('href')
91
+ }, {
92
+ tag: 'a[href]',
93
+ getAttrs: getLinkAttrsWithCheck('href')
65
94
  }, {
66
95
  /**
67
96
  * When links aren't wrapped in a paragraph and due to
@@ -72,7 +101,7 @@ var link = {
72
101
  * This change comes through via prosemirror-model@1.9.1
73
102
  */
74
103
  tag: 'a[href]',
75
- getAttrs: getLinkAttrs('href'),
104
+ getAttrs: getLinkAttrsWithCheck('href'),
76
105
  getContent: function getContent(node, schema) {
77
106
  if (node instanceof HTMLAnchorElement) {
78
107
  var href = node.getAttribute('href');
@@ -32,6 +32,10 @@ var emoji = {
32
32
  text: dom.getAttribute('data-emoji-text') || emoji.attrs.text.default
33
33
  };
34
34
  }
35
+ }, // Handle copy/paste beautiful panel from renderer />
36
+ {
37
+ tag: 'div.ak-editor-panel__icon',
38
+ ignore: true
35
39
  }, // Handle copy/paste from old <ac:emoticon />
36
40
  {
37
41
  tag: 'img[data-emoticon-name]',
@@ -22,7 +22,7 @@ exports.layoutSectionWithSingleColumn = exports.layoutSection = void 0;
22
22
  * @name layoutSection_with_single_column_node
23
23
  */
24
24
  var layoutSection = {
25
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
25
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
26
26
  marks: 'unsupportedMark unsupportedNodeAttribute',
27
27
  isolating: true,
28
28
  parseDOM: [{
@@ -41,7 +41,7 @@ var layoutSection = {
41
41
  };
42
42
  exports.layoutSection = layoutSection;
43
43
  var layoutSectionWithSingleColumn = {
44
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
44
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
45
45
  marks: 'unsupportedMark unsupportedNodeAttribute',
46
46
  isolating: true,
47
47
  parseDOM: [{
@@ -1,9 +1,18 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
8
  exports.panel = exports.customPanel = exports.PanelType = void 0;
9
+
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
12
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
13
+
14
+ 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) { (0, _defineProperty2.default)(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; }
15
+
7
16
  var PanelType;
8
17
  exports.PanelType = PanelType;
9
18
 
@@ -17,12 +26,8 @@ exports.PanelType = PanelType;
17
26
  PanelType["CUSTOM"] = "custom";
18
27
  })(PanelType || (exports.PanelType = PanelType = {}));
19
28
 
20
- //TODO: ED-10445 rename to panel and merge with the other panel node spec, after emoji panels moved to full schema
21
- var customPanel = {
22
- group: 'block',
23
- content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
24
- marks: 'unsupportedMark unsupportedNodeAttribute',
25
- attrs: {
29
+ var getDefaultAttrs = function getDefaultAttrs() {
30
+ var attrs = {
26
31
  panelType: {
27
32
  default: 'info'
28
33
  },
@@ -32,30 +37,56 @@ var customPanel = {
32
37
  panelColor: {
33
38
  default: null
34
39
  }
35
- },
36
- parseDOM: [{
37
- tag: 'div[data-panel-type]',
38
- getAttrs: function getAttrs(dom) {
39
- return {
40
- panelType: dom.getAttribute('data-panel-type'),
41
- panelIcon: dom.getAttribute('data-panel-icon'),
42
- panelColor: dom.getAttribute('data-panel-color')
43
- };
44
- }
45
- }],
46
- toDOM: function toDOM(node) {
47
- var _node$attrs = node.attrs,
48
- panelType = _node$attrs.panelType,
49
- panelIcon = _node$attrs.panelIcon,
50
- panelColor = _node$attrs.panelColor;
51
- var attrs = {
52
- 'data-panel-type': panelType,
53
- 'data-panel-icon': panelIcon,
54
- 'data-panel-color': panelColor
55
- };
56
- return ['div', attrs, ['div', {}, 0]];
40
+ };
41
+ return attrs;
42
+ };
43
+
44
+ var getDomAttrs = function getDomAttrs(nodeAttrs) {
45
+ var attrs = {
46
+ 'data-panel-type': nodeAttrs.panelType,
47
+ 'data-panel-icon': nodeAttrs.panelIcon,
48
+ 'data-panel-color': nodeAttrs.panelColor
49
+ };
50
+ return attrs;
51
+ };
52
+
53
+ var getParseDOMAttrs = function getParseDOMAttrs(allowCustomPanel, dom) {
54
+ var parseDOMAttrs = {
55
+ panelType: dom.getAttribute('data-panel-type')
56
+ };
57
+
58
+ if (allowCustomPanel) {
59
+ parseDOMAttrs = _objectSpread(_objectSpread({}, parseDOMAttrs), {}, {
60
+ panelIcon: dom.getAttribute('data-panel-icon'),
61
+ panelColor: dom.getAttribute('data-panel-color')
62
+ });
63
+ } else {
64
+ parseDOMAttrs.panelType = parseDOMAttrs.panelType === PanelType.CUSTOM ? PanelType.INFO : parseDOMAttrs.panelType;
57
65
  }
66
+
67
+ return parseDOMAttrs;
58
68
  };
69
+
70
+ var customPanel = function customPanel(allowCustomPanel) {
71
+ var panelNodeSpec = {
72
+ group: 'block',
73
+ content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
74
+ marks: 'unsupportedMark unsupportedNodeAttribute',
75
+ attrs: getDefaultAttrs(),
76
+ parseDOM: [{
77
+ tag: 'div[data-panel-type]',
78
+ getAttrs: function getAttrs(dom) {
79
+ return getParseDOMAttrs(allowCustomPanel, dom);
80
+ }
81
+ }],
82
+ toDOM: function toDOM(node) {
83
+ var attrs = getDomAttrs(node.attrs);
84
+ return ['div', attrs, ['div', {}, 0]];
85
+ }
86
+ };
87
+ return panelNodeSpec;
88
+ };
89
+
59
90
  exports.customPanel = customPanel;
60
91
  var panel = {
61
92
  group: 'block',
@@ -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,7 +7,7 @@ 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
 
@@ -21,10 +21,62 @@ var isSafeUrl = function isSafeUrl(url) {
21
21
 
22
22
  exports.isSafeUrl = isSafeUrl;
23
23
  var linkify = (0, _linkifyIt.default)();
24
+ exports.linkify = linkify;
24
25
  linkify.add('sourcetree:', 'http:');
26
+ var tlds = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
27
+ 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]';
28
+ tlds.push(tlds2Char);
29
+ linkify.tlds(tlds, false);
30
+ var LINK_REGEXP = /(https?|ftp):\/\/[^\s]+/;
31
+ exports.LINK_REGEXP = LINK_REGEXP;
32
+
33
+ var linkifyMatch = function linkifyMatch(text) {
34
+ var matches = [];
35
+
36
+ if (!LINK_REGEXP.test(text)) {
37
+ return matches;
38
+ }
39
+
40
+ var startpos = 0;
41
+ var substr;
42
+
43
+ while (substr = text.substr(startpos)) {
44
+ var link = (substr.match(LINK_REGEXP) || [''])[0];
45
+
46
+ if (link) {
47
+ var index = substr.search(LINK_REGEXP);
48
+ var start = index >= 0 ? index + startpos : index;
49
+ var end = start + link.length;
50
+ matches.push({
51
+ index: start,
52
+ lastIndex: end,
53
+ raw: link,
54
+ url: link,
55
+ text: link,
56
+ schema: ''
57
+ });
58
+ startpos += end;
59
+ } else {
60
+ break;
61
+ }
62
+ }
63
+
64
+ return matches;
65
+ };
66
+
67
+ exports.linkifyMatch = linkifyMatch;
25
68
 
26
69
  function getLinkMatch(str) {
27
- var match = str && linkify.match(str);
70
+ if (!str) {
71
+ return null;
72
+ }
73
+
74
+ var match = linkifyMatch(str);
75
+
76
+ if (!match.length) {
77
+ match = linkify.match(str);
78
+ }
79
+
28
80
  return match && match[0];
29
81
  }
30
82
  /**
@@ -34,5 +86,5 @@ function getLinkMatch(str) {
34
86
 
35
87
  function normalizeUrl(url) {
36
88
  var match = getLinkMatch(url);
37
- return match && match.url || url;
89
+ return match && match.url || '';
38
90
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/adf-schema",
3
- "version": "19.2.0",
3
+ "version": "19.3.0",
4
4
  "sideEffects": false
5
5
  }
@@ -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';
@@ -322,4 +322,6 @@ function isContentSupported(nodes, contentKey) {
322
322
  }
323
323
 
324
324
  return false;
325
- }
325
+ }
326
+
327
+ export const allowCustomPanel = true;
@@ -1,7 +1,7 @@
1
1
  import { customPanel } from './nodes/panel';
2
2
  import { layoutSectionWithSingleColumn } from './nodes/layout-section';
3
3
  import { dataConsumer } from './marks/data-consumer';
4
- import { createSchema } from './create-schema';
4
+ import { allowCustomPanel, createSchema } from './create-schema';
5
5
  import { mediaSingleWithCaption } from './nodes';
6
6
 
7
7
  const getDefaultSchemaConfig = () => {
@@ -19,7 +19,7 @@ export const getSchemaBasedOnStage = (stage = 'final') => {
19
19
 
20
20
  if (stage === 'stage0') {
21
21
  defaultSchemaConfig.customNodeSpecs = {
22
- panel: customPanel,
22
+ panel: customPanel(allowCustomPanel),
23
23
  mediaSingle: mediaSingleWithCaption,
24
24
  layoutSection: layoutSectionWithSingleColumn
25
25
  };
@@ -18,6 +18,28 @@ const getLinkAttrs = attribute => domNode => {
18
18
  return attrs;
19
19
  };
20
20
 
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
+
21
43
  export const link = {
22
44
  excludes: `${LINK} ${COLOR}`,
23
45
  // ED-5844 No multiple links in media node
@@ -41,8 +63,11 @@ export const link = {
41
63
  }
42
64
  }, {
43
65
  tag: 'a[href]',
44
- context: 'paragraph/|heading/|mediaSingle/|taskItem/|decisionItem/',
66
+ context: 'mediaSingle/|taskItem/|decisionItem/',
45
67
  getAttrs: getLinkAttrs('href')
68
+ }, {
69
+ tag: 'a[href]',
70
+ getAttrs: getLinkAttrsWithCheck('href')
46
71
  }, {
47
72
  /**
48
73
  * When links aren't wrapped in a paragraph and due to
@@ -53,7 +78,7 @@ export const link = {
53
78
  * This change comes through via prosemirror-model@1.9.1
54
79
  */
55
80
  tag: 'a[href]',
56
- getAttrs: getLinkAttrs('href'),
81
+ getAttrs: getLinkAttrsWithCheck('href'),
57
82
  getContent: (node, schema) => {
58
83
  if (node instanceof HTMLAnchorElement) {
59
84
  const href = node.getAttribute('href');
@@ -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]',
@@ -15,7 +15,7 @@
15
15
  * @name layoutSection_with_single_column_node
16
16
  */
17
17
  export const layoutSection = {
18
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
18
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
19
19
  marks: 'unsupportedMark unsupportedNodeAttribute',
20
20
  isolating: true,
21
21
  parseDOM: [{
@@ -35,7 +35,7 @@ export const layoutSection = {
35
35
 
36
36
  };
37
37
  export const layoutSectionWithSingleColumn = {
38
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
38
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
39
39
  marks: 'unsupportedMark unsupportedNodeAttribute',
40
40
  isolating: true,
41
41
  parseDOM: [{
@@ -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,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.0",
3
+ "version": "19.3.0",
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,7 +1,7 @@
1
1
  import { customPanel } from './nodes/panel';
2
2
  import { layoutSectionWithSingleColumn } from './nodes/layout-section';
3
3
  import { dataConsumer } from './marks/data-consumer';
4
- import { createSchema } from './create-schema';
4
+ import { allowCustomPanel, createSchema } from './create-schema';
5
5
  import { mediaSingleWithCaption } from './nodes';
6
6
 
7
7
  var getDefaultSchemaConfig = function getDefaultSchemaConfig() {
@@ -20,7 +20,7 @@ export var getSchemaBasedOnStage = function getSchemaBasedOnStage() {
20
20
 
21
21
  if (stage === 'stage0') {
22
22
  defaultSchemaConfig.customNodeSpecs = {
23
- panel: customPanel,
23
+ panel: customPanel(allowCustomPanel),
24
24
  mediaSingle: mediaSingleWithCaption,
25
25
  layoutSection: layoutSectionWithSingleColumn
26
26
  };
@@ -26,6 +26,32 @@ var getLinkAttrs = function getLinkAttrs(attribute) {
26
26
  };
27
27
  };
28
28
 
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
+
29
55
  export var link = {
30
56
  excludes: "".concat(LINK, " ").concat(COLOR),
31
57
  // ED-5844 No multiple links in media node
@@ -49,8 +75,11 @@ export var link = {
49
75
  }
50
76
  }, {
51
77
  tag: 'a[href]',
52
- context: 'paragraph/|heading/|mediaSingle/|taskItem/|decisionItem/',
78
+ context: 'mediaSingle/|taskItem/|decisionItem/',
53
79
  getAttrs: getLinkAttrs('href')
80
+ }, {
81
+ tag: 'a[href]',
82
+ getAttrs: getLinkAttrsWithCheck('href')
54
83
  }, {
55
84
  /**
56
85
  * When links aren't wrapped in a paragraph and due to
@@ -61,7 +90,7 @@ export var link = {
61
90
  * This change comes through via prosemirror-model@1.9.1
62
91
  */
63
92
  tag: 'a[href]',
64
- getAttrs: getLinkAttrs('href'),
93
+ getAttrs: getLinkAttrsWithCheck('href'),
65
94
  getContent: function getContent(node, schema) {
66
95
  if (node instanceof HTMLAnchorElement) {
67
96
  var href = node.getAttribute('href');
@@ -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]',
@@ -15,7 +15,7 @@
15
15
  * @name layoutSection_with_single_column_node
16
16
  */
17
17
  export var layoutSection = {
18
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
18
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
19
19
  marks: 'unsupportedMark unsupportedNodeAttribute',
20
20
  isolating: true,
21
21
  parseDOM: [{
@@ -33,7 +33,7 @@ export var layoutSection = {
33
33
  }
34
34
  };
35
35
  export var layoutSectionWithSingleColumn = {
36
- content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock*',
36
+ content: '(layoutColumn | unsupportedBlock){1,3} unsupportedBlock* | unsupportedBlock+',
37
37
  marks: 'unsupportedMark unsupportedNodeAttribute',
38
38
  isolating: true,
39
39
  parseDOM: [{
@@ -1,3 +1,9 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
4
+
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
+
1
7
  export var PanelType;
2
8
 
3
9
  (function (PanelType) {
@@ -10,12 +16,8 @@ export var PanelType;
10
16
  PanelType["CUSTOM"] = "custom";
11
17
  })(PanelType || (PanelType = {}));
12
18
 
13
- //TODO: ED-10445 rename to panel and merge with the other panel node spec, after emoji panels moved to full schema
14
- export var customPanel = {
15
- group: 'block',
16
- content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
17
- marks: 'unsupportedMark unsupportedNodeAttribute',
18
- attrs: {
19
+ var getDefaultAttrs = function getDefaultAttrs() {
20
+ var attrs = {
19
21
  panelType: {
20
22
  default: 'info'
21
23
  },
@@ -25,29 +27,54 @@ export var customPanel = {
25
27
  panelColor: {
26
28
  default: null
27
29
  }
28
- },
29
- parseDOM: [{
30
- tag: 'div[data-panel-type]',
31
- getAttrs: function getAttrs(dom) {
32
- return {
33
- panelType: dom.getAttribute('data-panel-type'),
34
- panelIcon: dom.getAttribute('data-panel-icon'),
35
- panelColor: dom.getAttribute('data-panel-color')
36
- };
37
- }
38
- }],
39
- toDOM: function toDOM(node) {
40
- var _node$attrs = node.attrs,
41
- panelType = _node$attrs.panelType,
42
- panelIcon = _node$attrs.panelIcon,
43
- panelColor = _node$attrs.panelColor;
44
- var attrs = {
45
- 'data-panel-type': panelType,
46
- 'data-panel-icon': panelIcon,
47
- 'data-panel-color': panelColor
48
- };
49
- return ['div', attrs, ['div', {}, 0]];
30
+ };
31
+ return attrs;
32
+ };
33
+
34
+ var getDomAttrs = function getDomAttrs(nodeAttrs) {
35
+ var attrs = {
36
+ 'data-panel-type': nodeAttrs.panelType,
37
+ 'data-panel-icon': nodeAttrs.panelIcon,
38
+ 'data-panel-color': nodeAttrs.panelColor
39
+ };
40
+ return attrs;
41
+ };
42
+
43
+ var getParseDOMAttrs = function getParseDOMAttrs(allowCustomPanel, dom) {
44
+ var parseDOMAttrs = {
45
+ panelType: dom.getAttribute('data-panel-type')
46
+ };
47
+
48
+ if (allowCustomPanel) {
49
+ parseDOMAttrs = _objectSpread(_objectSpread({}, parseDOMAttrs), {}, {
50
+ panelIcon: dom.getAttribute('data-panel-icon'),
51
+ panelColor: dom.getAttribute('data-panel-color')
52
+ });
53
+ } else {
54
+ parseDOMAttrs.panelType = parseDOMAttrs.panelType === PanelType.CUSTOM ? PanelType.INFO : parseDOMAttrs.panelType;
50
55
  }
56
+
57
+ return parseDOMAttrs;
58
+ };
59
+
60
+ export var customPanel = function customPanel(allowCustomPanel) {
61
+ var panelNodeSpec = {
62
+ group: 'block',
63
+ content: '(paragraph | heading | bulletList | orderedList | blockCard | unsupportedBlock)+',
64
+ marks: 'unsupportedMark unsupportedNodeAttribute',
65
+ attrs: getDefaultAttrs(),
66
+ parseDOM: [{
67
+ tag: 'div[data-panel-type]',
68
+ getAttrs: function getAttrs(dom) {
69
+ return getParseDOMAttrs(allowCustomPanel, dom);
70
+ }
71
+ }],
72
+ toDOM: function toDOM(node) {
73
+ var attrs = getDomAttrs(node.attrs);
74
+ return ['div', attrs, ['div', {}, 0]];
75
+ }
76
+ };
77
+ return panelNodeSpec;
51
78
  };
52
79
  export var panel = {
53
80
  group: 'block',
@@ -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';
@@ -5,10 +5,57 @@ export var isSafeUrl = function isSafeUrl(url) {
5
5
  return p.test(url.trim()) === true;
6
6
  });
7
7
  };
8
- var linkify = LinkifyIt();
8
+ export var linkify = LinkifyIt();
9
9
  linkify.add('sourcetree:', 'http:');
10
+ var tlds = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
11
+ 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]';
12
+ tlds.push(tlds2Char);
13
+ linkify.tlds(tlds, false);
14
+ export var LINK_REGEXP = /(https?|ftp):\/\/[^\s]+/;
15
+ export var linkifyMatch = function linkifyMatch(text) {
16
+ var matches = [];
17
+
18
+ if (!LINK_REGEXP.test(text)) {
19
+ return matches;
20
+ }
21
+
22
+ var startpos = 0;
23
+ var substr;
24
+
25
+ while (substr = text.substr(startpos)) {
26
+ var link = (substr.match(LINK_REGEXP) || [''])[0];
27
+
28
+ if (link) {
29
+ var index = substr.search(LINK_REGEXP);
30
+ var start = index >= 0 ? index + startpos : index;
31
+ var end = start + link.length;
32
+ matches.push({
33
+ index: start,
34
+ lastIndex: end,
35
+ raw: link,
36
+ url: link,
37
+ text: link,
38
+ schema: ''
39
+ });
40
+ startpos += end;
41
+ } else {
42
+ break;
43
+ }
44
+ }
45
+
46
+ return matches;
47
+ };
10
48
  export function getLinkMatch(str) {
11
- var match = str && linkify.match(str);
49
+ if (!str) {
50
+ return null;
51
+ }
52
+
53
+ var match = linkifyMatch(str);
54
+
55
+ if (!match.length) {
56
+ match = linkify.match(str);
57
+ }
58
+
12
59
  return match && match[0];
13
60
  }
14
61
  /**
@@ -17,5 +64,5 @@ export function getLinkMatch(str) {
17
64
 
18
65
  export function normalizeUrl(url) {
19
66
  var match = getLinkMatch(url);
20
- return match && match.url || url;
67
+ return match && match.url || '';
21
68
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/adf-schema",
3
- "version": "19.2.0",
3
+ "version": "19.3.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,4 +1,4 @@
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
2
  export type { AlignmentAttributes, AlignmentMarkDefinition, AnnotationMarkAttributes, AnnotationMarkDefinition, BlockCardDefinition, BlockContent, BlockQuoteDefinition, BodiedExtensionDefinition, BodiedExtensionWithMarksDefinition, BreakoutMarkAttrs, BreakoutMarkDefinition, BulletListDefinition, CaptionDefinition, CardAttributes, CellAttributes, CodeBlockAttrs, CodeBlockBaseDefinition, CodeBlockDefinition, CodeBlockWithMarksDefinition, CodeDefinition, DataConsumerAttributes, DataConsumerDefinition, DataType, DateDefinition, DecisionItemDefinition, DecisionListDefinition, DocNode, EmbedCardDefinition, EmbedCardAttributes, EmDefinition, EmojiAttributes, EmojiDefinition, ExpandDefinition, ExtensionDefinition, ExtensionWithMarksDefinition, ExtensionLayout, ExternalMediaAttributes, HardBreakDefinition, HeadingBaseDefinition, HeadingDefinition, HeadingWithAlignmentDefinition, HeadingWithIndentationDefinition, HeadingWithMarksDefinition, IndentationMarkAttributes, IndentationMarkDefinition, Inline, InlineAtomic, InlineCardDefinition, InlineCode, InlineExtensionDefinition, InlineExtensionWithMarksDefinition, InlineFormattedText, InlineLinkText, LayoutColumnDefinition, LayoutSectionDefinition, LayoutSectionFullDefinition, LayoutSectionWithSingleColumnDefinition, LinkAttributes, LinkDefinition, ListItemArray, ListItemDefinition, MarksObject, MediaADFAttrs, MediaAttributes, MediaInlineAttributes, MediaInlineDefinition, MediaBaseAttributes, MediaDefinition, MediaDisplayType, MediaGroupDefinition, MediaSingleDefinition, MediaType, MentionAttributes, MentionDefinition, MentionUserType, NestedExpandContent, NestedExpandDefinition, NoMark, NonNestableBlockContent, OrderedListDefinition, PanelAttributes, PanelDefinition, ParagraphBaseDefinition, ParagraphDefinition, ParagraphWithAlignmentDefinition, ParagraphWithIndentationDefinition, ParagraphWithMarksDefinition, PlaceholderDefinition, RuleDefinition, StatusDefinition, StrikeDefinition, StrongDefinition, SubSupAttributes, SubSupDefinition, TableAttributes, TableCellDefinition, TableDefinition, TableHeaderDefinition, TableLayout, TableRowDefinition, TaskItemDefinition, TaskListContent, TaskListDefinition, TextColorAttributes, TextColorDefinition, TextDefinition, UnderlineDefinition, UrlType, AnnotationId, RichMediaAttributes, RichMediaLayout, AnnotationDataAttributes, CellDomAttrs, } from './schema';
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, acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, generateUuid, getEmojiAcName, getLinkMatch, hexToRgb, hexToRgba, isHex, isRgb, isSafeUrl, normalizeHexColor, normalizeUrl, rgbToHex, uuid, } from './utils';
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, acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, generateUuid, getEmojiAcName, getLinkMatch, hexToRgb, hexToRgba, isHex, isRgb, isSafeUrl, linkify, linkifyMatch, normalizeHexColor, normalizeUrl, rgbToHex, uuid, } from './utils';
4
4
  export type { Match, NameToEmoji } from './utils';
@@ -29,3 +29,4 @@ export interface SchemaCustomNodeSpecs {
29
29
  export interface SchemaCustomMarkSpecs {
30
30
  [name: string]: MarkSpec;
31
31
  }
32
+ export declare const allowCustomPanel: boolean;
@@ -19,7 +19,7 @@ export declare type LayoutSectionFullDefinition = LayoutSectionBaseDefinition &
19
19
  type: 'layoutSection';
20
20
  marks?: Array<BreakoutMarkDefinition>;
21
21
  /**
22
- * @minItems 1
22
+ * @minItems 2
23
23
  * @maxItems 3
24
24
  * @allowUnsupportedBlock true
25
25
  */
@@ -42,5 +42,5 @@ export interface PanelDefinition {
42
42
  export interface DOMAttributes {
43
43
  [propName: string]: string;
44
44
  }
45
- export declare const customPanel: NodeSpec;
45
+ export declare const customPanel: (allowCustomPanel: boolean) => NodeSpec;
46
46
  export declare const panel: NodeSpec;
@@ -2,5 +2,5 @@ export { acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, getEmojiAcName, } fr
2
2
  export type { NameToEmoji } from './confluence/emoji';
3
3
  export { generateUuid, uuid } from './uuid';
4
4
  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';
5
- export { getLinkMatch, isSafeUrl, normalizeUrl } from './url';
5
+ export { getLinkMatch, isSafeUrl, normalizeUrl, linkify, linkifyMatch, } from './url';
6
6
  export type { Match } from './url';
@@ -1,3 +1,4 @@
1
+ import LinkifyIt from 'linkify-it';
1
2
  export declare const isSafeUrl: (url: string) => boolean;
2
3
  export interface Match {
3
4
  schema: any;
@@ -7,9 +8,13 @@ export interface Match {
7
8
  text: string;
8
9
  url: string;
9
10
  length?: number;
11
+ input?: string;
10
12
  }
11
- export declare function getLinkMatch(str: string): '' | Match | null;
13
+ export declare const linkify: LinkifyIt.LinkifyIt;
14
+ export declare const LINK_REGEXP: RegExp;
15
+ export declare const linkifyMatch: (text: string) => Match[];
16
+ export declare function getLinkMatch(str?: string): Match | null;
12
17
  /**
13
18
  * Adds protocol to url if needed.
14
19
  */
15
- export declare function normalizeUrl(url: string): string;
20
+ export declare function normalizeUrl(url?: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/adf-schema",
3
- "version": "19.2.0",
3
+ "version": "19.3.0",
4
4
  "description": "Shared package that contains the ADF-schema (json) and ProseMirror node/mark specs",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,13 +35,13 @@
35
35
  "@types/prosemirror-state": "^1.2.0",
36
36
  "css-color-names": "0.0.4",
37
37
  "linkify-it": "^2.0.3",
38
- "memoize-one": "^5.1.0",
38
+ "memoize-one": "^6.0.0",
39
39
  "prosemirror-model": "1.11.0",
40
40
  "prosemirror-transform": "1.2.8"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@atlaskit/editor-json-transformer": "^8.6.0",
44
- "@atlaskit/editor-test-helpers": "^15.4.0",
44
+ "@atlaskit/editor-test-helpers": "^15.5.0",
45
45
  "@atlaskit/json-schema-generator": "^3.1.0",
46
46
  "@atlassian/adf-sample": "^1.0.0",
47
47
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",