@atlaskit/editor-common 78.22.4 → 78.23.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 (30) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/monitoring/error.js +1 -1
  3. package/dist/cjs/paste/md-plugins/linkify-md-plugin.js +9 -1
  4. package/dist/cjs/ui/DropList/index.js +1 -1
  5. package/dist/cjs/utils/hyperlink.js +9 -1
  6. package/dist/cjs/utils/index.js +7 -0
  7. package/dist/cjs/utils/should-auto-linkify-tld.js +87 -0
  8. package/dist/es2019/monitoring/error.js +1 -1
  9. package/dist/es2019/paste/md-plugins/linkify-md-plugin.js +8 -2
  10. package/dist/es2019/ui/DropList/index.js +1 -1
  11. package/dist/es2019/utils/hyperlink.js +7 -1
  12. package/dist/es2019/utils/index.js +1 -0
  13. package/dist/es2019/utils/should-auto-linkify-tld.js +80 -0
  14. package/dist/esm/monitoring/error.js +1 -1
  15. package/dist/esm/paste/md-plugins/linkify-md-plugin.js +10 -2
  16. package/dist/esm/ui/DropList/index.js +1 -1
  17. package/dist/esm/utils/hyperlink.js +9 -1
  18. package/dist/esm/utils/index.js +1 -0
  19. package/dist/esm/utils/should-auto-linkify-tld.js +80 -0
  20. package/dist/types/analytics/types/loom-events.d.ts +4 -3
  21. package/dist/types/types/annotation/index.d.ts +1 -0
  22. package/dist/types/utils/hyperlink.d.ts +6 -3
  23. package/dist/types/utils/index.d.ts +1 -0
  24. package/dist/types/utils/should-auto-linkify-tld.d.ts +17 -0
  25. package/dist/types-ts4.5/analytics/types/loom-events.d.ts +4 -3
  26. package/dist/types-ts4.5/types/annotation/index.d.ts +1 -0
  27. package/dist/types-ts4.5/utils/hyperlink.d.ts +6 -3
  28. package/dist/types-ts4.5/utils/index.d.ts +1 -0
  29. package/dist/types-ts4.5/utils/should-auto-linkify-tld.d.ts +17 -0
  30. package/package.json +6 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 78.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#84430](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/84430) [`2981b2835973`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2981b2835973) - [ux] EDM-9111 Prevent linkification of links with suspicious tlds
