@atlaskit/editor-plugin-block-controls 3.15.10 → 3.15.12
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 +19 -0
- package/dist/cjs/pm-plugins/decorations-drag-handle.js +29 -11
- package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +51 -9
- package/dist/cjs/pm-plugins/quick-insert-calculate-position.js +70 -0
- package/dist/cjs/pm-plugins/vanilla-quick-insert.js +190 -0
- package/dist/cjs/pm-plugins/vanilla-tooltip.js +179 -0
- package/dist/cjs/ui/global-styles.js +86 -1
- package/dist/es2019/pm-plugins/decorations-drag-handle.js +29 -11
- package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +51 -9
- package/dist/es2019/pm-plugins/quick-insert-calculate-position.js +64 -0
- package/dist/es2019/pm-plugins/vanilla-quick-insert.js +189 -0
- package/dist/es2019/pm-plugins/vanilla-tooltip.js +147 -0
- package/dist/es2019/ui/global-styles.js +84 -1
- package/dist/esm/pm-plugins/decorations-drag-handle.js +29 -11
- package/dist/esm/pm-plugins/decorations-quick-insert-button.js +51 -9
- package/dist/esm/pm-plugins/quick-insert-calculate-position.js +64 -0
- package/dist/esm/pm-plugins/vanilla-quick-insert.js +183 -0
- package/dist/esm/pm-plugins/vanilla-tooltip.js +172 -0
- package/dist/esm/ui/global-styles.js +86 -1
- package/dist/types/pm-plugins/quick-insert-calculate-position.d.ts +12 -0
- package/dist/types/pm-plugins/vanilla-quick-insert.d.ts +21 -0
- package/dist/types/pm-plugins/vanilla-tooltip.d.ts +27 -0
- package/dist/types-ts4.5/pm-plugins/quick-insert-calculate-position.d.ts +12 -0
- package/dist/types-ts4.5/pm-plugins/vanilla-quick-insert.d.ts +21 -0
- package/dist/types-ts4.5/pm-plugins/vanilla-tooltip.d.ts +27 -0
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 3.15.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#162142](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/162142)
|
|
8
|
+
[`b92367d4d728b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b92367d4d728b) -
|
|
9
|
+
Migrating the quick insert decoration button to vanilla javascript to improve performance
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 3.15.11
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#166480](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/166480)
|
|
17
|
+
[`55d4dbd11d97d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/55d4dbd11d97d) -
|
|
18
|
+
Add 'marks: []' to both widgets to ensure PM renders them at the top level document, not inside
|
|
19
|
+
sibling elements wrapped with marks
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 3.15.10
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -37,6 +37,34 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
|
|
|
37
37
|
}
|
|
38
38
|
var unbind;
|
|
39
39
|
var key = (0, _uuid.default)();
|
|
40
|
+
var widgetSpec = (0, _experiments.editorExperiment)('platform_editor_breakout_resizing', true) ? {
|
|
41
|
+
side: -1,
|
|
42
|
+
type: _decorationsCommon.TYPE_HANDLE_DEC,
|
|
43
|
+
testid: "".concat(_decorationsCommon.TYPE_HANDLE_DEC, "-").concat((0, _uuid.default)()),
|
|
44
|
+
/**
|
|
45
|
+
* sigh - `marks` influences the position that the widget is drawn (as described on the `side` property).
|
|
46
|
+
* Leaving this 'undefined' causes the widget to be wrapped in the mark before this position which creates
|
|
47
|
+
* weird stacking context issues. Providing an empty array causes the widget to correctly render before
|
|
48
|
+
* this exact position at the top of the DOM.
|
|
49
|
+
*/
|
|
50
|
+
marks: [],
|
|
51
|
+
destroy: function destroy(node) {
|
|
52
|
+
unbind && unbind();
|
|
53
|
+
if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true) && node instanceof HTMLElement) {
|
|
54
|
+
_reactDom.default.unmountComponentAtNode(node);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} : {
|
|
58
|
+
side: -1,
|
|
59
|
+
type: _decorationsCommon.TYPE_HANDLE_DEC,
|
|
60
|
+
testid: "".concat(_decorationsCommon.TYPE_HANDLE_DEC, "-").concat((0, _uuid.default)()),
|
|
61
|
+
destroy: function destroy(node) {
|
|
62
|
+
unbind && unbind();
|
|
63
|
+
if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true) && node instanceof HTMLElement) {
|
|
64
|
+
_reactDom.default.unmountComponentAtNode(node);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
40
68
|
return _view.Decoration.widget(pos, function (view, getPosUnsafe) {
|
|
41
69
|
var element = document.createElement('span');
|
|
42
70
|
// inline decoration causes focus issues when refocusing Editor into first line
|
|
@@ -126,15 +154,5 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
|
|
|
126
154
|
}), element);
|
|
127
155
|
}
|
|
128
156
|
return element;
|
|
129
|
-
},
|
|
130
|
-
side: -1,
|
|
131
|
-
type: _decorationsCommon.TYPE_HANDLE_DEC,
|
|
132
|
-
testid: "".concat(_decorationsCommon.TYPE_HANDLE_DEC, "-").concat((0, _uuid.default)()),
|
|
133
|
-
destroy: function destroy(node) {
|
|
134
|
-
unbind && unbind();
|
|
135
|
-
if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true) && node instanceof HTMLElement) {
|
|
136
|
-
_reactDom.default.unmountComponentAtNode(node);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
157
|
+
}, widgetSpec);
|
|
140
158
|
};
|
|
@@ -9,7 +9,9 @@ var _react = require("react");
|
|
|
9
9
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
10
10
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
11
11
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
12
|
+
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
12
13
|
var _quickInsertButton = require("../ui/quick-insert-button");
|
|
14
|
+
var _vanillaQuickInsert = require("./vanilla-quick-insert");
|
|
13
15
|
var TYPE_QUICK_INSERT = 'INSERT_BUTTON';
|
|
14
16
|
var findQuickInsertInsertButtonDecoration = exports.findQuickInsertInsertButtonDecoration = function findQuickInsertInsertButtonDecoration(decorations, from, to) {
|
|
15
17
|
return decorations.find(from, to, function (spec) {
|
|
@@ -18,11 +20,59 @@ var findQuickInsertInsertButtonDecoration = exports.findQuickInsertInsertButtonD
|
|
|
18
20
|
};
|
|
19
21
|
var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function quickInsertButtonDecoration(api, formatMessage, rootPos, anchorName, nodeType, nodeViewPortalProviderAPI, rootAnchorName, rootNodeType, anchorRectCache) {
|
|
20
22
|
var key = (0, _uuid.default)();
|
|
23
|
+
var cleanupCallbacks = [];
|
|
24
|
+
var widgetSpec = (0, _experiments.editorExperiment)('platform_editor_breakout_resizing', true) ? {
|
|
25
|
+
side: -2,
|
|
26
|
+
type: TYPE_QUICK_INSERT,
|
|
27
|
+
/**
|
|
28
|
+
* sigh - `marks` influences the position that the widget is drawn (as described on the `side` property).
|
|
29
|
+
* Leaving this 'undefined' causes the widget to be wrapped in the mark before this position which creates
|
|
30
|
+
* weird stacking context issues. Providing an empty array causes the widget to correctly render before
|
|
31
|
+
* this exact position at the top of the DOM.
|
|
32
|
+
*/
|
|
33
|
+
marks: [],
|
|
34
|
+
destroy: function destroy(_) {
|
|
35
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_fix_widget_destroy')) {
|
|
36
|
+
nodeViewPortalProviderAPI.remove(key);
|
|
37
|
+
}
|
|
38
|
+
cleanupCallbacks.forEach(function (cb) {
|
|
39
|
+
cb();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
} : {
|
|
43
|
+
side: -2,
|
|
44
|
+
type: TYPE_QUICK_INSERT,
|
|
45
|
+
destroy: function destroy(_) {
|
|
46
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_fix_widget_destroy')) {
|
|
47
|
+
nodeViewPortalProviderAPI.remove(key);
|
|
48
|
+
}
|
|
49
|
+
cleanupCallbacks.forEach(function (cb) {
|
|
50
|
+
cb();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
21
54
|
return _view.Decoration.widget(rootPos, function (view, getPos) {
|
|
22
55
|
var element = document.createElement('span');
|
|
23
56
|
element.contentEditable = 'false';
|
|
24
57
|
element.setAttribute('data-blocks-quick-insert-container', 'true');
|
|
25
58
|
element.setAttribute('data-testid', 'block-ctrl-quick-insert-button');
|
|
59
|
+
if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true, {
|
|
60
|
+
exposure: true
|
|
61
|
+
})) {
|
|
62
|
+
var vanillaElement = (0, _vanillaQuickInsert.createVanillaButton)({
|
|
63
|
+
formatMessage: formatMessage,
|
|
64
|
+
api: api,
|
|
65
|
+
view: view,
|
|
66
|
+
getPos: getPos,
|
|
67
|
+
cleanupCallbacks: cleanupCallbacks,
|
|
68
|
+
rootAnchorName: rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : nodeType,
|
|
69
|
+
anchorName: anchorName,
|
|
70
|
+
rootNodeType: rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType,
|
|
71
|
+
anchorRectCache: anchorRectCache
|
|
72
|
+
});
|
|
73
|
+
element.appendChild(vanillaElement);
|
|
74
|
+
return element;
|
|
75
|
+
}
|
|
26
76
|
|
|
27
77
|
// all changes already under experiment
|
|
28
78
|
if ((0, _platformFeatureFlags.fg)('platform_editor_controls_widget_visibility')) {
|
|
@@ -55,13 +105,5 @@ var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function
|
|
|
55
105
|
}, element, key);
|
|
56
106
|
}
|
|
57
107
|
return element;
|
|
58
|
-
},
|
|
59
|
-
side: -2,
|
|
60
|
-
type: TYPE_QUICK_INSERT,
|
|
61
|
-
destroy: function destroy(_) {
|
|
62
|
-
if ((0, _platformFeatureFlags.fg)('platform_editor_fix_widget_destroy')) {
|
|
63
|
-
nodeViewPortalProviderAPI.remove(key);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
});
|
|
108
|
+
}, widgetSpec);
|
|
67
109
|
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.calculatePosition = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _consts = require("../ui/consts");
|
|
10
|
+
var _anchorName = require("../ui/utils/anchor-name");
|
|
11
|
+
var _dragHandlePositions = require("./utils/drag-handle-positions");
|
|
12
|
+
var _widgetPositions = require("./utils/widget-positions");
|
|
13
|
+
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; }
|
|
14
|
+
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; }
|
|
15
|
+
// Adapted from `src/ui/drag-handle.tsx` as positioning logic is similar
|
|
16
|
+
// CHANGES - added an offset so quick insert button can be positioned beside drag handle
|
|
17
|
+
// CHANGES - removed `editorExperiment('nested-dnd', true)` check and rootNodeType calculation
|
|
18
|
+
// CHANGES - replace anchorName with rootAnchorName
|
|
19
|
+
// CHANGES - `removed editorExperiment('advanced_layouts', true) && isLayoutColumn` checks as quick insert button will not be positioned for layout column
|
|
20
|
+
var calculatePosition = exports.calculatePosition = function calculatePosition(_ref) {
|
|
21
|
+
var rootAnchorName = _ref.rootAnchorName,
|
|
22
|
+
anchorName = _ref.anchorName,
|
|
23
|
+
view = _ref.view,
|
|
24
|
+
getPos = _ref.getPos,
|
|
25
|
+
rootNodeType = _ref.rootNodeType,
|
|
26
|
+
macroInteractionUpdates = _ref.macroInteractionUpdates,
|
|
27
|
+
anchorRectCache = _ref.anchorRectCache;
|
|
28
|
+
var supportsAnchor = CSS.supports('top', "anchor(".concat(rootAnchorName, " start)")) && CSS.supports('left', "anchor(".concat(rootAnchorName, " start)"));
|
|
29
|
+
var safeAnchorName = (0, _anchorName.refreshAnchorName)({
|
|
30
|
+
getPos: getPos,
|
|
31
|
+
view: view,
|
|
32
|
+
anchorName: rootAnchorName
|
|
33
|
+
});
|
|
34
|
+
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(safeAnchorName, "\"]"));
|
|
35
|
+
var hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
|
|
36
|
+
var isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension';
|
|
37
|
+
var isBlockCard = rootNodeType === 'blockCard';
|
|
38
|
+
var isEmbedCard = rootNodeType === 'embedCard';
|
|
39
|
+
var isMacroInteractionUpdates = macroInteractionUpdates && isExtension;
|
|
40
|
+
var innerContainer = null;
|
|
41
|
+
if (dom) {
|
|
42
|
+
if (isEmbedCard) {
|
|
43
|
+
innerContainer = dom.querySelector('.rich-media-item');
|
|
44
|
+
} else if (hasResizer) {
|
|
45
|
+
innerContainer = dom.querySelector('.resizer-item');
|
|
46
|
+
} else if (isExtension) {
|
|
47
|
+
innerContainer = dom.querySelector('.extension-container[data-layout]');
|
|
48
|
+
} else if (isBlockCard) {
|
|
49
|
+
//specific to datasource blockCard
|
|
50
|
+
innerContainer = dom.querySelector('.datasourceView-content-inner-wrap');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
|
|
54
|
+
var isSticky = (0, _dragHandlePositions.shouldBeSticky)(rootNodeType);
|
|
55
|
+
var bottom = (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName || anchorName, isSticky, true);
|
|
56
|
+
if (supportsAnchor) {
|
|
57
|
+
return _objectSpread({
|
|
58
|
+
left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _widgetPositions.getLeftPositionForRootElement)(dom, rootNodeType, _consts.QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(_consts.QUICK_INSERT_DIMENSIONS.width, "px - ").concat((0, _consts.rootElementGap)(rootNodeType), "px + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)"),
|
|
59
|
+
top: "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _consts.topPositionAdjustment)(rootNodeType), "px)")
|
|
60
|
+
}, bottom);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// expensive, calls offsetHeight
|
|
64
|
+
var nodeHeight = (0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName || anchorName, anchorRectCache) || 0;
|
|
65
|
+
var height = (0, _dragHandlePositions.getControlHeightCSSValue)(nodeHeight, isSticky, true, "var(--ds-space-300, 24px)");
|
|
66
|
+
return _objectSpread({
|
|
67
|
+
left: isEdgeCase ? "calc(".concat((dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0, "px + ").concat((0, _widgetPositions.getLeftPositionForRootElement)(dom, rootNodeType, _consts.QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(".concat((0, _widgetPositions.getLeftPositionForRootElement)(dom, rootNodeType, _consts.QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)"),
|
|
68
|
+
top: (0, _dragHandlePositions.getTopPosition)(dom, rootNodeType)
|
|
69
|
+
}, height);
|
|
70
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createVanillaButton = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
10
|
+
var _messages = require("@atlaskit/editor-common/messages");
|
|
11
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
12
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
13
|
+
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
14
|
+
var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
|
|
15
|
+
var _documentChecks = require("../ui/utils/document-checks");
|
|
16
|
+
var _editorCommands = require("../ui/utils/editor-commands");
|
|
17
|
+
var _quickInsertCalculatePosition = require("./quick-insert-calculate-position");
|
|
18
|
+
var _vanillaTooltip = require("./vanilla-tooltip");
|
|
19
|
+
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; }
|
|
20
|
+
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; }
|
|
21
|
+
// Based on platform/packages/design-system/icon/svgs/utility/add.svg
|
|
22
|
+
var plusButtonDOM = ['http://www.w3.org/2000/svg svg', {
|
|
23
|
+
width: '12',
|
|
24
|
+
height: '12',
|
|
25
|
+
fill: 'none',
|
|
26
|
+
viewBox: '0 0 12 12',
|
|
27
|
+
style: 'pointer-events: none;'
|
|
28
|
+
}, ['http://www.w3.org/2000/svg path', {
|
|
29
|
+
fill: 'currentcolor',
|
|
30
|
+
'fill-rule': 'evenodd',
|
|
31
|
+
d: 'M5.25 6.75V11h1.5V6.75H11v-1.5H6.75V1h-1.5v4.25H1v1.5z',
|
|
32
|
+
'clip-rule': 'evenodd',
|
|
33
|
+
style: 'pointer-events: none;'
|
|
34
|
+
}]];
|
|
35
|
+
var vanillaQuickInsert = function vanillaQuickInsert(_ref) {
|
|
36
|
+
var _api$featureFlags$sha, _api$featureFlags;
|
|
37
|
+
var view = _ref.view,
|
|
38
|
+
getPos = _ref.getPos,
|
|
39
|
+
rootNodeType = _ref.rootNodeType,
|
|
40
|
+
anchorRectCache = _ref.anchorRectCache,
|
|
41
|
+
anchorName = _ref.anchorName,
|
|
42
|
+
rootAnchorName = _ref.rootAnchorName,
|
|
43
|
+
api = _ref.api;
|
|
44
|
+
return ['div', {
|
|
45
|
+
style: (0, _lazyNodeView.convertToInlineCss)(_objectSpread({
|
|
46
|
+
position: 'absolute'
|
|
47
|
+
}, (0, _quickInsertCalculatePosition.calculatePosition)({
|
|
48
|
+
rootAnchorName: rootAnchorName,
|
|
49
|
+
anchorName: anchorName,
|
|
50
|
+
view: view,
|
|
51
|
+
getPos: getPos,
|
|
52
|
+
rootNodeType: rootNodeType,
|
|
53
|
+
macroInteractionUpdates: (_api$featureFlags$sha = api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 || (_api$featureFlags = _api$featureFlags.sharedState.currentState()) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.macroInteractionUpdates) !== null && _api$featureFlags$sha !== void 0 ? _api$featureFlags$sha : false,
|
|
54
|
+
anchorRectCache: anchorRectCache
|
|
55
|
+
})))
|
|
56
|
+
}, ['button', {
|
|
57
|
+
class: 'blocks-quick-insert-button',
|
|
58
|
+
'data-testid': 'editor-quick-insert-button'
|
|
59
|
+
}, plusButtonDOM]];
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create a Node which contains the quick insert button
|
|
64
|
+
*/
|
|
65
|
+
var createVanillaButton = exports.createVanillaButton = function createVanillaButton(props) {
|
|
66
|
+
var _props$api$typeAhead, _props$api$blockContr, _props$api$typeAhead2, _props$api$blockContr2;
|
|
67
|
+
var _DOMSerializer$render = _model.DOMSerializer.renderSpec(document, vanillaQuickInsert(props)),
|
|
68
|
+
dom = _DOMSerializer$render.dom;
|
|
69
|
+
if (dom instanceof HTMLElement) {
|
|
70
|
+
var button = dom.querySelector('button[data-testid="editor-quick-insert-button"]');
|
|
71
|
+
if (button instanceof HTMLButtonElement) {
|
|
72
|
+
button.onclick = function () {
|
|
73
|
+
return handleQuickInsert(props);
|
|
74
|
+
};
|
|
75
|
+
var tooltip = new _vanillaTooltip.VanillaTooltip(button, props.formatMessage(_messages.blockControlsMessages.insert), 'quick-insert-button-tooltip');
|
|
76
|
+
props.cleanupCallbacks.push(function () {
|
|
77
|
+
tooltip.destroy();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Dynamically control the visibility of the node
|
|
83
|
+
var isTypeAheadOpen = (_props$api$typeAhead = props.api.typeAhead) === null || _props$api$typeAhead === void 0 || (_props$api$typeAhead = _props$api$typeAhead.sharedState.currentState()) === null || _props$api$typeAhead === void 0 ? void 0 : _props$api$typeAhead.isOpen;
|
|
84
|
+
var isEditing = (_props$api$blockContr = props.api.blockControls) === null || _props$api$blockContr === void 0 || (_props$api$blockContr = _props$api$blockContr.sharedState.currentState()) === null || _props$api$blockContr === void 0 ? void 0 : _props$api$blockContr.isEditing;
|
|
85
|
+
var changeDOMVisibility = function changeDOMVisibility() {
|
|
86
|
+
if (!(dom instanceof HTMLElement)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (isTypeAheadOpen || isEditing) {
|
|
90
|
+
dom.classList.add('blocks-quick-insert-invisible-container');
|
|
91
|
+
dom.classList.remove('blocks-quick-insert-visible-container');
|
|
92
|
+
} else {
|
|
93
|
+
dom.classList.add('blocks-quick-insert-visible-container');
|
|
94
|
+
dom.classList.remove('blocks-quick-insert-invisible-container');
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
changeDOMVisibility();
|
|
98
|
+
props.cleanupCallbacks.push((_props$api$typeAhead2 = props.api.typeAhead) === null || _props$api$typeAhead2 === void 0 ? void 0 : _props$api$typeAhead2.sharedState.onChange(function (_ref2) {
|
|
99
|
+
var nextSharedState = _ref2.nextSharedState;
|
|
100
|
+
isTypeAheadOpen = nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isOpen;
|
|
101
|
+
changeDOMVisibility();
|
|
102
|
+
}));
|
|
103
|
+
props.cleanupCallbacks.push((_props$api$blockContr2 = props.api.blockControls) === null || _props$api$blockContr2 === void 0 ? void 0 : _props$api$blockContr2.sharedState.onChange(function (_ref3) {
|
|
104
|
+
var nextSharedState = _ref3.nextSharedState;
|
|
105
|
+
isEditing = nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isEditing;
|
|
106
|
+
changeDOMVisibility();
|
|
107
|
+
}));
|
|
108
|
+
return dom;
|
|
109
|
+
};
|
|
110
|
+
var TEXT_PARENT_TYPES = ['paragraph', 'heading', 'blockquote', 'taskItem', 'decisionItem'];
|
|
111
|
+
var handleQuickInsert = function handleQuickInsert(_ref4) {
|
|
112
|
+
var _api$quickInsert;
|
|
113
|
+
var api = _ref4.api,
|
|
114
|
+
view = _ref4.view,
|
|
115
|
+
getPos = _ref4.getPos;
|
|
116
|
+
// if the selection is not within the node this decoration is rendered at
|
|
117
|
+
// then insert a newline and trigger quick insert
|
|
118
|
+
var start = getPos();
|
|
119
|
+
if (start !== undefined) {
|
|
120
|
+
// if the selection is not within the node this decoration is rendered at
|
|
121
|
+
// or the node is non-editable, then insert a newline and trigger quick insert
|
|
122
|
+
var isSelectionInsideNode = (0, _documentChecks.isSelectionInNode)(start, view);
|
|
123
|
+
if (!isSelectionInsideNode || (0, _documentChecks.isNonEditableBlock)(start, view)) {
|
|
124
|
+
api.core.actions.execute((0, _editorCommands.createNewLine)(start));
|
|
125
|
+
}
|
|
126
|
+
var codeBlock = view.state.schema.nodes.codeBlock;
|
|
127
|
+
var selection = view.state.selection;
|
|
128
|
+
var codeBlockParentNode = (0, _utils.findParentNodeOfType)(codeBlock)(selection);
|
|
129
|
+
if (codeBlockParentNode) {
|
|
130
|
+
// Slash command is not meant to be triggered inside code block, hence always insert slash in a new line following
|
|
131
|
+
api.core.actions.execute((0, _editorCommands.createNewLine)(codeBlockParentNode.pos));
|
|
132
|
+
} else if (isSelectionInsideNode) {
|
|
133
|
+
// text or element with be deselected and the / added immediately after the paragraph
|
|
134
|
+
// unless the selection is empty
|
|
135
|
+
var currentSelection = view.state.selection;
|
|
136
|
+
if ((0, _documentChecks.isInTextSelection)(view) && currentSelection.from !== currentSelection.to) {
|
|
137
|
+
var currentParagraphNode = (0, _utils.findParentNode)(function (node) {
|
|
138
|
+
return TEXT_PARENT_TYPES.includes(node.type.name);
|
|
139
|
+
})(currentSelection);
|
|
140
|
+
if (currentParagraphNode) {
|
|
141
|
+
var newPos =
|
|
142
|
+
//if the current selection is selected from right to left, then set the selection to the start of the paragraph
|
|
143
|
+
currentSelection.anchor === currentSelection.to ? currentParagraphNode.pos : currentParagraphNode.pos + currentParagraphNode.node.nodeSize - 1;
|
|
144
|
+
api.core.actions.execute(function (_ref5) {
|
|
145
|
+
var tr = _ref5.tr;
|
|
146
|
+
tr.setSelection(_state.TextSelection.create(view.state.selection.$from.doc, newPos));
|
|
147
|
+
return tr;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if ((0, _documentChecks.isNestedNodeSelected)(view)) {
|
|
152
|
+
// if the nested selected node is non-editable, then insert a newline below the selected node
|
|
153
|
+
if ((0, _documentChecks.isNonEditableBlock)(view.state.selection.from, view)) {
|
|
154
|
+
api.core.actions.execute((0, _editorCommands.createNewLine)(view.state.selection.from));
|
|
155
|
+
} else {
|
|
156
|
+
// otherwise need to force the selection to be at the start of the node, because
|
|
157
|
+
// prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
|
|
158
|
+
// consistent NodeSelection for root level nodes.
|
|
159
|
+
api.core.actions.execute(function (_ref6) {
|
|
160
|
+
var tr = _ref6.tr;
|
|
161
|
+
(0, _editorCommands.createNewLine)(view.state.selection.from)({
|
|
162
|
+
tr: tr
|
|
163
|
+
});
|
|
164
|
+
tr.setSelection(_state.TextSelection.create(tr.doc, view.state.selection.from));
|
|
165
|
+
return tr;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (currentSelection instanceof _cellSelection.CellSelection) {
|
|
170
|
+
// find the last inline position in the selection
|
|
171
|
+
var lastInlinePosition = _state.TextSelection.near(view.state.selection.$to, -1);
|
|
172
|
+
lastInlinePosition && api.core.actions.execute(function (_ref7) {
|
|
173
|
+
var tr = _ref7.tr;
|
|
174
|
+
if (!(lastInlinePosition instanceof _state.TextSelection)) {
|
|
175
|
+
// this will create a new line after the node
|
|
176
|
+
(0, _editorCommands.createNewLine)(lastInlinePosition.from)({
|
|
177
|
+
tr: tr
|
|
178
|
+
});
|
|
179
|
+
// this will find the next valid text position after the node
|
|
180
|
+
tr.setSelection(_state.TextSelection.create(tr.doc, lastInlinePosition.to));
|
|
181
|
+
} else {
|
|
182
|
+
tr.setSelection(lastInlinePosition);
|
|
183
|
+
}
|
|
184
|
+
return tr;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
(_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl', true);
|
|
190
|
+
};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.VanillaTooltip = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var _core = require("@popperjs/core");
|
|
12
|
+
var _bindEventListener = require("bind-event-listener");
|
|
13
|
+
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; }
|
|
14
|
+
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; }
|
|
15
|
+
var startingOffset = {
|
|
16
|
+
name: 'offset',
|
|
17
|
+
options: {
|
|
18
|
+
offset: [0, 4]
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var endingOffset = {
|
|
22
|
+
name: 'offset',
|
|
23
|
+
options: {
|
|
24
|
+
offset: [0, 8]
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A tooltip component similar to "@atlaskit/tooltip" but built for vanilla scenarios
|
|
30
|
+
*
|
|
31
|
+
* Uses Popover API for accessibility + stacking context: https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
|
|
32
|
+
* Uses popperJS for positioning
|
|
33
|
+
*
|
|
34
|
+
* @warning Still experimental. One day we can likely want to move this to a common package.
|
|
35
|
+
*/
|
|
36
|
+
var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
37
|
+
function VanillaTooltip(button, content,
|
|
38
|
+
/**
|
|
39
|
+
* Id associated to the tooltip - must be unique.
|
|
40
|
+
*/
|
|
41
|
+
id) {
|
|
42
|
+
var _this = this;
|
|
43
|
+
var timeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300;
|
|
44
|
+
(0, _classCallCheck2.default)(this, VanillaTooltip);
|
|
45
|
+
(0, _defineProperty2.default)(this, "listeners", []);
|
|
46
|
+
(0, _defineProperty2.default)(this, "shouldHidePopover", false);
|
|
47
|
+
(0, _defineProperty2.default)(this, "isDisplayed", false);
|
|
48
|
+
this.button = button;
|
|
49
|
+
this.timeout = timeout;
|
|
50
|
+
var tooltip = document.createElement('span');
|
|
51
|
+
tooltip.role = 'tooltip';
|
|
52
|
+
tooltip.popover = 'hint';
|
|
53
|
+
// Warning: Currently this is used for styling - only works in the block controls package
|
|
54
|
+
tooltip.className = 'blocks-quick-insert-tooltip';
|
|
55
|
+
tooltip.id = id;
|
|
56
|
+
tooltip.textContent = content;
|
|
57
|
+
this.tooltip = tooltip;
|
|
58
|
+
|
|
59
|
+
// Button preparation
|
|
60
|
+
button.appendChild(tooltip);
|
|
61
|
+
// Prepare the button to have the popover target and accessibility properties
|
|
62
|
+
button.setAttribute('popovertarget', tooltip.id);
|
|
63
|
+
button.setAttribute('aria-describedby', tooltip.id);
|
|
64
|
+
var showEvents = ['mouseenter', 'focus'];
|
|
65
|
+
var hideEvents = ['mouseleave', 'blur'];
|
|
66
|
+
showEvents.forEach(function (event) {
|
|
67
|
+
_this.listeners.push((0, _bindEventListener.bind)(button, {
|
|
68
|
+
type: event,
|
|
69
|
+
listener: function listener() {
|
|
70
|
+
return _this.show();
|
|
71
|
+
}
|
|
72
|
+
}));
|
|
73
|
+
});
|
|
74
|
+
hideEvents.forEach(function (event) {
|
|
75
|
+
_this.listeners.push((0, _bindEventListener.bind)(button, {
|
|
76
|
+
type: event,
|
|
77
|
+
listener: function listener() {
|
|
78
|
+
return _this.hide();
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
});
|
|
82
|
+
this.listeners.push((0, _bindEventListener.bind)(window, {
|
|
83
|
+
type: 'keydown',
|
|
84
|
+
listener: function listener(e) {
|
|
85
|
+
if (e.key === 'Escape') {
|
|
86
|
+
_this.hide(true);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
|
|
91
|
+
// Hide the tooltip if the hide transition has completed
|
|
92
|
+
this.tooltip.ontransitionend = function () {
|
|
93
|
+
if (_this.shouldHidePopover) {
|
|
94
|
+
_this.tooltip.hidePopover();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return (0, _createClass2.default)(VanillaTooltip, [{
|
|
99
|
+
key: "createPopperInstance",
|
|
100
|
+
value: function createPopperInstance() {
|
|
101
|
+
this.popperInstance = (0, _core.createPopper)(this.button, this.tooltip, {
|
|
102
|
+
placement: 'top',
|
|
103
|
+
modifiers: [startingOffset]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}, {
|
|
107
|
+
key: "destroy",
|
|
108
|
+
value: function destroy() {
|
|
109
|
+
var _this$popperInstance;
|
|
110
|
+
(_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 || _this$popperInstance.destroy();
|
|
111
|
+
this.listeners.forEach(function (listener) {
|
|
112
|
+
listener();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}, {
|
|
116
|
+
key: "hide",
|
|
117
|
+
value: function hide() {
|
|
118
|
+
var _this2 = this;
|
|
119
|
+
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
120
|
+
clearTimeout(this.currentTimeoutId);
|
|
121
|
+
this.shouldHidePopover = true;
|
|
122
|
+
// Disable the event listeners
|
|
123
|
+
this.currentTimeoutId = setTimeout(function () {
|
|
124
|
+
var _this2$popperInstance;
|
|
125
|
+
(_this2$popperInstance = _this2.popperInstance) === null || _this2$popperInstance === void 0 || _this2$popperInstance.setOptions(function (options) {
|
|
126
|
+
return _objectSpread(_objectSpread({}, options), {}, {
|
|
127
|
+
modifiers: [startingOffset, {
|
|
128
|
+
name: 'eventListeners',
|
|
129
|
+
enabled: false
|
|
130
|
+
}]
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
_this2.tooltip.style.opacity = '0';
|
|
134
|
+
_this2.isDisplayed = false;
|
|
135
|
+
// If transition animations are disabled immediately hide the popover
|
|
136
|
+
if (_this2.tooltip.style.transition === 'none') {
|
|
137
|
+
_this2.tooltip.hidePopover();
|
|
138
|
+
}
|
|
139
|
+
}, immediate ? 0 : this.timeout);
|
|
140
|
+
}
|
|
141
|
+
}, {
|
|
142
|
+
key: "show",
|
|
143
|
+
value: function show() {
|
|
144
|
+
var _this3 = this;
|
|
145
|
+
if (this.isDisplayed) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
clearTimeout(this.currentTimeoutId);
|
|
149
|
+
this.shouldHidePopover = false;
|
|
150
|
+
|
|
151
|
+
// Make the tooltip visible - but hide until
|
|
152
|
+
this.tooltip.style.visibility = 'hidden';
|
|
153
|
+
this.tooltip.showPopover();
|
|
154
|
+
|
|
155
|
+
// Update its position
|
|
156
|
+
if (!this.popperInstance) {
|
|
157
|
+
this.createPopperInstance();
|
|
158
|
+
} else {
|
|
159
|
+
this.popperInstance.update();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Enable the event listeners
|
|
163
|
+
this.currentTimeoutId = setTimeout(function () {
|
|
164
|
+
var _this3$popperInstance;
|
|
165
|
+
_this3.tooltip.style.opacity = '1';
|
|
166
|
+
_this3.tooltip.style.visibility = 'visible';
|
|
167
|
+
(_this3$popperInstance = _this3.popperInstance) === null || _this3$popperInstance === void 0 || _this3$popperInstance.setOptions(function (options) {
|
|
168
|
+
return _objectSpread(_objectSpread({}, options), {}, {
|
|
169
|
+
modifiers: [endingOffset, {
|
|
170
|
+
name: 'eventListeners',
|
|
171
|
+
enabled: true
|
|
172
|
+
}]
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
_this3.isDisplayed = true;
|
|
176
|
+
}, this.timeout);
|
|
177
|
+
}
|
|
178
|
+
}]);
|
|
179
|
+
}();
|