@atlaskit/editor-plugin-card 35.1.4 → 35.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/cjs/cardPlugin.js +17 -5
- package/dist/cjs/pm-plugins/actions.js +21 -1
- package/dist/cjs/pm-plugins/main.js +17 -5
- package/dist/cjs/pm-plugins/reducers.js +13 -0
- package/dist/cjs/pm-plugins/util/pasted-inline-link.js +161 -0
- package/dist/cjs/pm-plugins/util/state.js +4 -1
- package/dist/es2019/cardPlugin.js +7 -1
- package/dist/es2019/pm-plugins/actions.js +12 -0
- package/dist/es2019/pm-plugins/main.js +15 -3
- package/dist/es2019/pm-plugins/reducers.js +13 -0
- package/dist/es2019/pm-plugins/util/pasted-inline-link.js +112 -0
- package/dist/es2019/pm-plugins/util/state.js +4 -0
- package/dist/esm/cardPlugin.js +18 -6
- package/dist/esm/pm-plugins/actions.js +20 -0
- package/dist/esm/pm-plugins/main.js +17 -5
- package/dist/esm/pm-plugins/reducers.js +13 -0
- package/dist/esm/pm-plugins/util/pasted-inline-link.js +154 -0
- package/dist/esm/pm-plugins/util/state.js +4 -1
- package/dist/types/cardPluginType.d.ts +5 -1
- package/dist/types/entry-points/types.d.ts +1 -1
- package/dist/types/pm-plugins/actions.d.ts +5 -1
- package/dist/types/pm-plugins/util/pasted-inline-link.d.ts +28 -0
- package/dist/types/pm-plugins/util/state.d.ts +5 -3
- package/dist/types/types/index.d.ts +21 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-card
|
|
2
2
|
|
|
3
|
+
## 35.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`8a910ddcb6d43`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8a910ddcb6d43) -
|
|
8
|
+
Add opt-in `trackPastedInlineLinks`. When enabled, the card plugin keeps a short, position-mapped
|
|
9
|
+
list of locally pasted inline links (pasted URLs converted to inline cards, and pasted inline
|
|
10
|
+
cards) in `pastedInlineLinks`. Existing links and other creation paths are never tracked, and a
|
|
11
|
+
candidate is dropped when its card is deleted, replaced or given a different URL.
|
|
12
|
+
|
|
13
|
+
The consumer decides which candidate to use. `markPastedInlineLinkShown(target)` confirms display:
|
|
14
|
+
it keeps only the displayed link and stops adding candidates. `clearPastedInlineLink(target)`
|
|
15
|
+
stops tracking one link. Existing first-resolved-inline-link changeboard targeting is unchanged.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
3
21
|
## 35.1.4
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/cjs/cardPlugin.js
CHANGED
|
@@ -204,9 +204,21 @@ var cardPlugin = exports.cardPlugin = function cardPlugin(_ref2) {
|
|
|
204
204
|
}));
|
|
205
205
|
},
|
|
206
206
|
commands: {
|
|
207
|
-
|
|
207
|
+
markPastedInlineLinkShown: function markPastedInlineLinkShown(target) {
|
|
208
208
|
return function (_ref6) {
|
|
209
209
|
var tr = _ref6.tr;
|
|
210
|
+
return options.trackPastedInlineLinks ? (0, _actions.markPastedInlineLinkShown)(target)(tr) : null;
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
clearPastedInlineLink: function clearPastedInlineLink(target) {
|
|
214
|
+
return function (_ref7) {
|
|
215
|
+
var tr = _ref7.tr;
|
|
216
|
+
return options.trackPastedInlineLinks ? (0, _actions.clearPastedInlineLink)(target)(tr) : null;
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
queueCardsFromRange: function queueCardsFromRange(from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance) {
|
|
220
|
+
return function (_ref8) {
|
|
221
|
+
var tr = _ref8.tr;
|
|
210
222
|
return (0, _doc.queueCardsFromRange)(
|
|
211
223
|
// Synthesise the minimal EditorState shape the impl actually reads.
|
|
212
224
|
{
|
|
@@ -239,8 +251,8 @@ var cardPlugin = exports.cardPlugin = function cardPlugin(_ref2) {
|
|
|
239
251
|
return _context.abrupt("return", false);
|
|
240
252
|
case 2:
|
|
241
253
|
previousCardProvider = provider;
|
|
242
|
-
return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (
|
|
243
|
-
var tr =
|
|
254
|
+
return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref9) {
|
|
255
|
+
var tr = _ref9.tr;
|
|
244
256
|
return (0, _actions.setProvider)(provider)(tr);
|
|
245
257
|
})) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false);
|
|
246
258
|
case 3:
|
|
@@ -349,8 +361,8 @@ var cardPlugin = exports.cardPlugin = function cardPlugin(_ref2) {
|
|
|
349
361
|
pluginsOptions: _objectSpread({
|
|
350
362
|
floatingToolbar: (0, _toolbar.floatingToolbar)(options, (_options$lpLinkPicker = options.lpLinkPicker) !== null && _options$lpLinkPicker !== void 0 ? _options$lpLinkPicker : false, options.linkPicker, api, options.disableFloatingToolbar)
|
|
351
363
|
}, isRegisteredSlashCommandEnabled ? {} : {
|
|
352
|
-
quickInsert: function quickInsert(
|
|
353
|
-
var formatMessage =
|
|
364
|
+
quickInsert: function quickInsert(_ref0) {
|
|
365
|
+
var formatMessage = _ref0.formatMessage;
|
|
354
366
|
var quickInsertArray = [];
|
|
355
367
|
if (!options.allowDatasource) {
|
|
356
368
|
return quickInsertArray;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.showLinkToolbar = exports.showDatasourceModal = exports.setResolvedToolbarAttributes = exports.setProvider = exports.setDatasourceTableRef = exports.setDatasourceStash = exports.setCardLayoutAndDatasourceTableRef = exports.setCardLayout = exports.resolveCard = exports.removeDatasourceStash = exports.removeCard = exports.registerSmartCardEvents = exports.registerRemoveOverlay = exports.registerCard = exports.queueCards = exports.hideLinkToolbar = exports.hideDatasourceModal = exports.clearOverlayCandidate = exports.cardAction = void 0;
|
|
6
|
+
exports.showLinkToolbar = exports.showDatasourceModal = exports.setResolvedToolbarAttributes = exports.setProvider = exports.setDatasourceTableRef = exports.setDatasourceStash = exports.setCardLayoutAndDatasourceTableRef = exports.setCardLayout = exports.resolveCard = exports.removeDatasourceStash = exports.removeCard = exports.registerSmartCardEvents = exports.registerRemoveOverlay = exports.registerCard = exports.queueCards = exports.markPastedInlineLinkShown = exports.hideLinkToolbar = exports.hideDatasourceModal = exports.clearPastedInlineLink = exports.clearOverlayCandidate = exports.cardAction = void 0;
|
|
7
7
|
var _pluginKey = require("./plugin-key");
|
|
8
8
|
var cardAction = exports.cardAction = function cardAction(tr, action) {
|
|
9
9
|
return tr.setMeta(_pluginKey.pluginKey, action);
|
|
@@ -140,4 +140,24 @@ var removeDatasourceStash = exports.removeDatasourceStash = function removeDatas
|
|
|
140
140
|
type: 'REMOVE_DATASOURCE_STASH',
|
|
141
141
|
url: url
|
|
142
142
|
});
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** Confirm actual display, not merely target selection or a request to display. */
|
|
146
|
+
var markPastedInlineLinkShown = exports.markPastedInlineLinkShown = function markPastedInlineLinkShown(target) {
|
|
147
|
+
return function (tr) {
|
|
148
|
+
return cardAction(tr, {
|
|
149
|
+
type: 'PASTED_INLINE_LINK_SHOWN',
|
|
150
|
+
target: target
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** Discard only this candidate; a stale callback must not clear a newer paste. */
|
|
156
|
+
var clearPastedInlineLink = exports.clearPastedInlineLink = function clearPastedInlineLink(target) {
|
|
157
|
+
return function (tr) {
|
|
158
|
+
return cardAction(tr, {
|
|
159
|
+
type: 'CLEAR_PASTED_INLINE_LINK',
|
|
160
|
+
target: target
|
|
161
|
+
});
|
|
162
|
+
};
|
|
143
163
|
};
|
|
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.createPlugin = void 0;
|
|
8
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
10
|
var _rafSchd = _interopRequireDefault(require("raf-schd"));
|
|
11
|
+
var _enums = require("@atlaskit/editor-common/analytics/types/enums");
|
|
11
12
|
var _getInlineNodeViewProducer = require("@atlaskit/editor-common/getInlineNodeViewProducer");
|
|
12
13
|
var _isSsr = require("@atlaskit/editor-common/is-ssr");
|
|
13
14
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
@@ -26,6 +27,7 @@ var _localStorage = require("../ui/local-storage");
|
|
|
26
27
|
var _actions = require("./actions");
|
|
27
28
|
var _pluginKey = require("./plugin-key");
|
|
28
29
|
var _reducers = _interopRequireDefault(require("./reducers"));
|
|
30
|
+
var _pastedInlineLink = require("./util/pasted-inline-link");
|
|
29
31
|
var _resolve = require("./util/resolve");
|
|
30
32
|
var _state2 = require("./util/state");
|
|
31
33
|
var _utils3 = require("./utils");
|
|
@@ -55,6 +57,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
|
|
|
55
57
|
fullWidthMode = options.fullWidthMode,
|
|
56
58
|
actionOptions = options.actionOptions,
|
|
57
59
|
cardPluginEvents = options.cardPluginEvents,
|
|
60
|
+
trackPastedInlineLinks = options.trackPastedInlineLinks,
|
|
58
61
|
showUpgradeDiscoverability = options.showUpgradeDiscoverability,
|
|
59
62
|
allowEmbeds = options.allowEmbeds,
|
|
60
63
|
allowBlockCards = options.allowBlockCards,
|
|
@@ -87,8 +90,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
|
|
|
87
90
|
return new _safePlugin.SafePlugin({
|
|
88
91
|
state: {
|
|
89
92
|
init: function init() {
|
|
90
|
-
return {
|
|
91
|
-
requests: []
|
|
93
|
+
return _objectSpread(_objectSpread({
|
|
94
|
+
requests: []
|
|
95
|
+
}, trackPastedInlineLinks ? {
|
|
96
|
+
pastedInlineLinks: []
|
|
97
|
+
} : {}), {}, {
|
|
92
98
|
provider: null,
|
|
93
99
|
cards: [],
|
|
94
100
|
datasourceStash: {},
|
|
@@ -101,13 +107,15 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
|
|
|
101
107
|
datasourceModalType: undefined,
|
|
102
108
|
datasourceTableRef: undefined,
|
|
103
109
|
layout: undefined
|
|
104
|
-
};
|
|
110
|
+
});
|
|
105
111
|
},
|
|
106
112
|
apply: function apply(tr, pluginState, prevEditorState) {
|
|
107
113
|
var _pluginState$requests, _pluginState$requests2;
|
|
108
114
|
// Update all the positions of outstanding requests and
|
|
109
115
|
// cards in the plugin state.
|
|
110
116
|
var pluginStateWithUpdatedPos = (0, _state2.getPluginStateWithUpdatedPos)(pluginState, tr);
|
|
117
|
+
// Pasted inline cards that already exist as nodes (copy and paste of cards).
|
|
118
|
+
pluginStateWithUpdatedPos = (0, _pastedInlineLink.withPastedInlineLinks)(pluginStateWithUpdatedPos, trackPastedInlineLinks ? (0, _pastedInlineLink.getPastedInlineCards)(tr) : []);
|
|
111
119
|
|
|
112
120
|
// apply any actions
|
|
113
121
|
var meta = tr.getMeta(_pluginKey.pluginKey);
|
|
@@ -129,7 +137,6 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
|
|
|
129
137
|
return pluginStateWithUpdatedPos;
|
|
130
138
|
}
|
|
131
139
|
var newState = (0, _reducers.default)(pluginStateWithUpdatedPos, meta);
|
|
132
|
-
|
|
133
140
|
// Track the first resolved inline smart link for PO spotlight DOM targeting
|
|
134
141
|
if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length) {
|
|
135
142
|
var resolvedRequest = pluginState.requests.find(function (req) {
|
|
@@ -147,6 +154,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
|
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
156
|
}
|
|
157
|
+
|
|
158
|
+
// Pasted URLs that were converted to inline cards.
|
|
159
|
+
if (trackPastedInlineLinks && meta.type === 'RESOLVE') {
|
|
160
|
+
newState = (0, _pastedInlineLink.withPastedInlineLinks)(newState, (0, _pastedInlineLink.getResolvedPastedInlineCards)(tr, pluginState.requests, meta.url, _enums.INPUT_METHOD.CLIPBOARD));
|
|
161
|
+
}
|
|
150
162
|
if (!enableInlineUpgradeFeatures) {
|
|
151
163
|
return newState;
|
|
152
164
|
}
|
|
@@ -9,6 +9,7 @@ exports.default = void 0;
|
|
|
9
9
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
11
|
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
12
|
+
var _pastedInlineLink = require("./util/pasted-inline-link");
|
|
12
13
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
13
14
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
15
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -141,6 +142,18 @@ var removeDatasourceStash = function removeDatasourceStash(state, action) {
|
|
|
141
142
|
};
|
|
142
143
|
var _default = exports.default = function _default(state, action) {
|
|
143
144
|
switch (action.type) {
|
|
145
|
+
case 'PASTED_INLINE_LINK_SHOWN':
|
|
146
|
+
return state.pastedInlineLinks ? _objectSpread(_objectSpread({}, state), {}, {
|
|
147
|
+
pastedInlineLinkShown: true,
|
|
148
|
+
// Keep only the displayed link so it can still be dismissed if it changes.
|
|
149
|
+
pastedInlineLinks: state.pastedInlineLinks.filter(function (link) {
|
|
150
|
+
return link.pos === action.target.pos && link.url === action.target.url;
|
|
151
|
+
})
|
|
152
|
+
}) : state;
|
|
153
|
+
case 'CLEAR_PASTED_INLINE_LINK':
|
|
154
|
+
return state.pastedInlineLinks ? _objectSpread(_objectSpread({}, state), {}, {
|
|
155
|
+
pastedInlineLinks: (0, _pastedInlineLink.removePastedInlineLink)(state.pastedInlineLinks, action.target)
|
|
156
|
+
}) : state;
|
|
144
157
|
case 'QUEUE':
|
|
145
158
|
return queue(state, action);
|
|
146
159
|
case 'SET_PROVIDER':
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.withPastedInlineLinks = exports.removePastedInlineLink = exports.mapPastedInlineLinks = exports.getResolvedPastedInlineCards = exports.getPastedInlineCards = exports.addPastedInlineLinks = exports.MAX_PASTED_INLINE_LINKS = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
10
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
|
+
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) { (0, _defineProperty2.default)(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; }
|
|
12
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
13
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
14
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
15
|
+
/** Bounds the per-editor work; the first pasted links win. */
|
|
16
|
+
var MAX_PASTED_INLINE_LINKS = exports.MAX_PASTED_INLINE_LINKS = 10;
|
|
17
|
+
var isSameLink = function isSameLink(a, b) {
|
|
18
|
+
return a.pos === b.pos && a.url === b.url;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Map candidates through a transaction. Anything that was deleted, replaced by another node or
|
|
23
|
+
* given a different URL stops being a candidate. Returns the same array when nothing changed.
|
|
24
|
+
*/
|
|
25
|
+
var mapPastedInlineLinks = exports.mapPastedInlineLinks = function mapPastedInlineLinks(links, tr) {
|
|
26
|
+
if (tr.getMeta('replaceDocument')) {
|
|
27
|
+
return links.length ? [] : links;
|
|
28
|
+
}
|
|
29
|
+
if (!tr.docChanged || !links.length) {
|
|
30
|
+
return links;
|
|
31
|
+
}
|
|
32
|
+
var changed = false;
|
|
33
|
+
var mapped = [];
|
|
34
|
+
var _iterator = _createForOfIteratorHelper(links),
|
|
35
|
+
_step;
|
|
36
|
+
try {
|
|
37
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
38
|
+
var link = _step.value;
|
|
39
|
+
var result = tr.mapping.mapResult(link.pos, 1);
|
|
40
|
+
var node = result.deleted ? null : tr.doc.nodeAt(result.pos);
|
|
41
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) !== 'inlineCard' || node.attrs.url !== link.url) {
|
|
42
|
+
changed = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (result.pos !== link.pos) {
|
|
46
|
+
changed = true;
|
|
47
|
+
mapped.push({
|
|
48
|
+
pos: result.pos,
|
|
49
|
+
url: link.url
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
mapped.push(link);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
_iterator.e(err);
|
|
57
|
+
} finally {
|
|
58
|
+
_iterator.f();
|
|
59
|
+
}
|
|
60
|
+
return changed ? mapped : links;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** Append new candidates, skipping duplicates and anything beyond the cap. */
|
|
64
|
+
var addPastedInlineLinks = exports.addPastedInlineLinks = function addPastedInlineLinks(links, additions) {
|
|
65
|
+
var next = links;
|
|
66
|
+
var _iterator2 = _createForOfIteratorHelper(additions),
|
|
67
|
+
_step2;
|
|
68
|
+
try {
|
|
69
|
+
var _loop = function _loop() {
|
|
70
|
+
var addition = _step2.value;
|
|
71
|
+
if (next.length >= MAX_PASTED_INLINE_LINKS) {
|
|
72
|
+
return 1; // break
|
|
73
|
+
}
|
|
74
|
+
if (!next.some(function (link) {
|
|
75
|
+
return isSameLink(link, addition);
|
|
76
|
+
})) {
|
|
77
|
+
next = [].concat((0, _toConsumableArray2.default)(next), [addition]);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
81
|
+
if (_loop()) break;
|
|
82
|
+
}
|
|
83
|
+
} catch (err) {
|
|
84
|
+
_iterator2.e(err);
|
|
85
|
+
} finally {
|
|
86
|
+
_iterator2.f();
|
|
87
|
+
}
|
|
88
|
+
return next;
|
|
89
|
+
};
|
|
90
|
+
var removePastedInlineLink = exports.removePastedInlineLink = function removePastedInlineLink(links, target) {
|
|
91
|
+
var next = links.filter(function (link) {
|
|
92
|
+
return !isSameLink(link, target);
|
|
93
|
+
});
|
|
94
|
+
return next.length === links.length ? links : next;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/** Inline cards inserted by a paste transaction (copy and paste of existing cards). */
|
|
98
|
+
var getPastedInlineCards = exports.getPastedInlineCards = function getPastedInlineCards(tr) {
|
|
99
|
+
if (!tr.docChanged || tr.getMeta('uiEvent') !== 'paste' || tr.getMeta('isRemote')) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
var found = [];
|
|
103
|
+
tr.mapping.maps.forEach(function (stepMap, index) {
|
|
104
|
+
var later = tr.mapping.slice(index + 1);
|
|
105
|
+
stepMap.forEach(function (_oldStart, _oldEnd, newStart, newEnd) {
|
|
106
|
+
tr.doc.nodesBetween(later.map(newStart, -1), later.map(newEnd, 1), function (node, pos) {
|
|
107
|
+
if (node.type.name === 'inlineCard' && typeof node.attrs.url === 'string') {
|
|
108
|
+
found.push({
|
|
109
|
+
pos: pos,
|
|
110
|
+
url: node.attrs.url
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
return found;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/** Inline cards created from clipboard URLs that just resolved in this transaction. */
|
|
120
|
+
var getResolvedPastedInlineCards = exports.getResolvedPastedInlineCards = function getResolvedPastedInlineCards(tr, requests, resolvedUrl, clipboardSource) {
|
|
121
|
+
if (tr.getMeta('isRemote')) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
var found = [];
|
|
125
|
+
var _iterator3 = _createForOfIteratorHelper(requests),
|
|
126
|
+
_step3;
|
|
127
|
+
try {
|
|
128
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
129
|
+
var request = _step3.value;
|
|
130
|
+
if (request.url !== resolvedUrl || request.appearance !== 'inline' || request.source !== clipboardSource) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
var pos = tr.mapping.map(request.pos, -1);
|
|
134
|
+
if (pos < 0 || pos >= tr.doc.content.size) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
var node = tr.doc.nodeAt(pos);
|
|
138
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) === 'inlineCard' && node.attrs.url === request.url) {
|
|
139
|
+
found.push({
|
|
140
|
+
pos: pos,
|
|
141
|
+
url: request.url
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (err) {
|
|
146
|
+
_iterator3.e(err);
|
|
147
|
+
} finally {
|
|
148
|
+
_iterator3.f();
|
|
149
|
+
}
|
|
150
|
+
return found;
|
|
151
|
+
};
|
|
152
|
+
/** Add candidates unless tracking is off or a link has already been displayed. */
|
|
153
|
+
var withPastedInlineLinks = exports.withPastedInlineLinks = function withPastedInlineLinks(state, additions) {
|
|
154
|
+
if (!state.pastedInlineLinks || state.pastedInlineLinkShown || !additions.length) {
|
|
155
|
+
return state;
|
|
156
|
+
}
|
|
157
|
+
var next = addPastedInlineLinks(state.pastedInlineLinks, additions);
|
|
158
|
+
return next === state.pastedInlineLinks ? state : _objectSpread(_objectSpread({}, state), {}, {
|
|
159
|
+
pastedInlineLinks: next
|
|
160
|
+
});
|
|
161
|
+
};
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.getPluginStateWithUpdatedPos = exports.getPluginState = exports.getNewRequests = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _pluginKey = require("../plugin-key");
|
|
10
|
+
var _pastedInlineLink = require("./pasted-inline-link");
|
|
10
11
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
12
|
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) { (0, _defineProperty2.default)(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; }
|
|
12
13
|
// ============================================================================ //
|
|
@@ -19,7 +20,9 @@ var getPluginState = exports.getPluginState = function getPluginState(editorStat
|
|
|
19
20
|
};
|
|
20
21
|
var getPluginStateWithUpdatedPos = exports.getPluginStateWithUpdatedPos = function getPluginStateWithUpdatedPos(pluginState, tr) {
|
|
21
22
|
var _pluginState$resolved;
|
|
22
|
-
return _objectSpread(_objectSpread({}, pluginState),
|
|
23
|
+
return _objectSpread(_objectSpread(_objectSpread({}, pluginState), pluginState.pastedInlineLinks ? {
|
|
24
|
+
pastedInlineLinks: (0, _pastedInlineLink.mapPastedInlineLinks)(pluginState.pastedInlineLinks, tr)
|
|
25
|
+
} : {}), {}, {
|
|
23
26
|
requests: pluginState.requests.map(function (request) {
|
|
24
27
|
return _objectSpread(_objectSpread({}, request), {}, {
|
|
25
28
|
pos: tr.mapping.map(request.pos)
|
|
@@ -12,7 +12,7 @@ import { createCardRegistry } from './actions/cardRegistry';
|
|
|
12
12
|
import { blockCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/blockCard';
|
|
13
13
|
import { embedCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/embedCard';
|
|
14
14
|
import { inlineCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/inlineCard';
|
|
15
|
-
import { hideLinkToolbar, setProvider, showDatasourceModal } from './pm-plugins/actions';
|
|
15
|
+
import { clearPastedInlineLink, markPastedInlineLinkShown, hideLinkToolbar, setProvider, showDatasourceModal } from './pm-plugins/actions';
|
|
16
16
|
import { queueCardsFromChangedTr, queueCardsFromRange } from './pm-plugins/doc';
|
|
17
17
|
import { cardKeymap } from './pm-plugins/keymap';
|
|
18
18
|
import { createPlugin } from './pm-plugins/main';
|
|
@@ -199,6 +199,12 @@ export const cardPlugin = ({
|
|
|
199
199
|
}));
|
|
200
200
|
},
|
|
201
201
|
commands: {
|
|
202
|
+
markPastedInlineLinkShown: target => ({
|
|
203
|
+
tr
|
|
204
|
+
}) => options.trackPastedInlineLinks ? markPastedInlineLinkShown(target)(tr) : null,
|
|
205
|
+
clearPastedInlineLink: target => ({
|
|
206
|
+
tr
|
|
207
|
+
}) => options.trackPastedInlineLinks ? clearPastedInlineLink(target)(tr) : null,
|
|
202
208
|
queueCardsFromRange: (from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance) => ({
|
|
203
209
|
tr
|
|
204
210
|
}) => queueCardsFromRange(
|
|
@@ -75,4 +75,16 @@ export const setDatasourceStash = (tr, datasourceStash) => cardAction(tr, {
|
|
|
75
75
|
export const removeDatasourceStash = (tr, url) => cardAction(tr, {
|
|
76
76
|
type: 'REMOVE_DATASOURCE_STASH',
|
|
77
77
|
url
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/** Confirm actual display, not merely target selection or a request to display. */
|
|
81
|
+
export const markPastedInlineLinkShown = target => tr => cardAction(tr, {
|
|
82
|
+
type: 'PASTED_INLINE_LINK_SHOWN',
|
|
83
|
+
target
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/** Discard only this candidate; a stale callback must not clear a newer paste. */
|
|
87
|
+
export const clearPastedInlineLink = target => tr => cardAction(tr, {
|
|
88
|
+
type: 'CLEAR_PASTED_INLINE_LINK',
|
|
89
|
+
target
|
|
78
90
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import rafSchedule from 'raf-schd';
|
|
2
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums';
|
|
2
3
|
import { getInlineNodeViewProducer } from '@atlaskit/editor-common/getInlineNodeViewProducer';
|
|
3
4
|
import { isSSR } from '@atlaskit/editor-common/is-ssr';
|
|
4
5
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
@@ -17,6 +18,7 @@ import { isLocalStorageKeyDiscovered } from '../ui/local-storage';
|
|
|
17
18
|
import { clearOverlayCandidate, setCardLayoutAndDatasourceTableRef, setDatasourceTableRef } from './actions';
|
|
18
19
|
import { pluginKey } from './plugin-key';
|
|
19
20
|
import reducer from './reducers';
|
|
21
|
+
import { getPastedInlineCards, getResolvedPastedInlineCards, withPastedInlineLinks } from './util/pasted-inline-link';
|
|
20
22
|
import { handleProvider, resolveWithProvider } from './util/resolve';
|
|
21
23
|
import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
|
|
22
24
|
import { isBlockSupportedAtPosition, isEmbedSupportedAtPosition } from './utils';
|
|
@@ -44,6 +46,7 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
|
|
|
44
46
|
fullWidthMode,
|
|
45
47
|
actionOptions,
|
|
46
48
|
cardPluginEvents,
|
|
49
|
+
trackPastedInlineLinks,
|
|
47
50
|
showUpgradeDiscoverability,
|
|
48
51
|
allowEmbeds,
|
|
49
52
|
allowBlockCards,
|
|
@@ -79,6 +82,9 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
|
|
|
79
82
|
init() {
|
|
80
83
|
return {
|
|
81
84
|
requests: [],
|
|
85
|
+
...(trackPastedInlineLinks ? {
|
|
86
|
+
pastedInlineLinks: []
|
|
87
|
+
} : {}),
|
|
82
88
|
provider: null,
|
|
83
89
|
cards: [],
|
|
84
90
|
datasourceStash: {},
|
|
@@ -97,7 +103,9 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
|
|
|
97
103
|
var _pluginState$requests, _pluginState$requests2;
|
|
98
104
|
// Update all the positions of outstanding requests and
|
|
99
105
|
// cards in the plugin state.
|
|
100
|
-
|
|
106
|
+
let pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
|
|
107
|
+
// Pasted inline cards that already exist as nodes (copy and paste of cards).
|
|
108
|
+
pluginStateWithUpdatedPos = withPastedInlineLinks(pluginStateWithUpdatedPos, trackPastedInlineLinks ? getPastedInlineCards(tr) : []);
|
|
101
109
|
|
|
102
110
|
// apply any actions
|
|
103
111
|
const meta = tr.getMeta(pluginKey);
|
|
@@ -119,8 +127,7 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
|
|
|
119
127
|
if (!meta) {
|
|
120
128
|
return pluginStateWithUpdatedPos;
|
|
121
129
|
}
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
let newState = reducer(pluginStateWithUpdatedPos, meta);
|
|
124
131
|
// Track the first resolved inline smart link for PO spotlight DOM targeting
|
|
125
132
|
if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length) {
|
|
126
133
|
const resolvedRequest = pluginState.requests.find(req => req.url === meta.url);
|
|
@@ -136,6 +143,11 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
|
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
}
|
|
146
|
+
|
|
147
|
+
// Pasted URLs that were converted to inline cards.
|
|
148
|
+
if (trackPastedInlineLinks && meta.type === 'RESOLVE') {
|
|
149
|
+
newState = withPastedInlineLinks(newState, getResolvedPastedInlineCards(tr, pluginState.requests, meta.url, INPUT_METHOD.CLIPBOARD));
|
|
150
|
+
}
|
|
139
151
|
if (!enableInlineUpgradeFeatures) {
|
|
140
152
|
return newState;
|
|
141
153
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
|
+
import { removePastedInlineLink } from './util/pasted-inline-link';
|
|
2
3
|
const queue = (state, action) => {
|
|
3
4
|
return {
|
|
4
5
|
...state,
|
|
@@ -149,6 +150,18 @@ const removeDatasourceStash = (state, action) => {
|
|
|
149
150
|
};
|
|
150
151
|
export default ((state, action) => {
|
|
151
152
|
switch (action.type) {
|
|
153
|
+
case 'PASTED_INLINE_LINK_SHOWN':
|
|
154
|
+
return state.pastedInlineLinks ? {
|
|
155
|
+
...state,
|
|
156
|
+
pastedInlineLinkShown: true,
|
|
157
|
+
// Keep only the displayed link so it can still be dismissed if it changes.
|
|
158
|
+
pastedInlineLinks: state.pastedInlineLinks.filter(link => link.pos === action.target.pos && link.url === action.target.url)
|
|
159
|
+
} : state;
|
|
160
|
+
case 'CLEAR_PASTED_INLINE_LINK':
|
|
161
|
+
return state.pastedInlineLinks ? {
|
|
162
|
+
...state,
|
|
163
|
+
pastedInlineLinks: removePastedInlineLink(state.pastedInlineLinks, action.target)
|
|
164
|
+
} : state;
|
|
152
165
|
case 'QUEUE':
|
|
153
166
|
return queue(state, action);
|
|
154
167
|
case 'SET_PROVIDER':
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/** Bounds the per-editor work; the first pasted links win. */
|
|
2
|
+
export const MAX_PASTED_INLINE_LINKS = 10;
|
|
3
|
+
const isSameLink = (a, b) => a.pos === b.pos && a.url === b.url;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map candidates through a transaction. Anything that was deleted, replaced by another node or
|
|
7
|
+
* given a different URL stops being a candidate. Returns the same array when nothing changed.
|
|
8
|
+
*/
|
|
9
|
+
export const mapPastedInlineLinks = (links, tr) => {
|
|
10
|
+
if (tr.getMeta('replaceDocument')) {
|
|
11
|
+
return links.length ? [] : links;
|
|
12
|
+
}
|
|
13
|
+
if (!tr.docChanged || !links.length) {
|
|
14
|
+
return links;
|
|
15
|
+
}
|
|
16
|
+
let changed = false;
|
|
17
|
+
const mapped = [];
|
|
18
|
+
for (const link of links) {
|
|
19
|
+
const result = tr.mapping.mapResult(link.pos, 1);
|
|
20
|
+
const node = result.deleted ? null : tr.doc.nodeAt(result.pos);
|
|
21
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) !== 'inlineCard' || node.attrs.url !== link.url) {
|
|
22
|
+
changed = true;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (result.pos !== link.pos) {
|
|
26
|
+
changed = true;
|
|
27
|
+
mapped.push({
|
|
28
|
+
pos: result.pos,
|
|
29
|
+
url: link.url
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
mapped.push(link);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return changed ? mapped : links;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Append new candidates, skipping duplicates and anything beyond the cap. */
|
|
39
|
+
export const addPastedInlineLinks = (links, additions) => {
|
|
40
|
+
let next = links;
|
|
41
|
+
for (const addition of additions) {
|
|
42
|
+
if (next.length >= MAX_PASTED_INLINE_LINKS) {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
if (!next.some(link => isSameLink(link, addition))) {
|
|
46
|
+
next = [...next, addition];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return next;
|
|
50
|
+
};
|
|
51
|
+
export const removePastedInlineLink = (links, target) => {
|
|
52
|
+
const next = links.filter(link => !isSameLink(link, target));
|
|
53
|
+
return next.length === links.length ? links : next;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Inline cards inserted by a paste transaction (copy and paste of existing cards). */
|
|
57
|
+
export const getPastedInlineCards = tr => {
|
|
58
|
+
if (!tr.docChanged || tr.getMeta('uiEvent') !== 'paste' || tr.getMeta('isRemote')) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const found = [];
|
|
62
|
+
tr.mapping.maps.forEach((stepMap, index) => {
|
|
63
|
+
const later = tr.mapping.slice(index + 1);
|
|
64
|
+
stepMap.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
|
|
65
|
+
tr.doc.nodesBetween(later.map(newStart, -1), later.map(newEnd, 1), (node, pos) => {
|
|
66
|
+
if (node.type.name === 'inlineCard' && typeof node.attrs.url === 'string') {
|
|
67
|
+
found.push({
|
|
68
|
+
pos,
|
|
69
|
+
url: node.attrs.url
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
return found;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** Inline cards created from clipboard URLs that just resolved in this transaction. */
|
|
79
|
+
export const getResolvedPastedInlineCards = (tr, requests, resolvedUrl, clipboardSource) => {
|
|
80
|
+
if (tr.getMeta('isRemote')) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const found = [];
|
|
84
|
+
for (const request of requests) {
|
|
85
|
+
if (request.url !== resolvedUrl || request.appearance !== 'inline' || request.source !== clipboardSource) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const pos = tr.mapping.map(request.pos, -1);
|
|
89
|
+
if (pos < 0 || pos >= tr.doc.content.size) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const node = tr.doc.nodeAt(pos);
|
|
93
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) === 'inlineCard' && node.attrs.url === request.url) {
|
|
94
|
+
found.push({
|
|
95
|
+
pos,
|
|
96
|
+
url: request.url
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return found;
|
|
101
|
+
};
|
|
102
|
+
/** Add candidates unless tracking is off or a link has already been displayed. */
|
|
103
|
+
export const withPastedInlineLinks = (state, additions) => {
|
|
104
|
+
if (!state.pastedInlineLinks || state.pastedInlineLinkShown || !additions.length) {
|
|
105
|
+
return state;
|
|
106
|
+
}
|
|
107
|
+
const next = addPastedInlineLinks(state.pastedInlineLinks, additions);
|
|
108
|
+
return next === state.pastedInlineLinks ? state : {
|
|
109
|
+
...state,
|
|
110
|
+
pastedInlineLinks: next
|
|
111
|
+
};
|
|
112
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pluginKey } from '../plugin-key';
|
|
2
|
+
import { mapPastedInlineLinks } from './pasted-inline-link';
|
|
2
3
|
|
|
3
4
|
// ============================================================================ //
|
|
4
5
|
// ============================== PLUGIN STATE ================================ //
|
|
@@ -10,6 +11,9 @@ export const getPluginStateWithUpdatedPos = (pluginState, tr) => {
|
|
|
10
11
|
var _pluginState$resolved;
|
|
11
12
|
return {
|
|
12
13
|
...pluginState,
|
|
14
|
+
...(pluginState.pastedInlineLinks ? {
|
|
15
|
+
pastedInlineLinks: mapPastedInlineLinks(pluginState.pastedInlineLinks, tr)
|
|
16
|
+
} : {}),
|
|
13
17
|
requests: pluginState.requests.map(request => ({
|
|
14
18
|
...request,
|
|
15
19
|
pos: tr.mapping.map(request.pos)
|
package/dist/esm/cardPlugin.js
CHANGED
|
@@ -18,7 +18,7 @@ import { createCardRegistry } from './actions/cardRegistry';
|
|
|
18
18
|
import { blockCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/blockCard';
|
|
19
19
|
import { embedCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/embedCard';
|
|
20
20
|
import { inlineCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/inlineCard';
|
|
21
|
-
import { hideLinkToolbar, setProvider as _setProvider, showDatasourceModal } from './pm-plugins/actions';
|
|
21
|
+
import { clearPastedInlineLink as _clearPastedInlineLink, markPastedInlineLinkShown as _markPastedInlineLinkShown, hideLinkToolbar, setProvider as _setProvider, showDatasourceModal } from './pm-plugins/actions';
|
|
22
22
|
import { queueCardsFromChangedTr, queueCardsFromRange as _queueCardsFromRange } from './pm-plugins/doc';
|
|
23
23
|
import { cardKeymap } from './pm-plugins/keymap';
|
|
24
24
|
import { createPlugin } from './pm-plugins/main';
|
|
@@ -196,9 +196,21 @@ export var cardPlugin = function cardPlugin(_ref2) {
|
|
|
196
196
|
}));
|
|
197
197
|
},
|
|
198
198
|
commands: {
|
|
199
|
-
|
|
199
|
+
markPastedInlineLinkShown: function markPastedInlineLinkShown(target) {
|
|
200
200
|
return function (_ref6) {
|
|
201
201
|
var tr = _ref6.tr;
|
|
202
|
+
return options.trackPastedInlineLinks ? _markPastedInlineLinkShown(target)(tr) : null;
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
clearPastedInlineLink: function clearPastedInlineLink(target) {
|
|
206
|
+
return function (_ref7) {
|
|
207
|
+
var tr = _ref7.tr;
|
|
208
|
+
return options.trackPastedInlineLinks ? _clearPastedInlineLink(target)(tr) : null;
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
queueCardsFromRange: function queueCardsFromRange(from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance) {
|
|
212
|
+
return function (_ref8) {
|
|
213
|
+
var tr = _ref8.tr;
|
|
202
214
|
return _queueCardsFromRange(
|
|
203
215
|
// Synthesise the minimal EditorState shape the impl actually reads.
|
|
204
216
|
{
|
|
@@ -231,8 +243,8 @@ export var cardPlugin = function cardPlugin(_ref2) {
|
|
|
231
243
|
return _context.abrupt("return", false);
|
|
232
244
|
case 2:
|
|
233
245
|
previousCardProvider = provider;
|
|
234
|
-
return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (
|
|
235
|
-
var tr =
|
|
246
|
+
return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref9) {
|
|
247
|
+
var tr = _ref9.tr;
|
|
236
248
|
return _setProvider(provider)(tr);
|
|
237
249
|
})) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false);
|
|
238
250
|
case 3:
|
|
@@ -341,8 +353,8 @@ export var cardPlugin = function cardPlugin(_ref2) {
|
|
|
341
353
|
pluginsOptions: _objectSpread({
|
|
342
354
|
floatingToolbar: floatingToolbar(options, (_options$lpLinkPicker = options.lpLinkPicker) !== null && _options$lpLinkPicker !== void 0 ? _options$lpLinkPicker : false, options.linkPicker, api, options.disableFloatingToolbar)
|
|
343
355
|
}, isRegisteredSlashCommandEnabled ? {} : {
|
|
344
|
-
quickInsert: function quickInsert(
|
|
345
|
-
var formatMessage =
|
|
356
|
+
quickInsert: function quickInsert(_ref0) {
|
|
357
|
+
var formatMessage = _ref0.formatMessage;
|
|
346
358
|
var quickInsertArray = [];
|
|
347
359
|
if (!options.allowDatasource) {
|
|
348
360
|
return quickInsertArray;
|
|
@@ -134,4 +134,24 @@ export var removeDatasourceStash = function removeDatasourceStash(tr, url) {
|
|
|
134
134
|
type: 'REMOVE_DATASOURCE_STASH',
|
|
135
135
|
url: url
|
|
136
136
|
});
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/** Confirm actual display, not merely target selection or a request to display. */
|
|
140
|
+
export var markPastedInlineLinkShown = function markPastedInlineLinkShown(target) {
|
|
141
|
+
return function (tr) {
|
|
142
|
+
return cardAction(tr, {
|
|
143
|
+
type: 'PASTED_INLINE_LINK_SHOWN',
|
|
144
|
+
target: target
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/** Discard only this candidate; a stale callback must not clear a newer paste. */
|
|
150
|
+
export var clearPastedInlineLink = function clearPastedInlineLink(target) {
|
|
151
|
+
return function (tr) {
|
|
152
|
+
return cardAction(tr, {
|
|
153
|
+
type: 'CLEAR_PASTED_INLINE_LINK',
|
|
154
|
+
target: target
|
|
155
|
+
});
|
|
156
|
+
};
|
|
137
157
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
3
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
4
|
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; }
|
|
5
5
|
import rafSchedule from 'raf-schd';
|
|
6
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums';
|
|
6
7
|
import { getInlineNodeViewProducer } from '@atlaskit/editor-common/getInlineNodeViewProducer';
|
|
7
8
|
import { isSSR } from '@atlaskit/editor-common/is-ssr';
|
|
8
9
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
@@ -21,6 +22,7 @@ import { isLocalStorageKeyDiscovered } from '../ui/local-storage';
|
|
|
21
22
|
import { clearOverlayCandidate, setCardLayoutAndDatasourceTableRef, setDatasourceTableRef } from './actions';
|
|
22
23
|
import { pluginKey } from './plugin-key';
|
|
23
24
|
import reducer from './reducers';
|
|
25
|
+
import { getPastedInlineCards, getResolvedPastedInlineCards, withPastedInlineLinks } from './util/pasted-inline-link';
|
|
24
26
|
import { handleProvider, resolveWithProvider } from './util/resolve';
|
|
25
27
|
import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
|
|
26
28
|
import { isBlockSupportedAtPosition, isEmbedSupportedAtPosition } from './utils';
|
|
@@ -48,6 +50,7 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
|
|
|
48
50
|
fullWidthMode = options.fullWidthMode,
|
|
49
51
|
actionOptions = options.actionOptions,
|
|
50
52
|
cardPluginEvents = options.cardPluginEvents,
|
|
53
|
+
trackPastedInlineLinks = options.trackPastedInlineLinks,
|
|
51
54
|
showUpgradeDiscoverability = options.showUpgradeDiscoverability,
|
|
52
55
|
allowEmbeds = options.allowEmbeds,
|
|
53
56
|
allowBlockCards = options.allowBlockCards,
|
|
@@ -80,8 +83,11 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
|
|
|
80
83
|
return new SafePlugin({
|
|
81
84
|
state: {
|
|
82
85
|
init: function init() {
|
|
83
|
-
return {
|
|
84
|
-
requests: []
|
|
86
|
+
return _objectSpread(_objectSpread({
|
|
87
|
+
requests: []
|
|
88
|
+
}, trackPastedInlineLinks ? {
|
|
89
|
+
pastedInlineLinks: []
|
|
90
|
+
} : {}), {}, {
|
|
85
91
|
provider: null,
|
|
86
92
|
cards: [],
|
|
87
93
|
datasourceStash: {},
|
|
@@ -94,13 +100,15 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
|
|
|
94
100
|
datasourceModalType: undefined,
|
|
95
101
|
datasourceTableRef: undefined,
|
|
96
102
|
layout: undefined
|
|
97
|
-
};
|
|
103
|
+
});
|
|
98
104
|
},
|
|
99
105
|
apply: function apply(tr, pluginState, prevEditorState) {
|
|
100
106
|
var _pluginState$requests, _pluginState$requests2;
|
|
101
107
|
// Update all the positions of outstanding requests and
|
|
102
108
|
// cards in the plugin state.
|
|
103
109
|
var pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
|
|
110
|
+
// Pasted inline cards that already exist as nodes (copy and paste of cards).
|
|
111
|
+
pluginStateWithUpdatedPos = withPastedInlineLinks(pluginStateWithUpdatedPos, trackPastedInlineLinks ? getPastedInlineCards(tr) : []);
|
|
104
112
|
|
|
105
113
|
// apply any actions
|
|
106
114
|
var meta = tr.getMeta(pluginKey);
|
|
@@ -122,7 +130,6 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
|
|
|
122
130
|
return pluginStateWithUpdatedPos;
|
|
123
131
|
}
|
|
124
132
|
var newState = reducer(pluginStateWithUpdatedPos, meta);
|
|
125
|
-
|
|
126
133
|
// Track the first resolved inline smart link for PO spotlight DOM targeting
|
|
127
134
|
if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length) {
|
|
128
135
|
var resolvedRequest = pluginState.requests.find(function (req) {
|
|
@@ -140,6 +147,11 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
|
|
|
140
147
|
}
|
|
141
148
|
}
|
|
142
149
|
}
|
|
150
|
+
|
|
151
|
+
// Pasted URLs that were converted to inline cards.
|
|
152
|
+
if (trackPastedInlineLinks && meta.type === 'RESOLVE') {
|
|
153
|
+
newState = withPastedInlineLinks(newState, getResolvedPastedInlineCards(tr, pluginState.requests, meta.url, INPUT_METHOD.CLIPBOARD));
|
|
154
|
+
}
|
|
143
155
|
if (!enableInlineUpgradeFeatures) {
|
|
144
156
|
return newState;
|
|
145
157
|
}
|
|
@@ -6,6 +6,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
6
6
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
7
7
|
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; }
|
|
8
8
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
|
+
import { removePastedInlineLink } from './util/pasted-inline-link';
|
|
9
10
|
var queue = function queue(state, action) {
|
|
10
11
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
11
12
|
requests: state.requests.concat(action.requests)
|
|
@@ -134,6 +135,18 @@ var removeDatasourceStash = function removeDatasourceStash(state, action) {
|
|
|
134
135
|
};
|
|
135
136
|
export default (function (state, action) {
|
|
136
137
|
switch (action.type) {
|
|
138
|
+
case 'PASTED_INLINE_LINK_SHOWN':
|
|
139
|
+
return state.pastedInlineLinks ? _objectSpread(_objectSpread({}, state), {}, {
|
|
140
|
+
pastedInlineLinkShown: true,
|
|
141
|
+
// Keep only the displayed link so it can still be dismissed if it changes.
|
|
142
|
+
pastedInlineLinks: state.pastedInlineLinks.filter(function (link) {
|
|
143
|
+
return link.pos === action.target.pos && link.url === action.target.url;
|
|
144
|
+
})
|
|
145
|
+
}) : state;
|
|
146
|
+
case 'CLEAR_PASTED_INLINE_LINK':
|
|
147
|
+
return state.pastedInlineLinks ? _objectSpread(_objectSpread({}, state), {}, {
|
|
148
|
+
pastedInlineLinks: removePastedInlineLink(state.pastedInlineLinks, action.target)
|
|
149
|
+
}) : state;
|
|
137
150
|
case 'QUEUE':
|
|
138
151
|
return queue(state, action);
|
|
139
152
|
case 'SET_PROVIDER':
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
+
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; }
|
|
5
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
6
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
7
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
8
|
+
/** Bounds the per-editor work; the first pasted links win. */
|
|
9
|
+
export var MAX_PASTED_INLINE_LINKS = 10;
|
|
10
|
+
var isSameLink = function isSameLink(a, b) {
|
|
11
|
+
return a.pos === b.pos && a.url === b.url;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Map candidates through a transaction. Anything that was deleted, replaced by another node or
|
|
16
|
+
* given a different URL stops being a candidate. Returns the same array when nothing changed.
|
|
17
|
+
*/
|
|
18
|
+
export var mapPastedInlineLinks = function mapPastedInlineLinks(links, tr) {
|
|
19
|
+
if (tr.getMeta('replaceDocument')) {
|
|
20
|
+
return links.length ? [] : links;
|
|
21
|
+
}
|
|
22
|
+
if (!tr.docChanged || !links.length) {
|
|
23
|
+
return links;
|
|
24
|
+
}
|
|
25
|
+
var changed = false;
|
|
26
|
+
var mapped = [];
|
|
27
|
+
var _iterator = _createForOfIteratorHelper(links),
|
|
28
|
+
_step;
|
|
29
|
+
try {
|
|
30
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
31
|
+
var link = _step.value;
|
|
32
|
+
var result = tr.mapping.mapResult(link.pos, 1);
|
|
33
|
+
var node = result.deleted ? null : tr.doc.nodeAt(result.pos);
|
|
34
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) !== 'inlineCard' || node.attrs.url !== link.url) {
|
|
35
|
+
changed = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (result.pos !== link.pos) {
|
|
39
|
+
changed = true;
|
|
40
|
+
mapped.push({
|
|
41
|
+
pos: result.pos,
|
|
42
|
+
url: link.url
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
mapped.push(link);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch (err) {
|
|
49
|
+
_iterator.e(err);
|
|
50
|
+
} finally {
|
|
51
|
+
_iterator.f();
|
|
52
|
+
}
|
|
53
|
+
return changed ? mapped : links;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Append new candidates, skipping duplicates and anything beyond the cap. */
|
|
57
|
+
export var addPastedInlineLinks = function addPastedInlineLinks(links, additions) {
|
|
58
|
+
var next = links;
|
|
59
|
+
var _iterator2 = _createForOfIteratorHelper(additions),
|
|
60
|
+
_step2;
|
|
61
|
+
try {
|
|
62
|
+
var _loop = function _loop() {
|
|
63
|
+
var addition = _step2.value;
|
|
64
|
+
if (next.length >= MAX_PASTED_INLINE_LINKS) {
|
|
65
|
+
return 1; // break
|
|
66
|
+
}
|
|
67
|
+
if (!next.some(function (link) {
|
|
68
|
+
return isSameLink(link, addition);
|
|
69
|
+
})) {
|
|
70
|
+
next = [].concat(_toConsumableArray(next), [addition]);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
74
|
+
if (_loop()) break;
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
_iterator2.e(err);
|
|
78
|
+
} finally {
|
|
79
|
+
_iterator2.f();
|
|
80
|
+
}
|
|
81
|
+
return next;
|
|
82
|
+
};
|
|
83
|
+
export var removePastedInlineLink = function removePastedInlineLink(links, target) {
|
|
84
|
+
var next = links.filter(function (link) {
|
|
85
|
+
return !isSameLink(link, target);
|
|
86
|
+
});
|
|
87
|
+
return next.length === links.length ? links : next;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/** Inline cards inserted by a paste transaction (copy and paste of existing cards). */
|
|
91
|
+
export var getPastedInlineCards = function getPastedInlineCards(tr) {
|
|
92
|
+
if (!tr.docChanged || tr.getMeta('uiEvent') !== 'paste' || tr.getMeta('isRemote')) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
var found = [];
|
|
96
|
+
tr.mapping.maps.forEach(function (stepMap, index) {
|
|
97
|
+
var later = tr.mapping.slice(index + 1);
|
|
98
|
+
stepMap.forEach(function (_oldStart, _oldEnd, newStart, newEnd) {
|
|
99
|
+
tr.doc.nodesBetween(later.map(newStart, -1), later.map(newEnd, 1), function (node, pos) {
|
|
100
|
+
if (node.type.name === 'inlineCard' && typeof node.attrs.url === 'string') {
|
|
101
|
+
found.push({
|
|
102
|
+
pos: pos,
|
|
103
|
+
url: node.attrs.url
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
return found;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/** Inline cards created from clipboard URLs that just resolved in this transaction. */
|
|
113
|
+
export var getResolvedPastedInlineCards = function getResolvedPastedInlineCards(tr, requests, resolvedUrl, clipboardSource) {
|
|
114
|
+
if (tr.getMeta('isRemote')) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
var found = [];
|
|
118
|
+
var _iterator3 = _createForOfIteratorHelper(requests),
|
|
119
|
+
_step3;
|
|
120
|
+
try {
|
|
121
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
122
|
+
var request = _step3.value;
|
|
123
|
+
if (request.url !== resolvedUrl || request.appearance !== 'inline' || request.source !== clipboardSource) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
var pos = tr.mapping.map(request.pos, -1);
|
|
127
|
+
if (pos < 0 || pos >= tr.doc.content.size) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
var node = tr.doc.nodeAt(pos);
|
|
131
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) === 'inlineCard' && node.attrs.url === request.url) {
|
|
132
|
+
found.push({
|
|
133
|
+
pos: pos,
|
|
134
|
+
url: request.url
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
_iterator3.e(err);
|
|
140
|
+
} finally {
|
|
141
|
+
_iterator3.f();
|
|
142
|
+
}
|
|
143
|
+
return found;
|
|
144
|
+
};
|
|
145
|
+
/** Add candidates unless tracking is off or a link has already been displayed. */
|
|
146
|
+
export var withPastedInlineLinks = function withPastedInlineLinks(state, additions) {
|
|
147
|
+
if (!state.pastedInlineLinks || state.pastedInlineLinkShown || !additions.length) {
|
|
148
|
+
return state;
|
|
149
|
+
}
|
|
150
|
+
var next = addPastedInlineLinks(state.pastedInlineLinks, additions);
|
|
151
|
+
return next === state.pastedInlineLinks ? state : _objectSpread(_objectSpread({}, state), {}, {
|
|
152
|
+
pastedInlineLinks: next
|
|
153
|
+
});
|
|
154
|
+
};
|
|
@@ -2,6 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
3
|
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; }
|
|
4
4
|
import { pluginKey } from '../plugin-key';
|
|
5
|
+
import { mapPastedInlineLinks } from './pasted-inline-link';
|
|
5
6
|
|
|
6
7
|
// ============================================================================ //
|
|
7
8
|
// ============================== PLUGIN STATE ================================ //
|
|
@@ -13,7 +14,9 @@ export var getPluginState = function getPluginState(editorState) {
|
|
|
13
14
|
};
|
|
14
15
|
export var getPluginStateWithUpdatedPos = function getPluginStateWithUpdatedPos(pluginState, tr) {
|
|
15
16
|
var _pluginState$resolved;
|
|
16
|
-
return _objectSpread(_objectSpread({}, pluginState),
|
|
17
|
+
return _objectSpread(_objectSpread(_objectSpread({}, pluginState), pluginState.pastedInlineLinks ? {
|
|
18
|
+
pastedInlineLinks: mapPastedInlineLinks(pluginState.pastedInlineLinks, tr)
|
|
19
|
+
} : {}), {}, {
|
|
17
20
|
requests: pluginState.requests.map(function (request) {
|
|
18
21
|
return _objectSpread(_objectSpread({}, request), {}, {
|
|
19
22
|
pos: tr.mapping.map(request.pos)
|
|
@@ -20,7 +20,7 @@ import type { ToolbarPlugin } from '@atlaskit/editor-plugin-toolbar/toolbar-plug
|
|
|
20
20
|
import type { UiControlRegistryPlugin } from '@atlaskit/editor-plugin-ui-control-registry/ui-control-registry-plugin-type';
|
|
21
21
|
import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent/user-intent-plugin-type';
|
|
22
22
|
import type { WidthPlugin } from '@atlaskit/editor-plugin-width/width-plugin-type';
|
|
23
|
-
import type { CardPluginOptions, CardPluginState } from './types';
|
|
23
|
+
import type { CardPluginOptions, CardPluginState, PastedInlineLink } from './types';
|
|
24
24
|
type DummyAnnotationPlugin = NextEditorPlugin<'annotation', {
|
|
25
25
|
actions: {
|
|
26
26
|
setInlineCommentDraftState: (isDraft: boolean, inputMethod: INPUT_METHOD) => Command;
|
|
@@ -47,6 +47,10 @@ export type CardPluginDependencies = [
|
|
|
47
47
|
export type CardPlugin = NextEditorPlugin<'card', {
|
|
48
48
|
actions: CardPluginActions;
|
|
49
49
|
commands: {
|
|
50
|
+
/** Stop tracking a pasted link, for example one the consumer found ineligible. */
|
|
51
|
+
clearPastedInlineLink: (target: PastedInlineLink) => EditorCommand;
|
|
52
|
+
/** Confirm that the consumer displayed the message for this pasted link. */
|
|
53
|
+
markPastedInlineLinkShown: (target: PastedInlineLink) => EditorCommand;
|
|
50
54
|
/** EditorCommand form of `queueCardsFromRange`. Prefer over the action. */
|
|
51
55
|
queueCardsFromRange: (from: number, to: number, source: CardReplacementInputMethod, analyticsAction?: ACTION, normalizeLinkText?: boolean, sourceEvent?: UIAnalyticsEvent | null, appearance?: CardAppearance) => EditorCommand;
|
|
52
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { Request, CardPluginOptions, CardPluginState } from '../types/index';
|
|
1
|
+
export type { Request, CardPluginOptions, CardPluginState, PastedInlineLink } from '../types/index';
|
|
@@ -3,7 +3,7 @@ import type { DatasourceModalType } from '@atlaskit/editor-common/types/datasour
|
|
|
3
3
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import type { DatasourceAdfView } from '@atlaskit/linking-common/types';
|
|
5
5
|
import type { SmartLinkEvents } from '@atlaskit/smart-card/smart-link-events';
|
|
6
|
-
import type { CardInfo, CardPluginAction, Request, ToolbarResolvedAttributes } from '../types';
|
|
6
|
+
import type { CardInfo, CardPluginAction, PastedInlineLink, Request, ToolbarResolvedAttributes } from '../types';
|
|
7
7
|
import type { DatasourceTableLayout } from '../ui/LayoutButton/types';
|
|
8
8
|
export declare const cardAction: (tr: Transaction, action: CardPluginAction) => Transaction;
|
|
9
9
|
export declare const resolveCard: (url: string) => (tr: Transaction) => Transaction;
|
|
@@ -30,3 +30,7 @@ export declare const setDatasourceStash: (tr: Transaction, datasourceStash: {
|
|
|
30
30
|
views: DatasourceAdfView[];
|
|
31
31
|
}) => Transaction;
|
|
32
32
|
export declare const removeDatasourceStash: (tr: Transaction, url: string) => Transaction;
|
|
33
|
+
/** Confirm actual display, not merely target selection or a request to display. */
|
|
34
|
+
export declare const markPastedInlineLinkShown: (target: PastedInlineLink) => (tr: Transaction) => Transaction;
|
|
35
|
+
/** Discard only this candidate; a stale callback must not clear a newer paste. */
|
|
36
|
+
export declare const clearPastedInlineLink: (target: PastedInlineLink) => (tr: Transaction) => Transaction;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import type { PastedInlineLink } from '../../types';
|
|
3
|
+
/** Bounds the per-editor work; the first pasted links win. */
|
|
4
|
+
export declare const MAX_PASTED_INLINE_LINKS = 10;
|
|
5
|
+
/**
|
|
6
|
+
* Map candidates through a transaction. Anything that was deleted, replaced by another node or
|
|
7
|
+
* given a different URL stops being a candidate. Returns the same array when nothing changed.
|
|
8
|
+
*/
|
|
9
|
+
export declare const mapPastedInlineLinks: (links: PastedInlineLink[], tr: ReadonlyTransaction | Transaction) => PastedInlineLink[];
|
|
10
|
+
/** Append new candidates, skipping duplicates and anything beyond the cap. */
|
|
11
|
+
export declare const addPastedInlineLinks: (links: PastedInlineLink[], additions: PastedInlineLink[]) => PastedInlineLink[];
|
|
12
|
+
export declare const removePastedInlineLink: (links: PastedInlineLink[], target: PastedInlineLink) => PastedInlineLink[];
|
|
13
|
+
/** Inline cards inserted by a paste transaction (copy and paste of existing cards). */
|
|
14
|
+
export declare const getPastedInlineCards: (tr: ReadonlyTransaction | Transaction) => PastedInlineLink[];
|
|
15
|
+
/** Inline cards created from clipboard URLs that just resolved in this transaction. */
|
|
16
|
+
export declare const getResolvedPastedInlineCards: (tr: ReadonlyTransaction | Transaction, requests: Array<{
|
|
17
|
+
appearance?: string;
|
|
18
|
+
pos: number;
|
|
19
|
+
source?: string;
|
|
20
|
+
url: string;
|
|
21
|
+
}>, resolvedUrl: string, clipboardSource: string) => PastedInlineLink[];
|
|
22
|
+
type PastedInlineLinkState = {
|
|
23
|
+
pastedInlineLinks?: PastedInlineLink[];
|
|
24
|
+
pastedInlineLinkShown?: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** Add candidates unless tracking is off or a link has already been displayed. */
|
|
27
|
+
export declare const withPastedInlineLinks: <State extends PastedInlineLinkState>(state: State, additions: PastedInlineLink[]) => State;
|
|
28
|
+
export {};
|
|
@@ -4,13 +4,13 @@ import type { CardReplacementInputMethod } from '@atlaskit/editor-common/card/ty
|
|
|
4
4
|
import type { CardAppearance, CardProvider } from '@atlaskit/editor-common/provider-factory/card-provider';
|
|
5
5
|
import type { DatasourceModalType } from '@atlaskit/editor-common/types/datasource';
|
|
6
6
|
import type { EditorAppearance } from '@atlaskit/editor-common/types/editor-appearance';
|
|
7
|
-
import type { EditorState, ReadonlyTransaction } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
import type { EditorState, ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
8
8
|
import type { DatasourceAdfView } from '@atlaskit/linking-common/types';
|
|
9
9
|
import type { SmartLinkEvents } from '@atlaskit/smart-card/smart-link-events';
|
|
10
|
-
import type { CardPluginState, Request, ToolbarResolvedAttributes } from '../../types';
|
|
10
|
+
import type { CardPluginState, Request, ToolbarResolvedAttributes, PastedInlineLink } from '../../types';
|
|
11
11
|
import type { DatasourceTableLayout } from '../../ui/LayoutButton/types';
|
|
12
12
|
export declare const getPluginState: (editorState: EditorState) => CardPluginState | undefined;
|
|
13
|
-
export declare const getPluginStateWithUpdatedPos: (pluginState: CardPluginState, tr: ReadonlyTransaction) => {
|
|
13
|
+
export declare const getPluginStateWithUpdatedPos: (pluginState: CardPluginState, tr: ReadonlyTransaction | Transaction) => {
|
|
14
14
|
allowBlockCards?: boolean;
|
|
15
15
|
allowEmbeds?: boolean;
|
|
16
16
|
cards: {
|
|
@@ -30,6 +30,8 @@ export declare const getPluginStateWithUpdatedPos: (pluginState: CardPluginState
|
|
|
30
30
|
inlineCardAwarenessCandidatePosition?: number;
|
|
31
31
|
layout?: DatasourceTableLayout;
|
|
32
32
|
overlayCandidatePosition?: number;
|
|
33
|
+
pastedInlineLinks?: PastedInlineLink[];
|
|
34
|
+
pastedInlineLinkShown?: boolean;
|
|
33
35
|
provider: CardProvider | null;
|
|
34
36
|
removeOverlay?: () => void;
|
|
35
37
|
removeOverlayCardId?: string;
|
|
@@ -90,6 +90,11 @@ export type Request = {
|
|
|
90
90
|
type DatasourceStash = Record<string, {
|
|
91
91
|
views: DatasourceAdfView[];
|
|
92
92
|
}>;
|
|
93
|
+
/** The single eligible locally pasted inline link selected for a product nudge. */
|
|
94
|
+
export type PastedInlineLink = {
|
|
95
|
+
pos: number;
|
|
96
|
+
url: string;
|
|
97
|
+
};
|
|
93
98
|
export type CardPluginState = {
|
|
94
99
|
allowBlockCards?: boolean;
|
|
95
100
|
allowEmbeds?: boolean;
|
|
@@ -102,6 +107,13 @@ export type CardPluginState = {
|
|
|
102
107
|
inlineCardAwarenessCandidatePosition?: number;
|
|
103
108
|
layout?: DatasourceTableLayout;
|
|
104
109
|
overlayCandidatePosition?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Locally pasted inline links, mapped through edits. Defined only when `trackPastedInlineLinks`
|
|
112
|
+
* is on. Once the consumer confirms display this holds only the displayed link.
|
|
113
|
+
*/
|
|
114
|
+
pastedInlineLinks?: PastedInlineLink[];
|
|
115
|
+
/** Permanently stop adding candidates after the consumer confirms actual display. */
|
|
116
|
+
pastedInlineLinkShown?: boolean;
|
|
105
117
|
provider: CardProvider | null;
|
|
106
118
|
removeOverlay?: () => void;
|
|
107
119
|
removeOverlayCardId?: string;
|
|
@@ -133,6 +145,8 @@ export type CardPluginOptions = CardOptions & {
|
|
|
133
145
|
lpLinkPicker?: boolean;
|
|
134
146
|
onClickCallback?: OnClickCallback;
|
|
135
147
|
smartCardContext?: CardContext;
|
|
148
|
+
/** Opt in to tracking locally pasted inline links in plugin state. */
|
|
149
|
+
trackPastedInlineLinks?: boolean;
|
|
136
150
|
};
|
|
137
151
|
export type SetProvider = {
|
|
138
152
|
provider: CardProvider | null;
|
|
@@ -208,5 +222,11 @@ export type RemoveDatasourceStash = {
|
|
|
208
222
|
type: 'REMOVE_DATASOURCE_STASH';
|
|
209
223
|
url: string;
|
|
210
224
|
};
|
|
211
|
-
export type CardPluginAction =
|
|
225
|
+
export type CardPluginAction = {
|
|
226
|
+
target: PastedInlineLink;
|
|
227
|
+
type: 'PASTED_INLINE_LINK_SHOWN';
|
|
228
|
+
} | {
|
|
229
|
+
target: PastedInlineLink;
|
|
230
|
+
type: 'CLEAR_PASTED_INLINE_LINK';
|
|
231
|
+
} | SetProvider | Queue | Resolve | Register | RemoveCard | ShowLinkToolbar | HideLinkToolbar | ShowDatasourceModal | HideDatasourceModal | RegisterSmartCardEvents | SetDatasourceTableRef | SetResolvedToolbarAttributes | SetCardLayout | SetCardLayoutAndDatasourceTableRef | ClearOverlayCandidate | RegisterRemoveOverlayOnInsertedLink | SetDatasourceStash | RemoveDatasourceStash;
|
|
212
232
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-card",
|
|
3
|
-
"version": "35.
|
|
3
|
+
"version": "35.2.0",
|
|
4
4
|
"description": "Card plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@atlaskit/custom-steps": "^1.1.0",
|
|
29
29
|
"@atlaskit/editor-card-provider": "^8.2.0",
|
|
30
30
|
"@atlaskit/editor-plugin-analytics": "^29.0.0",
|
|
31
|
-
"@atlaskit/editor-plugin-annotation": "^29.
|
|
31
|
+
"@atlaskit/editor-plugin-annotation": "^29.1.0",
|
|
32
32
|
"@atlaskit/editor-plugin-base": "^30.0.0",
|
|
33
33
|
"@atlaskit/editor-plugin-connectivity": "^29.0.0",
|
|
34
34
|
"@atlaskit/editor-plugin-decorations": "^29.0.0",
|