8
+ - [#86103](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/86103) [`af2544086b27`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/af2544086b27) - Changed comment create mutation to send pos if comment is added to a block node
9
+
10
+ ### Patch Changes
11
+
12
+ - [#85470](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/85470) [`32cb4d4ca34f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/32cb4d4ca34f) - Update loom plugin to take in interface and remove SDK references
13
+ - Updated dependencies
14
+
3
15
  ## 78.22.4
4
16
 
5
17
  ### Patch Changes
@@ -16,7 +16,7 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
16
16
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
17
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
18
18
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
19
- var packageVersion = "78.22.4";
19
+ var packageVersion = "78.23.0";
20
20
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
21
21
  // Remove URL as it has UGC
22
22
  // TODO: Sanitise the URL instead of just removing it
@@ -7,11 +7,14 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _linkifyIt = _interopRequireDefault(require("linkify-it"));
9
9
  var _adfSchema = require("@atlaskit/adf-schema");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _utils = require("../../utils");
11
12
  // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/md/linkify-md-plugin.ts
12
13
  // If changes are made to this file, please make the same update in the linked file.
13
14
 
14
- // modified version of the original Linkify plugin
15
+ // See https://product-fabric.atlassian.net/browse/ED-3097 for why this file exists.
16
+
17
+ // modified version of the original markdown-it Linkify plugin
15
18
  // https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js
16
19
  var arrayReplaceAt = function arrayReplaceAt(src, pos, newElements) {
17
20
  return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1));
@@ -64,6 +67,11 @@ var linkify = function linkify(state) {
64
67
  if (!links.length) {
65
68
  links = linkify.match(text) || [];
66
69
  }
70
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.prevent-suspicious-linkification')) {
71
+ links = links.filter(function (link) {
72
+ return (0, _utils.shouldAutoLinkifyMatch)(link);
73
+ });
74
+ }
67
75
 
68
76
  // Now split string to nodes
69
77
  var nodes = [];
@@ -22,7 +22,7 @@ var _templateObject, _templateObject2, _templateObject3;
22
22
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
23
23
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /** @jsx jsx */
24
24
  var packageName = "@atlaskit/editor-common";
25
- var packageVersion = "78.22.4";
25
+ var packageVersion = "78.23.0";
26
26
  var halfFocusRing = 1;
27
27
  var dropOffset = '0, 8';
28
28
  var DropList = /*#__PURE__*/function (_Component) {
@@ -14,7 +14,9 @@ exports.normalizeUrl = normalizeUrl;
14
14
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
15
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
16
16
  var _adfSchema = require("@atlaskit/adf-schema");
17
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
18
  var _types = require("../analytics/types");
19
+ var _shouldAutoLinkifyTld = require("./should-auto-linkify-tld");
18
20
  var _slice = require("./slice");
19
21
  // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/utils/hyperlink.ts
20
22
  // If changes are made to this file, please make the same update in the linked file.
@@ -84,6 +86,10 @@ function normalizeUrl(url) {
84
86
  }
85
87
  return (0, _adfSchema.normalizeUrl)(url);
86
88
  }
89
+
90
+ /**
91
+ * Linkify content in a slice (eg. after a rich text paste)
92
+ */
87
93
  function linkifyContent(schema) {
88
94
  return function (slice) {
89
95
  return (0, _slice.mapSlice)(slice, function (node, parent) {
@@ -95,7 +101,9 @@ function linkifyContent(schema) {
95
101
  if (isAllowedInParent && node.isText && !link.isInSet(node.marks)) {
96
102
  var linkified = [];
97
103
  var text = node.text;
98
- var matches = findLinkMatches(text);
104
+ var matches = (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.prevent-suspicious-linkification') ? findLinkMatches(text).filter(function (match) {
105
+ return (0, _shouldAutoLinkifyTld.shouldAutoLinkifyTld)(match.title);
106
+ }) : findLinkMatches(text);
99
107
  var pos = 0;
100
108
  var filepaths = findFilepaths(text);
101
109
  matches.forEach(function (match) {
@@ -950,6 +950,12 @@ Object.defineProperty(exports, "setTextSelection", {
950
950
  }
951
951
  });
952
952
  exports.shallowEqual = shallowEqual;
953
+ Object.defineProperty(exports, "shouldAutoLinkifyMatch", {
954
+ enumerable: true,
955
+ get: function get() {
956
+ return _shouldAutoLinkifyTld.shouldAutoLinkifyMatch;
957
+ }
958
+ });
953
959
  Object.defineProperty(exports, "shouldForceTracking", {
954
960
  enumerable: true,
955
961
  get: function get() {
@@ -1109,6 +1115,7 @@ Object.defineProperty(exports, "wrapSelectionIn", {
1109
1115
  var _utils = require("@atlaskit/editor-prosemirror/utils");
1110
1116
  var _document = require("./document");
1111
1117
  var _editorCoreUtils = require("./editor-core-utils");
1118
+ var _shouldAutoLinkifyTld = require("./should-auto-linkify-tld");
1112
1119
  var _annotation = require("./annotation");
1113
1120
  var _macro = require("./macro");
1114
1121
  var _browser = _interopRequireDefault(require("./browser"));
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldAutoLinkifyMatch = shouldAutoLinkifyMatch;
7
+ exports.shouldAutoLinkifyTld = shouldAutoLinkifyTld;
8
+ /** Created by scanning the Wikipedia page for all TLDs and selecting those that are common filenames, along
9
+ * with customer complaints */
10
+ var tldsToNotAutoLinkify = ['name', 'zip', 'doc', 'mov',
11
+ // Ensure common 2 character file extensions aren't linkified without https prefix
12
+ 'md',
13
+ // Postscript
14
+ 'ps',
15
+ // C++
16
+ 'cc',
17
+ // C#
18
+ 'cs',
19
+ // f#
20
+ 'fs',
21
+ // Go
22
+ 'go',
23
+ // JavaScript
24
+ 'js',
25
+ // Perl
26
+ 'pl',
27
+ // Perl module
28
+ 'pm',
29
+ // Python
30
+ 'py',
31
+ // Ruby
32
+ 'rb',
33
+ // Rust
34
+ 'rs',
35
+ // Bash
36
+ 'sh',
37
+ // Typescript
38
+ 'ts',
39
+ // C#
40
+ 'cs',
41
+ // Visual Basic
42
+ 'vb'];
43
+
44
+ /**
45
+ * Decide if a url should auto linkify, based on the TLD.
46
+ * If URL is in a list of suspicious TLDs (eg. README.md), returns false
47
+ * If URL is prefixed with http:// or https:// or www, returns true (allows linkify), as user intention is clear
48
+ * this is a URL.
49
+ * If the link is invalid (eg. missing a TLD), returns true (allows linkify)
50
+ *
51
+ * @param url Link that hasn't been already prefixed with http://, https:// or www.
52
+ */
53
+ function shouldAutoLinkifyTld(url) {
54
+ var startsWithHttpHttps = /^https?:\/\//.test(url);
55
+ if (startsWithHttpHttps) {
56
+ return true;
57
+ }
58
+ var startsWithWWW = /^www\./.test(url);
59
+ if (startsWithWWW) {
60
+ return true;
61
+ }
62
+ try {
63
+ var hostname = new URL("https://".concat(url)).hostname;
64
+ var parts = hostname.split('.');
65
+ var tld = parts.length > 1 ? parts[parts.length - 1] : null;
66
+ if (parts[0] === '') {
67
+ // If the domain is an empty string (ie the link is `.com`), it's invalid, so
68
+ // automatically return true
69
+ return true;
70
+ }
71
+ if (!tld) {
72
+ return true;
73
+ }
74
+ return !tldsToNotAutoLinkify.includes(tld);
75
+ } catch (e) {
76
+ return true;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Check if url match uses tld we don't want to auto linkify
82
+ * @param match Linkify Match
83
+ * @returns True if should auto linkify, false otherwise
84
+ */
85
+ function shouldAutoLinkifyMatch(match) {
86
+ return shouldAutoLinkifyTld(match.raw);
87
+ }
@@ -1,6 +1,6 @@
1
1
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
2
2
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
3
- const packageVersion = "78.22.4";
3
+ const packageVersion = "78.23.0";
4
4
  const sanitiseSentryEvents = (data, _hint) => {
5
5
  // Remove URL as it has UGC
6
6
  // TODO: Sanitise the URL instead of just removing it
@@ -1,11 +1,14 @@
1
1
  // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/md/linkify-md-plugin.ts
2
2
  // If changes are made to this file, please make the same update in the linked file.
3
3
 
4
+ // See https://product-fabric.atlassian.net/browse/ED-3097 for why this file exists.
5
+
4
6
  import LinkifyIt from 'linkify-it';
5
7
  import { linkifyMatch } from '@atlaskit/adf-schema';
6
- import { findFilepaths, isLinkInMatches } from '../../utils';
8
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
9
+ import { findFilepaths, isLinkInMatches, shouldAutoLinkifyMatch } from '../../utils';
7
10
 
8
- // modified version of the original Linkify plugin
11
+ // modified version of the original markdown-it Linkify plugin
9
12
  // https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js
10
13
  const arrayReplaceAt = (src, pos, newElements) => {
11
14
  return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1));
@@ -58,6 +61,9 @@ const linkify = state => {
58
61
  if (!links.length) {
59
62
  links = linkify.match(text) || [];
60
63
  }
64
+ if (getBooleanFF('platform.linking-platform.prevent-suspicious-linkification')) {
65
+ links = links.filter(link => shouldAutoLinkifyMatch(link));
66
+ }
61
67
 
62
68
  // Now split string to nodes
63
69
  const nodes = [];
@@ -7,7 +7,7 @@ import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@
7
7
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
8
8
  import Layer from '../Layer';
9
9
  const packageName = "@atlaskit/editor-common";
10
- const packageVersion = "78.22.4";
10
+ const packageVersion = "78.23.0";
11
11
  const halfFocusRing = 1;
12
12
  const dropOffset = '0, 8';
13
13
  class DropList extends Component {
@@ -2,7 +2,9 @@
2
2
  // If changes are made to this file, please make the same update in the linked file.
3
3
 
4
4
  import { isSafeUrl, linkify, normalizeUrl as normaliseLinkHref } from '@atlaskit/adf-schema';
5
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
6
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics/types';
7
+ import { shouldAutoLinkifyTld } from './should-auto-linkify-tld';
6
8
  import { mapSlice } from './slice';
7
9
 
8
10
  // Regular expression for a windows filepath in the format <DRIVE LETTER>:\<folder name>\
@@ -57,6 +59,10 @@ export function normalizeUrl(url) {
57
59
  }
58
60
  return normaliseLinkHref(url);
59
61
  }
62
+
63
+ /**
64
+ * Linkify content in a slice (eg. after a rich text paste)
65
+ */
60
66
  export function linkifyContent(schema) {
61
67
  return slice => mapSlice(slice, (node, parent) => {
62
68
  const isAllowedInParent = !parent || parent.type !== schema.nodes.codeBlock;
@@ -67,7 +73,7 @@ export function linkifyContent(schema) {
67
73
  if (isAllowedInParent && node.isText && !link.isInSet(node.marks)) {
68
74
  const linkified = [];
69
75
  const text = node.text;
70
- const matches = findLinkMatches(text);
76
+ const matches = getBooleanFF('platform.linking-platform.prevent-suspicious-linkification') ? findLinkMatches(text).filter(match => shouldAutoLinkifyTld(match.title)) : findLinkMatches(text);
71
77
  let pos = 0;
72
78
  const filepaths = findFilepaths(text);
73
79
  matches.forEach(match => {
@@ -1,6 +1,7 @@
1
1
  import { hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
2
2
  import { hasDocAsParent } from './document';
3
3
  import { isEmptyParagraph } from './editor-core-utils';
4
+ export { shouldAutoLinkifyMatch } from './should-auto-linkify-tld';
4
5
  export { canApplyAnnotationOnRange, containsAnyAnnotations, getAnnotationIdsFromRange, hasAnnotationMark } from './annotation';
5
6
  export { getExtensionLozengeData } from './macro';
6
7
  export { default as browser } from './browser';
@@ -0,0 +1,80 @@
1
+ /** Created by scanning the Wikipedia page for all TLDs and selecting those that are common filenames, along
2
+ * with customer complaints */
3
+ const tldsToNotAutoLinkify = ['name', 'zip', 'doc', 'mov',
4
+ // Ensure common 2 character file extensions aren't linkified without https prefix
5
+ 'md',
6
+ // Postscript
7
+ 'ps',
8
+ // C++
9
+ 'cc',
10
+ // C#
11
+ 'cs',
12
+ // f#
13
+ 'fs',
14
+ // Go
15
+ 'go',
16
+ // JavaScript
17
+ 'js',
18
+ // Perl
19
+ 'pl',
20
+ // Perl module
21
+ 'pm',
22
+ // Python
23
+ 'py',
24
+ // Ruby
25
+ 'rb',
26
+ // Rust
27
+ 'rs',
28
+ // Bash
29
+ 'sh',
30
+ // Typescript
31
+ 'ts',
32
+ // C#
33
+ 'cs',
34
+ // Visual Basic
35
+ 'vb'];
36
+
37
+ /**
38
+ * Decide if a url should auto linkify, based on the TLD.
39
+ * If URL is in a list of suspicious TLDs (eg. README.md), returns false
40
+ * If URL is prefixed with http:// or https:// or www, returns true (allows linkify), as user intention is clear
41
+ * this is a URL.
42
+ * If the link is invalid (eg. missing a TLD), returns true (allows linkify)
43
+ *
44
+ * @param url Link that hasn't been already prefixed with http://, https:// or www.
45
+ */
46
+ export function shouldAutoLinkifyTld(url) {
47
+ const startsWithHttpHttps = /^https?:\/\//.test(url);
48
+ if (startsWithHttpHttps) {
49
+ return true;
50
+ }
51
+ const startsWithWWW = /^www\./.test(url);
52
+ if (startsWithWWW) {
53
+ return true;
54
+ }
55
+ try {
56
+ const hostname = new URL(`https://${url}`).hostname;
57
+ const parts = hostname.split('.');
58
+ const tld = parts.length > 1 ? parts[parts.length - 1] : null;
59
+ if (parts[0] === '') {
60
+ // If the domain is an empty string (ie the link is `.com`), it's invalid, so
61
+ // automatically return true
62
+ return true;
63
+ }
64
+ if (!tld) {
65
+ return true;
66
+ }
67
+ return !tldsToNotAutoLinkify.includes(tld);
68
+ } catch (e) {
69
+ return true;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Check if url match uses tld we don't want to auto linkify
75
+ * @param match Linkify Match
76
+ * @returns True if should auto linkify, false otherwise
77
+ */
78
+ export function shouldAutoLinkifyMatch(match) {
79
+ return shouldAutoLinkifyTld(match.raw);
80
+ }
@@ -6,7 +6,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
6
6
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
7
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
8
8
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
9
- var packageVersion = "78.22.4";
9
+ var packageVersion = "78.23.0";
10
10
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
11
11
  // Remove URL as it has UGC
12
12
  // TODO: Sanitise the URL instead of just removing it
@@ -1,11 +1,14 @@
1
1
  // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/md/linkify-md-plugin.ts
2
2
  // If changes are made to this file, please make the same update in the linked file.
3
3
 
4
+ // See https://product-fabric.atlassian.net/browse/ED-3097 for why this file exists.
5
+
4
6
  import LinkifyIt from 'linkify-it';
5
7
  import { linkifyMatch } from '@atlaskit/adf-schema';
6
- import { findFilepaths, isLinkInMatches } from '../../utils';
8
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
9
+ import { findFilepaths, isLinkInMatches, shouldAutoLinkifyMatch } from '../../utils';
7
10
 
8
- // modified version of the original Linkify plugin
11
+ // modified version of the original markdown-it Linkify plugin
9
12
  // https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js
10
13
  var arrayReplaceAt = function arrayReplaceAt(src, pos, newElements) {
11
14
  return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1));
@@ -58,6 +61,11 @@ var linkify = function linkify(state) {
58
61
  if (!links.length) {
59
62
  links = linkify.match(text) || [];
60
63
  }
64
+ if (getBooleanFF('platform.linking-platform.prevent-suspicious-linkification')) {
65
+ links = links.filter(function (link) {
66
+ return shouldAutoLinkifyMatch(link);
67
+ });
68
+ }
61
69
 
62
70
  // Now split string to nodes
63
71
  var nodes = [];
@@ -17,7 +17,7 @@ import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@
17
17
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
18
18
  import Layer from '../Layer';
19
19
  var packageName = "@atlaskit/editor-common";
20
- var packageVersion = "78.22.4";
20
+ var packageVersion = "78.23.0";
21
21
  var halfFocusRing = 1;
22
22
  var dropOffset = '0, 8';
23
23
  var DropList = /*#__PURE__*/function (_Component) {
@@ -4,7 +4,9 @@ import _createClass from "@babel/runtime/helpers/createClass";
4
4
  // If changes are made to this file, please make the same update in the linked file.
5
5
 
6
6
  import { isSafeUrl, linkify, normalizeUrl as normaliseLinkHref } from '@atlaskit/adf-schema';
7
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
8
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics/types';
9
+ import { shouldAutoLinkifyTld } from './should-auto-linkify-tld';
8
10
  import { mapSlice } from './slice';
9
11
 
10
12
  // Regular expression for a windows filepath in the format <DRIVE LETTER>:\<folder name>\
@@ -73,6 +75,10 @@ export function normalizeUrl(url) {
73
75
  }
74
76
  return normaliseLinkHref(url);
75
77
  }
78
+
79
+ /**
80
+ * Linkify content in a slice (eg. after a rich text paste)
81
+ */
76
82
  export function linkifyContent(schema) {
77
83
  return function (slice) {
78
84
  return mapSlice(slice, function (node, parent) {
@@ -84,7 +90,9 @@ export function linkifyContent(schema) {
84
90
  if (isAllowedInParent && node.isText && !link.isInSet(node.marks)) {
85
91
  var linkified = [];
86
92
  var text = node.text;
87
- var matches = findLinkMatches(text);
93
+ var matches = getBooleanFF('platform.linking-platform.prevent-suspicious-linkification') ? findLinkMatches(text).filter(function (match) {
94
+ return shouldAutoLinkifyTld(match.title);
95
+ }) : findLinkMatches(text);
88
96
  var pos = 0;
89
97
  var filepaths = findFilepaths(text);
90
98
  matches.forEach(function (match) {
@@ -1,6 +1,7 @@
1
1
  import { hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
2
2
  import { hasDocAsParent } from './document';
3
3
  import { isEmptyParagraph } from './editor-core-utils';
4
+ export { shouldAutoLinkifyMatch } from './should-auto-linkify-tld';
4
5
  export { canApplyAnnotationOnRange, containsAnyAnnotations, getAnnotationIdsFromRange, hasAnnotationMark } from './annotation';
5
6
  export { getExtensionLozengeData } from './macro';
6
7
  export { default as browser } from './browser';
@@ -0,0 +1,80 @@
1
+ /** Created by scanning the Wikipedia page for all TLDs and selecting those that are common filenames, along
2
+ * with customer complaints */
3
+ var tldsToNotAutoLinkify = ['name', 'zip', 'doc', 'mov',
4
+ // Ensure common 2 character file extensions aren't linkified without https prefix
5
+ 'md',
6
+ // Postscript
7
+ 'ps',
8
+ // C++
9
+ 'cc',
10
+ // C#
11
+ 'cs',
12
+ // f#
13
+ 'fs',
14
+ // Go
15
+ 'go',
16
+ // JavaScript
17
+ 'js',
18
+ // Perl
19
+ 'pl',
20
+ // Perl module
21
+ 'pm',
22
+ // Python
23
+ 'py',
24
+ // Ruby
25
+ 'rb',
26
+ // Rust
27
+ 'rs',
28
+ // Bash
29
+ 'sh',
30
+ // Typescript
31
+ 'ts',
32
+ // C#
33
+ 'cs',
34
+ // Visual Basic
35
+ 'vb'];
36
+
37
+ /**
38
+ * Decide if a url should auto linkify, based on the TLD.
39
+ * If URL is in a list of suspicious TLDs (eg. README.md), returns false
40
+ * If URL is prefixed with http:// or https:// or www, returns true (allows linkify), as user intention is clear
41
+ * this is a URL.
42
+ * If the link is invalid (eg. missing a TLD), returns true (allows linkify)
43
+ *
44
+ * @param url Link that hasn't been already prefixed with http://, https:// or www.
45
+ */
46
+ export function shouldAutoLinkifyTld(url) {
47
+ var startsWithHttpHttps = /^https?:\/\//.test(url);
48
+ if (startsWithHttpHttps) {
49
+ return true;
50
+ }
51
+ var startsWithWWW = /^www\./.test(url);
52
+ if (startsWithWWW) {
53
+ return true;
54
+ }
55
+ try {
56
+ var hostname = new URL("https://".concat(url)).hostname;
57
+ var parts = hostname.split('.');
58
+ var tld = parts.length > 1 ? parts[parts.length - 1] : null;
59
+ if (parts[0] === '') {
60
+ // If the domain is an empty string (ie the link is `.com`), it's invalid, so
61
+ // automatically return true
62
+ return true;
63
+ }
64
+ if (!tld) {
65
+ return true;
66
+ }
67
+ return !tldsToNotAutoLinkify.includes(tld);
68
+ } catch (e) {
69
+ return true;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Check if url match uses tld we don't want to auto linkify
75
+ * @param match Linkify Match
76
+ * @returns True if should auto linkify, false otherwise
77
+ */
78
+ export function shouldAutoLinkifyMatch(match) {
79
+ return shouldAutoLinkifyTld(match.raw);
80
+ }
@@ -1,16 +1,17 @@
1
- import type { SDKUnsupportedReasons } from '@loomhq/record-sdk';
2
1
  import type { ACTION, ACTION_SUBJECT, INPUT_METHOD } from './enums';
3
2
  import type { OperationalAEP, TrackAEP } from './utils';
3
+ type LoomPluginErrorMessages = 'is-supported-failure' | 'failed-to-initialise' | 'api-key-not-provided';
4
+ type LoomSDKErrorMessages = 'incompatible-browser' | 'third-party-cookies-disabled' | 'no-media-streams-support';
4
5
  type LoomInitialisedAEP = OperationalAEP<ACTION.INITIALISED, ACTION_SUBJECT.LOOM, undefined, undefined>;
5
6
  type LoomDisabledAEP = OperationalAEP<ACTION.ERRORED, ACTION_SUBJECT.LOOM, undefined, {
6
- error?: SDKUnsupportedReasons;
7
+ error?: LoomPluginErrorMessages | LoomSDKErrorMessages;
7
8
  }>;
8
9
  type RecordVideoAEP = TrackAEP<ACTION.RECORD_VIDEO, ACTION_SUBJECT.LOOM, undefined, {
9
10
  inputMethod: INPUT_METHOD;
10
11
  }, undefined>;
11
12
  type RecordVideoFailedAEP = TrackAEP<ACTION.RECORD_VIDEO_FAILED, ACTION_SUBJECT.LOOM, undefined, {
12
13
  inputMethod: INPUT_METHOD;
13
- error?: SDKUnsupportedReasons;
14
+ error?: LoomPluginErrorMessages | LoomSDKErrorMessages;
14
15
  }, undefined>;
15
16
  type InsertVideoAEP = TrackAEP<ACTION.INSERT_VIDEO, ACTION_SUBJECT.LOOM, undefined, {
16
17
  duration?: number;
@@ -9,6 +9,7 @@ export type AnnotationByMatches = {
9
9
  originalSelection: string;
10
10
  numMatches: number;
11
11
  matchIndex: number;
12
+ pos?: number;
12
13
  isAnnotationAllowed?: boolean;
13
14
  };
14
15
  type ActionResult = {
@@ -1,6 +1,6 @@
1
- import { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
2
- import { EditorState } from '@atlaskit/editor-prosemirror/state';
3
- import { AnalyticsEventPayload, InputMethodInsertLink } from '../analytics/types';
1
+ import type { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
2
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ import type { AnalyticsEventPayload, InputMethodInsertLink } from '../analytics/types';
4
4
  export declare const FILEPATH_REGEXP: RegExp;
5
5
  export declare const DONTLINKIFY_REGEXP: RegExp;
6
6
  /**
@@ -15,6 +15,9 @@ export declare class LinkMatcher {
15
15
  * Adds protocol to url if needed.
16
16
  */
17
17
  export declare function normalizeUrl(url?: string | null): string;
18
+ /**
19
+ * Linkify content in a slice (eg. after a rich text paste)
20
+ */
18
21
  export declare function linkifyContent(schema: Schema): (slice: Slice) => Slice;
19
22
  export declare function getLinkDomain(url: string): string;
20
23
  export declare function isFromCurrentDomain(url: string): boolean;
@@ -1,6 +1,7 @@
1
1
  import type { Node as PMNode, ResolvedPos, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
4
+ export { shouldAutoLinkifyMatch } from './should-auto-linkify-tld';
4
5
  export { canApplyAnnotationOnRange, containsAnyAnnotations, getAnnotationIdsFromRange, hasAnnotationMark, } from './annotation';
5
6
  export { getExtensionLozengeData } from './macro';
6
7
  export type { Params } from './macro';
@@ -0,0 +1,17 @@
1
+ import type { Match } from '@atlaskit/adf-schema';
2
+ /**
3
+ * Decide if a url should auto linkify, based on the TLD.
4
+ * If URL is in a list of suspicious TLDs (eg. README.md), returns false
5
+ * If URL is prefixed with http:// or https:// or www, returns true (allows linkify), as user intention is clear
6
+ * this is a URL.
7
+ * If the link is invalid (eg. missing a TLD), returns true (allows linkify)
8
+ *
9
+ * @param url Link that hasn't been already prefixed with http://, https:// or www.
10
+ */
11
+ export declare function shouldAutoLinkifyTld(url: string): boolean;
12
+ /**
13
+ * Check if url match uses tld we don't want to auto linkify
14
+ * @param match Linkify Match
15
+ * @returns True if should auto linkify, false otherwise
16
+ */
17
+ export declare function shouldAutoLinkifyMatch(match: Match): boolean;
@@ -1,16 +1,17 @@
1
- import type { SDKUnsupportedReasons } from '@loomhq/record-sdk';
2
1
  import type { ACTION, ACTION_SUBJECT, INPUT_METHOD } from './enums';
3
2
  import type { OperationalAEP, TrackAEP } from './utils';
3
+ type LoomPluginErrorMessages = 'is-supported-failure' | 'failed-to-initialise' | 'api-key-not-provided';
4
+ type LoomSDKErrorMessages = 'incompatible-browser' | 'third-party-cookies-disabled' | 'no-media-streams-support';
4
5
  type LoomInitialisedAEP = OperationalAEP<ACTION.INITIALISED, ACTION_SUBJECT.LOOM, undefined, undefined>;
5
6
  type LoomDisabledAEP = OperationalAEP<ACTION.ERRORED, ACTION_SUBJECT.LOOM, undefined, {
6
- error?: SDKUnsupportedReasons;
7
+ error?: LoomPluginErrorMessages | LoomSDKErrorMessages;
7
8
  }>;
8
9
  type RecordVideoAEP = TrackAEP<ACTION.RECORD_VIDEO, ACTION_SUBJECT.LOOM, undefined, {
9
10
  inputMethod: INPUT_METHOD;
10
11
  }, undefined>;
11
12
  type RecordVideoFailedAEP = TrackAEP<ACTION.RECORD_VIDEO_FAILED, ACTION_SUBJECT.LOOM, undefined, {
12
13
  inputMethod: INPUT_METHOD;
13
- error?: SDKUnsupportedReasons;
14
+ error?: LoomPluginErrorMessages | LoomSDKErrorMessages;
14
15
  }, undefined>;
15
16
  type InsertVideoAEP = TrackAEP<ACTION.INSERT_VIDEO, ACTION_SUBJECT.LOOM, undefined, {
16
17
  duration?: number;
@@ -9,6 +9,7 @@ export type AnnotationByMatches = {
9
9
  originalSelection: string;
10
10
  numMatches: number;
11
11
  matchIndex: number;
12
+ pos?: number;
12
13
  isAnnotationAllowed?: boolean;
13
14
  };
14
15
  type ActionResult = {
@@ -1,6 +1,6 @@
1
- import { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
2
- import { EditorState } from '@atlaskit/editor-prosemirror/state';
3
- import { AnalyticsEventPayload, InputMethodInsertLink } from '../analytics/types';
1
+ import type { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
2
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ import type { AnalyticsEventPayload, InputMethodInsertLink } from '../analytics/types';
4
4
  export declare const FILEPATH_REGEXP: RegExp;
5
5
  export declare const DONTLINKIFY_REGEXP: RegExp;
6
6
  /**
@@ -15,6 +15,9 @@ export declare class LinkMatcher {
15
15
  * Adds protocol to url if needed.
16
16
  */
17
17
  export declare function normalizeUrl(url?: string | null): string;
18
+ /**
19
+ * Linkify content in a slice (eg. after a rich text paste)
20
+ */
18
21
  export declare function linkifyContent(schema: Schema): (slice: Slice) => Slice;
19
22
  export declare function getLinkDomain(url: string): string;
20
23
  export declare function isFromCurrentDomain(url: string): boolean;
@@ -1,6 +1,7 @@
1
1
  import type { Node as PMNode, ResolvedPos, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
4
+ export { shouldAutoLinkifyMatch } from './should-auto-linkify-tld';
4
5
  export { canApplyAnnotationOnRange, containsAnyAnnotations, getAnnotationIdsFromRange, hasAnnotationMark, } from './annotation';
5
6
  export { getExtensionLozengeData } from './macro';
6
7
  export type { Params } from './macro';
@@ -0,0 +1,17 @@
1
+ import type { Match } from '@atlaskit/adf-schema';
2
+ /**
3
+ * Decide if a url should auto linkify, based on the TLD.
4
+ * If URL is in a list of suspicious TLDs (eg. README.md), returns false
5
+ * If URL is prefixed with http:// or https:// or www, returns true (allows linkify), as user intention is clear
6
+ * this is a URL.
7
+ * If the link is invalid (eg. missing a TLD), returns true (allows linkify)
8
+ *
9
+ * @param url Link that hasn't been already prefixed with http://, https:// or www.
10
+ */
11
+ export declare function shouldAutoLinkifyTld(url: string): boolean;
12
+ /**
13
+ * Check if url match uses tld we don't want to auto linkify
14
+ * @param match Linkify Match
15
+ * @returns True if should auto linkify, false otherwise
16
+ */
17
+ export declare function shouldAutoLinkifyMatch(match: Match): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "78.22.4",
3
+ "version": "78.23.0",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -126,10 +126,10 @@
126
126
  "@atlaskit/mention": "^23.0.0",
127
127
  "@atlaskit/menu": "^2.1.0",
128
128
  "@atlaskit/platform-feature-flags": "^0.2.0",
129
- "@atlaskit/primitives": "^5.2.0",
129
+ "@atlaskit/primitives": "^5.3.0",
130
130
  "@atlaskit/profilecard": "^19.11.0",
131
131
  "@atlaskit/section-message": "^6.4.0",
132
- "@atlaskit/smart-card": "^26.50.0",
132
+ "@atlaskit/smart-card": "^26.51.0",
133
133
  "@atlaskit/smart-user-picker": "^6.9.0",
134
134
  "@atlaskit/spinner": "^16.0.0",
135
135
  "@atlaskit/task-decision": "^17.9.0",
@@ -177,7 +177,6 @@
177
177
  "@atlaskit/visual-regression": "*",
178
178
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
179
179
  "@atlassian/feature-flags-test-utils": "*",
180
- "@loomhq/record-sdk": "^2.36.18",
181
180
  "@testing-library/dom": "^8.17.1",
182
181
  "@testing-library/jest-dom": "^5.16.5",
183
182
  "@testing-library/react": "^12.1.5",
@@ -216,6 +215,9 @@
216
215
  "platform.editor.media.extended-resize-experience": {
217
216
  "type": "boolean"
218
217
  },
218
+ "platform.linking-platform.prevent-suspicious-linkification": {
219
+ "type": "boolean"
220
+ },
219
221
  "platform.editor.media.inline-image.base-support": {
220
222
  "type": "boolean"
221
223
  },