@atlaskit/editor-core 187.18.1 → 187.18.2
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 +7 -0
- package/dist/cjs/labs/next/presets/universal.js +2 -1
- package/dist/cjs/plugins/index.js +0 -7
- package/dist/cjs/plugins/paste/pm-plugins/main.js +2 -6
- package/dist/cjs/utils/clipboard.js +5 -27
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/labs/next/presets/universal.js +2 -1
- package/dist/es2019/plugins/index.js +0 -1
- package/dist/es2019/plugins/paste/pm-plugins/main.js +2 -2
- package/dist/es2019/utils/clipboard.js +0 -16
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/labs/next/presets/universal.js +2 -1
- package/dist/esm/plugins/index.js +0 -1
- package/dist/esm/plugins/paste/pm-plugins/main.js +2 -2
- package/dist/esm/utils/clipboard.js +4 -23
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/plugins/index.d.ts +0 -1
- package/dist/types/plugins/insert-block/index.d.ts +1 -1
- package/dist/types/utils/clipboard.d.ts +0 -3
- package/dist/types-ts4.5/plugins/index.d.ts +0 -1
- package/dist/types-ts4.5/plugins/insert-block/index.d.ts +1 -1
- package/dist/types-ts4.5/utils/clipboard.d.ts +0 -3
- package/package.json +4 -3
- package/dist/cjs/plugins/image-upload/index.js +0 -45
- package/dist/cjs/plugins/image-upload/pm-plugins/actions.js +0 -19
- package/dist/cjs/plugins/image-upload/pm-plugins/commands-toolbar.js +0 -19
- package/dist/cjs/plugins/image-upload/pm-plugins/commands.js +0 -40
- package/dist/cjs/plugins/image-upload/pm-plugins/input-rule.js +0 -31
- package/dist/cjs/plugins/image-upload/pm-plugins/main.js +0 -194
- package/dist/cjs/plugins/image-upload/pm-plugins/plugin-key.js +0 -9
- package/dist/cjs/plugins/image-upload/types.js +0 -5
- package/dist/cjs/plugins/image-upload/utils.js +0 -40
- package/dist/cjs/utils/drag-drop.js +0 -19
- package/dist/es2019/plugins/image-upload/index.js +0 -34
- package/dist/es2019/plugins/image-upload/pm-plugins/actions.js +0 -8
- package/dist/es2019/plugins/image-upload/pm-plugins/commands-toolbar.js +0 -12
- package/dist/es2019/plugins/image-upload/pm-plugins/commands.js +0 -28
- package/dist/es2019/plugins/image-upload/pm-plugins/input-rule.js +0 -25
- package/dist/es2019/plugins/image-upload/pm-plugins/main.js +0 -159
- package/dist/es2019/plugins/image-upload/pm-plugins/plugin-key.js +0 -2
- package/dist/es2019/plugins/image-upload/types.js +0 -1
- package/dist/es2019/plugins/image-upload/utils.js +0 -38
- package/dist/es2019/utils/drag-drop.js +0 -9
- package/dist/esm/plugins/image-upload/index.js +0 -37
- package/dist/esm/plugins/image-upload/pm-plugins/actions.js +0 -12
- package/dist/esm/plugins/image-upload/pm-plugins/commands-toolbar.js +0 -12
- package/dist/esm/plugins/image-upload/pm-plugins/commands.js +0 -32
- package/dist/esm/plugins/image-upload/pm-plugins/input-rule.js +0 -23
- package/dist/esm/plugins/image-upload/pm-plugins/main.js +0 -186
- package/dist/esm/plugins/image-upload/pm-plugins/plugin-key.js +0 -2
- package/dist/esm/plugins/image-upload/types.js +0 -1
- package/dist/esm/plugins/image-upload/utils.js +0 -31
- package/dist/esm/utils/drag-drop.js +0 -11
- package/dist/types/plugins/image-upload/index.d.ts +0 -16
- package/dist/types/plugins/image-upload/pm-plugins/actions.d.ts +0 -3
- package/dist/types/plugins/image-upload/pm-plugins/commands-toolbar.d.ts +0 -3
- package/dist/types/plugins/image-upload/pm-plugins/commands.d.ts +0 -5
- package/dist/types/plugins/image-upload/pm-plugins/input-rule.d.ts +0 -5
- package/dist/types/plugins/image-upload/pm-plugins/main.d.ts +0 -4
- package/dist/types/plugins/image-upload/pm-plugins/plugin-key.d.ts +0 -3
- package/dist/types/plugins/image-upload/types.d.ts +0 -18
- package/dist/types/plugins/image-upload/utils.d.ts +0 -5
- package/dist/types/utils/drag-drop.d.ts +0 -2
- package/dist/types-ts4.5/plugins/image-upload/index.d.ts +0 -16
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/actions.d.ts +0 -3
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/commands-toolbar.d.ts +0 -3
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/commands.d.ts +0 -5
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/input-rule.d.ts +0 -5
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/main.d.ts +0 -4
- package/dist/types-ts4.5/plugins/image-upload/pm-plugins/plugin-key.d.ts +0 -3
- package/dist/types-ts4.5/plugins/image-upload/types.d.ts +0 -18
- package/dist/types-ts4.5/plugins/image-upload/utils.d.ts +0 -5
- package/dist/types-ts4.5/utils/drag-drop.d.ts +0 -2
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.createPlugin = void 0;
|
|
8
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
-
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
12
|
-
var _clipboard = require("../../../utils/clipboard");
|
|
13
|
-
var _dragDrop = require("../../../utils/drag-drop");
|
|
14
|
-
var _utils = require("../utils");
|
|
15
|
-
var _commands = require("./commands");
|
|
16
|
-
var _pluginKey = require("./plugin-key");
|
|
17
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
18
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
19
|
-
/**
|
|
20
|
-
* Microsoft Office includes a screenshot image when copying text content.
|
|
21
|
-
*
|
|
22
|
-
* This function determines whether or not we can ignore the image if it
|
|
23
|
-
* came from MS Office. We do this by checking for
|
|
24
|
-
*
|
|
25
|
-
* - plain text
|
|
26
|
-
* - HTML text which includes the MS Office namespace
|
|
27
|
-
* - the number of files and the file name/type
|
|
28
|
-
*
|
|
29
|
-
* It is easy to manually verify this using by using Office on Mac
|
|
30
|
-
* (or Excel if on Windows) and pasting into
|
|
31
|
-
* https://evercoder.github.io/clipboard-inspector/
|
|
32
|
-
*
|
|
33
|
-
* Note: image content in Word is stored in the `text/html` portion
|
|
34
|
-
* of the clipboard, not under `files` attachment like the screenshot.
|
|
35
|
-
*
|
|
36
|
-
* @returns boolean True if the paste event contains a screenshot from MS Office
|
|
37
|
-
*/
|
|
38
|
-
var hasScreenshotImageFromMSOffice = function hasScreenshotImageFromMSOffice(ev) {
|
|
39
|
-
var _ref = ev,
|
|
40
|
-
clipboardData = _ref.clipboardData;
|
|
41
|
-
if (!clipboardData || clipboardData.files.length !== 1) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
var textPlain = !!clipboardData.getData('text/plain');
|
|
45
|
-
var textHtml = clipboardData.getData('text/html');
|
|
46
|
-
var isOfficeXMLNamespace = textHtml.includes('urn:schemas-microsoft-com:office:office');
|
|
47
|
-
var file = clipboardData.files[0];
|
|
48
|
-
var isImagePNG = file.type === 'image/png' && file.name === 'image.png';
|
|
49
|
-
return isImagePNG && textPlain && isOfficeXMLNamespace;
|
|
50
|
-
};
|
|
51
|
-
var createReferenceEventFromEvent = function createReferenceEventFromEvent(event) {
|
|
52
|
-
var _event$dataTransfer, _event$clipboardData;
|
|
53
|
-
if (!(0, _dragDrop.isDragEvent)(event) && !(0, _clipboard.isClipboardEvent)(event)) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Get files list and early exit if files is undefined
|
|
58
|
-
var files = (0, _dragDrop.isDragEvent)(event) ? (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files : (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.files;
|
|
59
|
-
if (!files) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Convert filelist into an array
|
|
64
|
-
var filesArray = Array.from(files);
|
|
65
|
-
|
|
66
|
-
// Creating a new DataTransfer object should remove any mutation that could be possible from the original event
|
|
67
|
-
var dataTransfer = filesArray.reduce(function (acc, value) {
|
|
68
|
-
acc.items.add(value);
|
|
69
|
-
return acc;
|
|
70
|
-
}, new DataTransfer());
|
|
71
|
-
return _objectSpread(_objectSpread({
|
|
72
|
-
type: (0, _dragDrop.isDragEvent)(event) ? 'drop' : 'paste'
|
|
73
|
-
}, (0, _dragDrop.isDragEvent)(event) && {
|
|
74
|
-
dataTransfer: dataTransfer
|
|
75
|
-
}), (0, _clipboard.isClipboardEvent)(event) && {
|
|
76
|
-
clipboardData: dataTransfer
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
var createDOMHandler = function createDOMHandler(pred, _eventName, uploadHandlerReference) {
|
|
80
|
-
return function (view, event) {
|
|
81
|
-
if (!pred(event)) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
var shouldUpload = !hasScreenshotImageFromMSOffice(event);
|
|
85
|
-
var referenceEvent = createReferenceEventFromEvent(event);
|
|
86
|
-
if (shouldUpload && referenceEvent) {
|
|
87
|
-
event.preventDefault();
|
|
88
|
-
event.stopPropagation();
|
|
89
|
-
|
|
90
|
-
// Insert external image into document
|
|
91
|
-
if (uploadHandlerReference.current) {
|
|
92
|
-
uploadHandlerReference.current(referenceEvent, function (options) {
|
|
93
|
-
(0, _commands.insertExternalImage)(options)(view.state, view.dispatch);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Start image upload
|
|
98
|
-
(0, _commands.startImageUpload)(referenceEvent)(view.state, view.dispatch);
|
|
99
|
-
}
|
|
100
|
-
return shouldUpload;
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
var getNewActiveUpload = function getNewActiveUpload(tr, pluginState) {
|
|
104
|
-
var meta = tr.getMeta(_pluginKey.stateKey);
|
|
105
|
-
if (meta && meta.name === 'START_UPLOAD') {
|
|
106
|
-
return {
|
|
107
|
-
event: meta.event
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
return pluginState.activeUpload;
|
|
111
|
-
};
|
|
112
|
-
var createPlugin = function createPlugin(uploadHandlerReference) {
|
|
113
|
-
return function (_ref2) {
|
|
114
|
-
var dispatch = _ref2.dispatch,
|
|
115
|
-
providerFactory = _ref2.providerFactory;
|
|
116
|
-
return new _safePlugin.SafePlugin({
|
|
117
|
-
state: {
|
|
118
|
-
init: function init(_config, state) {
|
|
119
|
-
return {
|
|
120
|
-
active: false,
|
|
121
|
-
enabled: (0, _utils.canInsertMedia)(state),
|
|
122
|
-
hidden: !state.schema.nodes.media || !state.schema.nodes.mediaSingle
|
|
123
|
-
};
|
|
124
|
-
},
|
|
125
|
-
apply: function apply(tr, pluginState, _oldState, newState) {
|
|
126
|
-
var newActive = (0, _utils.isMediaSelected)(newState);
|
|
127
|
-
var newEnabled = (0, _utils.canInsertMedia)(newState);
|
|
128
|
-
var newActiveUpload = getNewActiveUpload(tr, pluginState);
|
|
129
|
-
if (newActive !== pluginState.active || newEnabled !== pluginState.enabled || newActiveUpload !== pluginState.activeUpload) {
|
|
130
|
-
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
131
|
-
active: newActive,
|
|
132
|
-
enabled: newEnabled,
|
|
133
|
-
activeUpload: newActiveUpload
|
|
134
|
-
});
|
|
135
|
-
dispatch(_pluginKey.stateKey, newPluginState);
|
|
136
|
-
return newPluginState;
|
|
137
|
-
}
|
|
138
|
-
return pluginState;
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
key: _pluginKey.stateKey,
|
|
142
|
-
view: function view() {
|
|
143
|
-
var handleProvider = /*#__PURE__*/function () {
|
|
144
|
-
var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(name, provider) {
|
|
145
|
-
var imageUploadProvider;
|
|
146
|
-
return _regenerator.default.wrap(function _callee$(_context) {
|
|
147
|
-
while (1) switch (_context.prev = _context.next) {
|
|
148
|
-
case 0:
|
|
149
|
-
if (!(name !== 'imageUploadProvider' || !provider)) {
|
|
150
|
-
_context.next = 2;
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
return _context.abrupt("return");
|
|
154
|
-
case 2:
|
|
155
|
-
_context.prev = 2;
|
|
156
|
-
_context.next = 5;
|
|
157
|
-
return provider;
|
|
158
|
-
case 5:
|
|
159
|
-
imageUploadProvider = _context.sent;
|
|
160
|
-
uploadHandlerReference.current = imageUploadProvider;
|
|
161
|
-
_context.next = 12;
|
|
162
|
-
break;
|
|
163
|
-
case 9:
|
|
164
|
-
_context.prev = 9;
|
|
165
|
-
_context.t0 = _context["catch"](2);
|
|
166
|
-
uploadHandlerReference.current = null;
|
|
167
|
-
case 12:
|
|
168
|
-
case "end":
|
|
169
|
-
return _context.stop();
|
|
170
|
-
}
|
|
171
|
-
}, _callee, null, [[2, 9]]);
|
|
172
|
-
}));
|
|
173
|
-
return function handleProvider(_x, _x2) {
|
|
174
|
-
return _ref3.apply(this, arguments);
|
|
175
|
-
};
|
|
176
|
-
}();
|
|
177
|
-
providerFactory.subscribe('imageUploadProvider', handleProvider);
|
|
178
|
-
return {
|
|
179
|
-
destroy: function destroy() {
|
|
180
|
-
uploadHandlerReference.current = null;
|
|
181
|
-
providerFactory.unsubscribe('imageUploadProvider', handleProvider);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
},
|
|
185
|
-
props: {
|
|
186
|
-
handleDOMEvents: {
|
|
187
|
-
drop: createDOMHandler(_dragDrop.isDroppedFile, 'atlassian.editor.image.drop', uploadHandlerReference),
|
|
188
|
-
paste: createDOMHandler(_clipboard.isPastedFile, 'atlassian.editor.image.paste', uploadHandlerReference)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
};
|
|
194
|
-
exports.createPlugin = createPlugin;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.stateKey = void 0;
|
|
7
|
-
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
-
var stateKey = new _state.PluginKey('imageUploadPlugin');
|
|
9
|
-
exports.stateKey = stateKey;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.isMediaSelected = exports.createExternalMediaNode = exports.canInsertMedia = void 0;
|
|
7
|
-
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
-
var isMediaSelected = function isMediaSelected(state) {
|
|
9
|
-
var media = state.schema.nodes.media;
|
|
10
|
-
return state.selection instanceof _state.NodeSelection && state.selection.node.type === media;
|
|
11
|
-
};
|
|
12
|
-
exports.isMediaSelected = isMediaSelected;
|
|
13
|
-
var canInsertMedia = function canInsertMedia(state) {
|
|
14
|
-
var mediaSingle = state.schema.nodes.mediaSingle;
|
|
15
|
-
var $to = state.selection.$to;
|
|
16
|
-
if (mediaSingle) {
|
|
17
|
-
for (var d = $to.depth; d >= 0; d--) {
|
|
18
|
-
var index = $to.index(d);
|
|
19
|
-
if ($to.node(d).canReplaceWith(index, index, mediaSingle)) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return false;
|
|
25
|
-
};
|
|
26
|
-
exports.canInsertMedia = canInsertMedia;
|
|
27
|
-
var createExternalMediaNode = function createExternalMediaNode(url, schema) {
|
|
28
|
-
var _schema$nodes = schema.nodes,
|
|
29
|
-
media = _schema$nodes.media,
|
|
30
|
-
mediaSingle = _schema$nodes.mediaSingle;
|
|
31
|
-
if (!media || !mediaSingle) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
var mediaNode = media.createChecked({
|
|
35
|
-
type: 'external',
|
|
36
|
-
url: url
|
|
37
|
-
});
|
|
38
|
-
return mediaSingle.createChecked({}, mediaNode);
|
|
39
|
-
};
|
|
40
|
-
exports.createExternalMediaNode = createExternalMediaNode;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.isDragEvent = void 0;
|
|
7
|
-
exports.isDroppedFile = isDroppedFile;
|
|
8
|
-
// Typeguard Function
|
|
9
|
-
var isDragEvent = function isDragEvent(event) {
|
|
10
|
-
return 'dataTransfer' in event;
|
|
11
|
-
};
|
|
12
|
-
exports.isDragEvent = isDragEvent;
|
|
13
|
-
function isDroppedFile(rawEvent) {
|
|
14
|
-
var e = rawEvent;
|
|
15
|
-
if (!e.dataTransfer) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
return Array.prototype.slice.call(e.dataTransfer.types).indexOf('Files') !== -1;
|
|
19
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { createPlugin } from './pm-plugins/main';
|
|
2
|
-
import inputRulePlugin from './pm-plugins/input-rule';
|
|
3
|
-
import { stateKey } from './pm-plugins/plugin-key';
|
|
4
|
-
import { insertActionForToolbar } from './pm-plugins/commands-toolbar';
|
|
5
|
-
const imageUpload = () => {
|
|
6
|
-
let uploadHandlerReference = {
|
|
7
|
-
current: null
|
|
8
|
-
};
|
|
9
|
-
return {
|
|
10
|
-
name: 'imageUpload',
|
|
11
|
-
getSharedState(editorState) {
|
|
12
|
-
if (!editorState) {
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
15
|
-
return stateKey.getState(editorState);
|
|
16
|
-
},
|
|
17
|
-
actions: {
|
|
18
|
-
startUpload: () => insertActionForToolbar(uploadHandlerReference)
|
|
19
|
-
},
|
|
20
|
-
pmPlugins() {
|
|
21
|
-
return [{
|
|
22
|
-
name: 'imageUpload',
|
|
23
|
-
plugin: createPlugin(uploadHandlerReference)
|
|
24
|
-
}, {
|
|
25
|
-
name: 'imageUploadInputRule',
|
|
26
|
-
plugin: ({
|
|
27
|
-
schema,
|
|
28
|
-
featureFlags
|
|
29
|
-
}) => inputRulePlugin(schema, featureFlags)
|
|
30
|
-
}];
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
export default imageUpload;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { insertExternalImage } from './commands';
|
|
2
|
-
export const insertActionForToolbar = uploadHandlerReference => {
|
|
3
|
-
return (state, dispatch) => {
|
|
4
|
-
if (!uploadHandlerReference.current) {
|
|
5
|
-
return false;
|
|
6
|
-
}
|
|
7
|
-
uploadHandlerReference.current(undefined, options => {
|
|
8
|
-
insertExternalImage(options)(state, dispatch);
|
|
9
|
-
});
|
|
10
|
-
return true;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
2
|
-
import { createExternalMediaNode } from '../utils';
|
|
3
|
-
import { startUpload } from './actions';
|
|
4
|
-
import { stateKey } from './plugin-key';
|
|
5
|
-
export const insertExternalImage = options => (state, dispatch) => {
|
|
6
|
-
const pluginState = stateKey.getState(state);
|
|
7
|
-
if (!(pluginState !== null && pluginState !== void 0 && pluginState.enabled) || !options.src) {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
const mediaNode = createExternalMediaNode(options.src, state.schema);
|
|
11
|
-
if (!mediaNode) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
if (dispatch) {
|
|
15
|
-
dispatch(safeInsert(mediaNode, state.selection.$to.pos)(state.tr).scrollIntoView());
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
};
|
|
19
|
-
export const startImageUpload = event => (state, dispatch) => {
|
|
20
|
-
const pluginState = stateKey.getState(state);
|
|
21
|
-
if (pluginState && !pluginState.enabled) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
if (dispatch) {
|
|
25
|
-
dispatch(startUpload(event)(state.tr));
|
|
26
|
-
}
|
|
27
|
-
return true;
|
|
28
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { createRule, createPlugin } from '@atlaskit/prosemirror-input-rules';
|
|
2
|
-
import { createExternalMediaNode } from '../utils';
|
|
3
|
-
export function inputRulePlugin(schema, featureFlags) {
|
|
4
|
-
if (!schema.nodes.media || !schema.nodes.mediaSingle) {
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
//  should convert to an image
|
|
9
|
-
const imageRule = createRule(/!\[(.*)\]\((\S+)\)$/, (state, match, start, end) => {
|
|
10
|
-
const {
|
|
11
|
-
schema
|
|
12
|
-
} = state;
|
|
13
|
-
const attrs = {
|
|
14
|
-
src: match[2],
|
|
15
|
-
alt: match[1]
|
|
16
|
-
};
|
|
17
|
-
const node = createExternalMediaNode(attrs.src, schema);
|
|
18
|
-
if (node) {
|
|
19
|
-
return state.tr.replaceWith(start, end, node);
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
});
|
|
23
|
-
return createPlugin('image-upload', [imageRule]);
|
|
24
|
-
}
|
|
25
|
-
export default inputRulePlugin;
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
-
import { isClipboardEvent, isPastedFile } from '../../../utils/clipboard';
|
|
3
|
-
import { isDragEvent, isDroppedFile } from '../../../utils/drag-drop';
|
|
4
|
-
import { canInsertMedia, isMediaSelected } from '../utils';
|
|
5
|
-
import { insertExternalImage, startImageUpload } from './commands';
|
|
6
|
-
import { stateKey } from './plugin-key';
|
|
7
|
-
/**
|
|
8
|
-
* Microsoft Office includes a screenshot image when copying text content.
|
|
9
|
-
*
|
|
10
|
-
* This function determines whether or not we can ignore the image if it
|
|
11
|
-
* came from MS Office. We do this by checking for
|
|
12
|
-
*
|
|
13
|
-
* - plain text
|
|
14
|
-
* - HTML text which includes the MS Office namespace
|
|
15
|
-
* - the number of files and the file name/type
|
|
16
|
-
*
|
|
17
|
-
* It is easy to manually verify this using by using Office on Mac
|
|
18
|
-
* (or Excel if on Windows) and pasting into
|
|
19
|
-
* https://evercoder.github.io/clipboard-inspector/
|
|
20
|
-
*
|
|
21
|
-
* Note: image content in Word is stored in the `text/html` portion
|
|
22
|
-
* of the clipboard, not under `files` attachment like the screenshot.
|
|
23
|
-
*
|
|
24
|
-
* @returns boolean True if the paste event contains a screenshot from MS Office
|
|
25
|
-
*/
|
|
26
|
-
const hasScreenshotImageFromMSOffice = ev => {
|
|
27
|
-
const {
|
|
28
|
-
clipboardData
|
|
29
|
-
} = ev;
|
|
30
|
-
if (!clipboardData || clipboardData.files.length !== 1) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
const textPlain = !!clipboardData.getData('text/plain');
|
|
34
|
-
const textHtml = clipboardData.getData('text/html');
|
|
35
|
-
const isOfficeXMLNamespace = textHtml.includes('urn:schemas-microsoft-com:office:office');
|
|
36
|
-
const file = clipboardData.files[0];
|
|
37
|
-
const isImagePNG = file.type === 'image/png' && file.name === 'image.png';
|
|
38
|
-
return isImagePNG && textPlain && isOfficeXMLNamespace;
|
|
39
|
-
};
|
|
40
|
-
const createReferenceEventFromEvent = event => {
|
|
41
|
-
var _event$dataTransfer, _event$clipboardData;
|
|
42
|
-
if (!isDragEvent(event) && !isClipboardEvent(event)) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Get files list and early exit if files is undefined
|
|
47
|
-
const files = isDragEvent(event) ? (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.files : (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.files;
|
|
48
|
-
if (!files) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Convert filelist into an array
|
|
53
|
-
const filesArray = Array.from(files);
|
|
54
|
-
|
|
55
|
-
// Creating a new DataTransfer object should remove any mutation that could be possible from the original event
|
|
56
|
-
const dataTransfer = filesArray.reduce((acc, value) => {
|
|
57
|
-
acc.items.add(value);
|
|
58
|
-
return acc;
|
|
59
|
-
}, new DataTransfer());
|
|
60
|
-
return {
|
|
61
|
-
type: isDragEvent(event) ? 'drop' : 'paste',
|
|
62
|
-
...(isDragEvent(event) && {
|
|
63
|
-
dataTransfer
|
|
64
|
-
}),
|
|
65
|
-
...(isClipboardEvent(event) && {
|
|
66
|
-
clipboardData: dataTransfer
|
|
67
|
-
})
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
const createDOMHandler = (pred, _eventName, uploadHandlerReference) => (view, event) => {
|
|
71
|
-
if (!pred(event)) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
const shouldUpload = !hasScreenshotImageFromMSOffice(event);
|
|
75
|
-
const referenceEvent = createReferenceEventFromEvent(event);
|
|
76
|
-
if (shouldUpload && referenceEvent) {
|
|
77
|
-
event.preventDefault();
|
|
78
|
-
event.stopPropagation();
|
|
79
|
-
|
|
80
|
-
// Insert external image into document
|
|
81
|
-
if (uploadHandlerReference.current) {
|
|
82
|
-
uploadHandlerReference.current(referenceEvent, options => {
|
|
83
|
-
insertExternalImage(options)(view.state, view.dispatch);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Start image upload
|
|
88
|
-
startImageUpload(referenceEvent)(view.state, view.dispatch);
|
|
89
|
-
}
|
|
90
|
-
return shouldUpload;
|
|
91
|
-
};
|
|
92
|
-
const getNewActiveUpload = (tr, pluginState) => {
|
|
93
|
-
const meta = tr.getMeta(stateKey);
|
|
94
|
-
if (meta && meta.name === 'START_UPLOAD') {
|
|
95
|
-
return {
|
|
96
|
-
event: meta.event
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
return pluginState.activeUpload;
|
|
100
|
-
};
|
|
101
|
-
export const createPlugin = uploadHandlerReference => ({
|
|
102
|
-
dispatch,
|
|
103
|
-
providerFactory
|
|
104
|
-
}) => {
|
|
105
|
-
return new SafePlugin({
|
|
106
|
-
state: {
|
|
107
|
-
init(_config, state) {
|
|
108
|
-
return {
|
|
109
|
-
active: false,
|
|
110
|
-
enabled: canInsertMedia(state),
|
|
111
|
-
hidden: !state.schema.nodes.media || !state.schema.nodes.mediaSingle
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
|
-
apply(tr, pluginState, _oldState, newState) {
|
|
115
|
-
const newActive = isMediaSelected(newState);
|
|
116
|
-
const newEnabled = canInsertMedia(newState);
|
|
117
|
-
const newActiveUpload = getNewActiveUpload(tr, pluginState);
|
|
118
|
-
if (newActive !== pluginState.active || newEnabled !== pluginState.enabled || newActiveUpload !== pluginState.activeUpload) {
|
|
119
|
-
const newPluginState = {
|
|
120
|
-
...pluginState,
|
|
121
|
-
active: newActive,
|
|
122
|
-
enabled: newEnabled,
|
|
123
|
-
activeUpload: newActiveUpload
|
|
124
|
-
};
|
|
125
|
-
dispatch(stateKey, newPluginState);
|
|
126
|
-
return newPluginState;
|
|
127
|
-
}
|
|
128
|
-
return pluginState;
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
key: stateKey,
|
|
132
|
-
view: () => {
|
|
133
|
-
const handleProvider = async (name, provider) => {
|
|
134
|
-
if (name !== 'imageUploadProvider' || !provider) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
const imageUploadProvider = await provider;
|
|
139
|
-
uploadHandlerReference.current = imageUploadProvider;
|
|
140
|
-
} catch (e) {
|
|
141
|
-
uploadHandlerReference.current = null;
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
providerFactory.subscribe('imageUploadProvider', handleProvider);
|
|
145
|
-
return {
|
|
146
|
-
destroy() {
|
|
147
|
-
uploadHandlerReference.current = null;
|
|
148
|
-
providerFactory.unsubscribe('imageUploadProvider', handleProvider);
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
},
|
|
152
|
-
props: {
|
|
153
|
-
handleDOMEvents: {
|
|
154
|
-
drop: createDOMHandler(isDroppedFile, 'atlassian.editor.image.drop', uploadHandlerReference),
|
|
155
|
-
paste: createDOMHandler(isPastedFile, 'atlassian.editor.image.paste', uploadHandlerReference)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
-
export const isMediaSelected = state => {
|
|
3
|
-
const {
|
|
4
|
-
media
|
|
5
|
-
} = state.schema.nodes;
|
|
6
|
-
return state.selection instanceof NodeSelection && state.selection.node.type === media;
|
|
7
|
-
};
|
|
8
|
-
export const canInsertMedia = state => {
|
|
9
|
-
const {
|
|
10
|
-
mediaSingle
|
|
11
|
-
} = state.schema.nodes;
|
|
12
|
-
const {
|
|
13
|
-
$to
|
|
14
|
-
} = state.selection;
|
|
15
|
-
if (mediaSingle) {
|
|
16
|
-
for (let d = $to.depth; d >= 0; d--) {
|
|
17
|
-
let index = $to.index(d);
|
|
18
|
-
if ($to.node(d).canReplaceWith(index, index, mediaSingle)) {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return false;
|
|
24
|
-
};
|
|
25
|
-
export const createExternalMediaNode = (url, schema) => {
|
|
26
|
-
const {
|
|
27
|
-
media,
|
|
28
|
-
mediaSingle
|
|
29
|
-
} = schema.nodes;
|
|
30
|
-
if (!media || !mediaSingle) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
const mediaNode = media.createChecked({
|
|
34
|
-
type: 'external',
|
|
35
|
-
url
|
|
36
|
-
});
|
|
37
|
-
return mediaSingle.createChecked({}, mediaNode);
|
|
38
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// Typeguard Function
|
|
2
|
-
export const isDragEvent = event => 'dataTransfer' in event;
|
|
3
|
-
export function isDroppedFile(rawEvent) {
|
|
4
|
-
const e = rawEvent;
|
|
5
|
-
if (!e.dataTransfer) {
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
return Array.prototype.slice.call(e.dataTransfer.types).indexOf('Files') !== -1;
|
|
9
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { createPlugin } from './pm-plugins/main';
|
|
2
|
-
import inputRulePlugin from './pm-plugins/input-rule';
|
|
3
|
-
import { stateKey } from './pm-plugins/plugin-key';
|
|
4
|
-
import { insertActionForToolbar } from './pm-plugins/commands-toolbar';
|
|
5
|
-
var imageUpload = function imageUpload() {
|
|
6
|
-
var uploadHandlerReference = {
|
|
7
|
-
current: null
|
|
8
|
-
};
|
|
9
|
-
return {
|
|
10
|
-
name: 'imageUpload',
|
|
11
|
-
getSharedState: function getSharedState(editorState) {
|
|
12
|
-
if (!editorState) {
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
15
|
-
return stateKey.getState(editorState);
|
|
16
|
-
},
|
|
17
|
-
actions: {
|
|
18
|
-
startUpload: function startUpload() {
|
|
19
|
-
return insertActionForToolbar(uploadHandlerReference);
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
pmPlugins: function pmPlugins() {
|
|
23
|
-
return [{
|
|
24
|
-
name: 'imageUpload',
|
|
25
|
-
plugin: createPlugin(uploadHandlerReference)
|
|
26
|
-
}, {
|
|
27
|
-
name: 'imageUploadInputRule',
|
|
28
|
-
plugin: function plugin(_ref) {
|
|
29
|
-
var schema = _ref.schema,
|
|
30
|
-
featureFlags = _ref.featureFlags;
|
|
31
|
-
return inputRulePlugin(schema, featureFlags);
|
|
32
|
-
}
|
|
33
|
-
}];
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
export default imageUpload;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { stateKey } from './plugin-key';
|
|
2
|
-
var imageUploadAction = function imageUploadAction(tr, action) {
|
|
3
|
-
return tr.setMeta(stateKey, action);
|
|
4
|
-
};
|
|
5
|
-
export var startUpload = function startUpload(event) {
|
|
6
|
-
return function (tr) {
|
|
7
|
-
return imageUploadAction(tr, {
|
|
8
|
-
name: 'START_UPLOAD',
|
|
9
|
-
event: event
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { insertExternalImage } from './commands';
|
|
2
|
-
export var insertActionForToolbar = function insertActionForToolbar(uploadHandlerReference) {
|
|
3
|
-
return function (state, dispatch) {
|
|
4
|
-
if (!uploadHandlerReference.current) {
|
|
5
|
-
return false;
|
|
6
|
-
}
|
|
7
|
-
uploadHandlerReference.current(undefined, function (options) {
|
|
8
|
-
insertExternalImage(options)(state, dispatch);
|
|
9
|
-
});
|
|
10
|
-
return true;
|
|
11
|
-
};
|
|
12
|
-
};
|