@atlaskit/editor-common 74.5.2 → 74.7.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 +12 -0
- package/dist/cjs/analytics/index.js +26 -1
- package/dist/cjs/analytics/linking-utils.js +84 -0
- package/dist/cjs/card/MediaAndEmbedsToolbar/index.js +156 -0
- package/dist/cjs/card/index.js +9 -1
- package/dist/cjs/messages/index.js +14 -0
- package/dist/cjs/messages/link-toolbar.js +60 -0
- package/dist/cjs/messages/media-and-embed-toolbar.js +20 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/node-width/index.js +16 -2
- package/dist/cjs/react-node-view/getInlineNodeViewProducer.js +225 -0
- package/dist/cjs/react-node-view/index.js +13 -0
- package/dist/cjs/{ui/Resizer/index.js → resizer/Resizer.js} +6 -3
- package/dist/cjs/{resizer.js → resizer/index.js} +1 -1
- package/dist/cjs/resizer/utils.js +21 -0
- package/dist/cjs/styles/shared/resizer.js +1 -1
- package/dist/cjs/styles/shared/table.js +5 -4
- package/dist/cjs/types/hyperlink.js +5 -0
- package/dist/cjs/types/resizable-media-single.js +5 -0
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/ui/LinkSearch/const.js +14 -0
- package/dist/cjs/ui/ResizerLegacy/index.js +210 -0
- package/dist/cjs/ui/ResizerLegacy/styled.js +15 -0
- package/dist/cjs/ui/ResizerLegacy/types.js +5 -0
- package/dist/cjs/ui/ResizerLegacy/utils.js +21 -0
- package/dist/cjs/ui/index.js +58 -0
- package/dist/cjs/utils/document.js +258 -0
- package/dist/cjs/utils/editor-core-utils.js +7 -2
- package/dist/cjs/utils/filter/privacy-filter.js +55 -0
- package/dist/cjs/utils/index.js +75 -0
- package/dist/cjs/utils/rich-media-utils.js +131 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics/index.js +2 -1
- package/dist/es2019/analytics/linking-utils.js +74 -0
- package/dist/es2019/card/MediaAndEmbedsToolbar/index.js +161 -0
- package/dist/es2019/card/index.js +2 -1
- package/dist/es2019/messages/index.js +2 -0
- package/dist/es2019/messages/link-toolbar.js +53 -0
- package/dist/es2019/messages/media-and-embed-toolbar.js +13 -0
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/node-width/index.js +12 -1
- package/dist/es2019/react-node-view/getInlineNodeViewProducer.js +219 -0
- package/dist/es2019/react-node-view/index.js +1 -0
- package/dist/es2019/{ui/Resizer/index.js → resizer/Resizer.js} +5 -3
- package/dist/es2019/resizer/index.js +1 -0
- package/dist/es2019/resizer/utils.js +12 -0
- package/dist/es2019/styles/shared/resizer.js +8 -4
- package/dist/es2019/styles/shared/table.js +5 -4
- package/dist/es2019/types/resizable-media-single.js +1 -0
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/ui/LinkSearch/const.js +4 -0
- package/dist/es2019/ui/ResizerLegacy/index.js +191 -0
- package/dist/es2019/ui/ResizerLegacy/styled.js +15 -0
- package/dist/es2019/ui/ResizerLegacy/types.js +1 -0
- package/dist/es2019/ui/ResizerLegacy/utils.js +12 -0
- package/dist/es2019/ui/index.js +5 -1
- package/dist/es2019/utils/document.js +253 -0
- package/dist/es2019/utils/editor-core-utils.js +4 -0
- package/dist/es2019/utils/filter/privacy-filter.js +47 -0
- package/dist/es2019/utils/index.js +5 -2
- package/dist/es2019/utils/rich-media-utils.js +109 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics/index.js +2 -1
- package/dist/esm/analytics/linking-utils.js +74 -0
- package/dist/esm/card/MediaAndEmbedsToolbar/index.js +146 -0
- package/dist/esm/card/index.js +2 -1
- package/dist/esm/messages/index.js +2 -0
- package/dist/esm/messages/link-toolbar.js +53 -0
- package/dist/esm/messages/media-and-embed-toolbar.js +13 -0
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/node-width/index.js +12 -1
- package/dist/esm/react-node-view/getInlineNodeViewProducer.js +215 -0
- package/dist/esm/react-node-view/index.js +1 -0
- package/dist/esm/{ui/Resizer/index.js → resizer/Resizer.js} +6 -3
- package/dist/esm/resizer/index.js +1 -0
- package/dist/esm/resizer/types.js +1 -0
- package/dist/esm/resizer/utils.js +12 -0
- package/dist/esm/styles/shared/resizer.js +1 -1
- package/dist/esm/styles/shared/table.js +5 -4
- package/dist/esm/types/hyperlink.js +1 -0
- package/dist/esm/types/resizable-media-single.js +1 -0
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/ui/LinkSearch/const.js +4 -0
- package/dist/esm/ui/ResizerLegacy/index.js +203 -0
- package/dist/esm/ui/ResizerLegacy/styled.js +7 -0
- package/dist/esm/ui/ResizerLegacy/types.js +1 -0
- package/dist/esm/ui/ResizerLegacy/utils.js +12 -0
- package/dist/esm/ui/index.js +5 -1
- package/dist/esm/utils/document.js +246 -0
- package/dist/esm/utils/editor-core-utils.js +4 -0
- package/dist/esm/utils/filter/privacy-filter.js +48 -0
- package/dist/esm/utils/index.js +5 -2
- package/dist/esm/utils/rich-media-utils.js +118 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/linking-utils.d.ts +14 -0
- package/dist/types/card/MediaAndEmbedsToolbar/index.d.ts +11 -0
- package/dist/types/card/index.d.ts +1 -0
- package/dist/types/messages/index.d.ts +2 -0
- package/dist/types/messages/link-toolbar.d.ts +52 -0
- package/dist/types/messages/media-and-embed-toolbar.d.ts +12 -0
- package/dist/types/node-width/index.d.ts +7 -0
- package/dist/types/react-node-view/getInlineNodeViewProducer.d.ts +25 -0
- package/dist/types/react-node-view/index.d.ts +3 -0
- package/dist/types/{ui/Resizer/index.d.ts → resizer/Resizer.d.ts} +1 -0
- package/dist/types/resizer/index.d.ts +2 -0
- package/dist/types/resizer/utils.d.ts +6 -0
- package/dist/types/styles/shared/table.d.ts +2 -1
- package/dist/types/types/hyperlink.d.ts +35 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/resizable-media-single.d.ts +15 -0
- package/dist/types/ui/DropList/index.d.ts +1 -1
- package/dist/types/ui/LinkSearch/const.d.ts +4 -0
- package/dist/types/ui/ResizerLegacy/index.d.ts +40 -0
- package/dist/types/ui/ResizerLegacy/styled.d.ts +2 -0
- package/dist/types/ui/ResizerLegacy/types.d.ts +26 -0
- package/dist/types/ui/ResizerLegacy/utils.d.ts +6 -0
- package/dist/types/ui/index.d.ts +6 -0
- package/dist/types/utils/document.d.ts +19 -0
- package/dist/types/utils/editor-core-utils.d.ts +1 -0
- package/dist/types/utils/filter/privacy-filter.d.ts +9 -0
- package/dist/types/utils/index.d.ts +4 -1
- package/dist/types/utils/rich-media-utils.d.ts +8 -0
- package/dist/types-ts4.5/analytics/index.d.ts +2 -0
- package/dist/types-ts4.5/analytics/linking-utils.d.ts +14 -0
- package/dist/types-ts4.5/card/MediaAndEmbedsToolbar/index.d.ts +11 -0
- package/dist/types-ts4.5/card/index.d.ts +1 -0
- package/dist/types-ts4.5/messages/index.d.ts +2 -0
- package/dist/types-ts4.5/messages/link-toolbar.d.ts +52 -0
- package/dist/types-ts4.5/messages/media-and-embed-toolbar.d.ts +12 -0
- package/dist/types-ts4.5/node-width/index.d.ts +7 -0
- package/dist/types-ts4.5/react-node-view/getInlineNodeViewProducer.d.ts +25 -0
- package/dist/types-ts4.5/react-node-view/index.d.ts +3 -0
- package/dist/types-ts4.5/{ui/Resizer/index.d.ts → resizer/Resizer.d.ts} +1 -0
- package/dist/types-ts4.5/resizer/index.d.ts +2 -0
- package/dist/types-ts4.5/resizer/utils.d.ts +6 -0
- package/dist/types-ts4.5/styles/shared/table.d.ts +2 -1
- package/dist/types-ts4.5/types/hyperlink.d.ts +35 -0
- package/dist/types-ts4.5/types/index.d.ts +2 -0
- package/dist/types-ts4.5/types/resizable-media-single.d.ts +15 -0
- package/dist/types-ts4.5/ui/DropList/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/LinkSearch/const.d.ts +4 -0
- package/dist/types-ts4.5/ui/ResizerLegacy/index.d.ts +40 -0
- package/dist/types-ts4.5/ui/ResizerLegacy/styled.d.ts +2 -0
- package/dist/types-ts4.5/ui/ResizerLegacy/types.d.ts +26 -0
- package/dist/types-ts4.5/ui/ResizerLegacy/utils.d.ts +6 -0
- package/dist/types-ts4.5/ui/index.d.ts +6 -0
- package/dist/types-ts4.5/utils/document.d.ts +19 -0
- package/dist/types-ts4.5/utils/editor-core-utils.d.ts +1 -0
- package/dist/types-ts4.5/utils/filter/privacy-filter.d.ts +9 -0
- package/dist/types-ts4.5/utils/index.d.ts +4 -1
- package/dist/types-ts4.5/utils/rich-media-utils.d.ts +8 -0
- package/package.json +9 -9
- package/resizer/package.json +5 -5
- package/dist/cjs/ui/Resizer/utils.js +0 -8
- package/dist/es2019/resizer.js +0 -1
- package/dist/es2019/ui/Resizer/utils.js +0 -1
- package/dist/esm/resizer.js +0 -1
- package/dist/esm/ui/Resizer/utils.js +0 -1
- package/dist/types/resizer.d.ts +0 -2
- package/dist/types/ui/Resizer/utils.d.ts +0 -1
- package/dist/types-ts4.5/resizer.d.ts +0 -2
- package/dist/types-ts4.5/ui/Resizer/utils.d.ts +0 -1
- /package/dist/cjs/{ui/Resizer → resizer}/types.js +0 -0
- /package/dist/es2019/{ui/Resizer → resizer}/types.js +0 -0
- /package/dist/{esm/ui/Resizer/types.js → es2019/types/hyperlink.js} +0 -0
- /package/dist/types/{ui/Resizer → resizer}/types.d.ts +0 -0
- /package/dist/types-ts4.5/{ui/Resizer → resizer}/types.d.ts +0 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { Node } from 'prosemirror-model';
|
|
2
|
+
import { transformDedupeMarks, transformIndentationMarks, transformInvalidMediaContent, transformMediaLinkMarks, transformNodesMissingContent, transformTextLinkCodeMarks } from '@atlaskit/adf-utils/transforms';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../analytics';
|
|
4
|
+
import { isEmptyParagraph } from './editor-core-utils';
|
|
5
|
+
import { sanitizeNodeForPrivacy } from './filter/privacy-filter';
|
|
6
|
+
import { findAndTrackUnsupportedContentNodes } from './track-unsupported-content';
|
|
7
|
+
import { validateADFEntity } from './validate-using-spec';
|
|
8
|
+
export const getStepRange = transaction => {
|
|
9
|
+
let from = -1;
|
|
10
|
+
let to = -1;
|
|
11
|
+
transaction.mapping.maps.forEach((stepMap, index) => {
|
|
12
|
+
stepMap.forEach((oldStart, oldEnd) => {
|
|
13
|
+
const newStart = transaction.mapping.slice(index).map(oldStart, -1);
|
|
14
|
+
const newEnd = transaction.mapping.slice(index).map(oldEnd);
|
|
15
|
+
from = newStart < from || from === -1 ? newStart : from;
|
|
16
|
+
to = newEnd > to || to === -1 ? newEnd : to;
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
if (from !== -1) {
|
|
20
|
+
return {
|
|
21
|
+
from,
|
|
22
|
+
to
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Checks to see if the parent node is the document, ie not contained within another entity
|
|
29
|
+
export function hasDocAsParent($anchor) {
|
|
30
|
+
return $anchor.depth === 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Checks if a node looks like an empty document
|
|
35
|
+
*/
|
|
36
|
+
export function isEmptyDocument(node) {
|
|
37
|
+
const nodeChild = node.content.firstChild;
|
|
38
|
+
if (node.childCount !== 1 || !nodeChild) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return isEmptyParagraph(nodeChild);
|
|
42
|
+
}
|
|
43
|
+
export function bracketTyped(state) {
|
|
44
|
+
const {
|
|
45
|
+
selection
|
|
46
|
+
} = state;
|
|
47
|
+
const {
|
|
48
|
+
$cursor,
|
|
49
|
+
$anchor
|
|
50
|
+
} = selection;
|
|
51
|
+
if (!$cursor) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const node = $cursor.nodeBefore;
|
|
55
|
+
if (!node) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (node.type.name === 'text' && node.text === '{') {
|
|
59
|
+
const paragraphNode = $anchor.node();
|
|
60
|
+
return paragraphNode.marks.length === 0 && hasDocAsParent($anchor);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
export function nodesBetweenChanged(tr, f, startPos) {
|
|
65
|
+
const stepRange = getStepRange(tr);
|
|
66
|
+
if (!stepRange) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
tr.doc.nodesBetween(stepRange.from, stepRange.to, f, startPos);
|
|
70
|
+
}
|
|
71
|
+
export function processRawValue(schema, value, providerFactory, sanitizePrivateContent, contentTransformer, dispatchAnalyticsEvent) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let node;
|
|
76
|
+
if (typeof value === 'string') {
|
|
77
|
+
try {
|
|
78
|
+
if (contentTransformer) {
|
|
79
|
+
const doc = contentTransformer.parse(value);
|
|
80
|
+
node = doc.toJSON();
|
|
81
|
+
} else {
|
|
82
|
+
node = JSON.parse(value);
|
|
83
|
+
}
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// eslint-disable-next-line no-console
|
|
86
|
+
console.error(`Error processing value: ${value} isn't a valid JSON`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
node = value;
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(node)) {
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
console.error(`Error processing value: ${node} is an array, but it must be an object.`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
// ProseMirror always require a child under doc
|
|
99
|
+
if (node.type === 'doc') {
|
|
100
|
+
if (Array.isArray(node.content) && node.content.length === 0) {
|
|
101
|
+
node.content.push({
|
|
102
|
+
type: 'paragraph',
|
|
103
|
+
content: []
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Just making sure doc is always valid
|
|
107
|
+
if (!node.version) {
|
|
108
|
+
node.version = 1;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (contentTransformer) {
|
|
112
|
+
return Node.fromJSON(schema, node);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// link mark on mediaSingle is deprecated, need to move link mark to child media node
|
|
116
|
+
// https://product-fabric.atlassian.net/browse/ED-14043
|
|
117
|
+
let {
|
|
118
|
+
transformedAdf,
|
|
119
|
+
isTransformed
|
|
120
|
+
} = transformMediaLinkMarks(node);
|
|
121
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
122
|
+
dispatchAnalyticsEvent({
|
|
123
|
+
action: ACTION.MEDIA_LINK_TRANSFORMED,
|
|
124
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
125
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// See: HOT-97965 https://product-fabric.atlassian.net/browse/ED-14400
|
|
130
|
+
// We declared in code mark spec that links and marks should not co-exist on
|
|
131
|
+
// text nodes. This util strips code marks from bad text nodes and preserves links.
|
|
132
|
+
// Otherwise, prosemirror will try to repair the invalid document by stripping links
|
|
133
|
+
// and preserving code marks during content changes.
|
|
134
|
+
({
|
|
135
|
+
transformedAdf,
|
|
136
|
+
isTransformed
|
|
137
|
+
} = transformTextLinkCodeMarks(transformedAdf));
|
|
138
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
139
|
+
dispatchAnalyticsEvent({
|
|
140
|
+
action: ACTION.TEXT_LINK_MARK_TRANSFORMED,
|
|
141
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
142
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
let discardedMarks = [];
|
|
146
|
+
({
|
|
147
|
+
transformedAdf,
|
|
148
|
+
isTransformed,
|
|
149
|
+
discardedMarks
|
|
150
|
+
} = transformDedupeMarks(transformedAdf));
|
|
151
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
152
|
+
dispatchAnalyticsEvent({
|
|
153
|
+
action: ACTION.DEDUPE_MARKS_TRANSFORMED_V2,
|
|
154
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
155
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
156
|
+
attributes: {
|
|
157
|
+
/** UGC WARNING
|
|
158
|
+
*
|
|
159
|
+
* DO NOT include the `mark` attributes inside, we map here to only
|
|
160
|
+
* extract the mark type as that is the only non-UGC safe information
|
|
161
|
+
* that we can add to event-attributes
|
|
162
|
+
*
|
|
163
|
+
*/
|
|
164
|
+
discardedMarkTypes: discardedMarks.map(mark => mark.type)
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
({
|
|
169
|
+
transformedAdf,
|
|
170
|
+
isTransformed
|
|
171
|
+
} = transformNodesMissingContent(transformedAdf));
|
|
172
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
173
|
+
dispatchAnalyticsEvent({
|
|
174
|
+
action: ACTION.NODES_MISSING_CONTENT_TRANSFORMED,
|
|
175
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
176
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
({
|
|
180
|
+
transformedAdf,
|
|
181
|
+
isTransformed
|
|
182
|
+
} = transformIndentationMarks(transformedAdf));
|
|
183
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
184
|
+
dispatchAnalyticsEvent({
|
|
185
|
+
action: ACTION.INDENTATION_MARKS_TRANSFORMED,
|
|
186
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
187
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
({
|
|
191
|
+
transformedAdf,
|
|
192
|
+
isTransformed
|
|
193
|
+
} = transformInvalidMediaContent(transformedAdf));
|
|
194
|
+
if (isTransformed && dispatchAnalyticsEvent) {
|
|
195
|
+
dispatchAnalyticsEvent({
|
|
196
|
+
action: ACTION.INVALID_MEDIA_CONTENT_TRANSFORMED,
|
|
197
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
198
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const entity = validateADFEntity(schema, transformedAdf || node, dispatchAnalyticsEvent);
|
|
202
|
+
let newEntity = maySanitizePrivateContent(entity, providerFactory, sanitizePrivateContent);
|
|
203
|
+
const parsedDoc = Node.fromJSON(schema, newEntity);
|
|
204
|
+
|
|
205
|
+
// throws an error if the document is invalid
|
|
206
|
+
try {
|
|
207
|
+
parsedDoc.check();
|
|
208
|
+
} catch (err) {
|
|
209
|
+
if (dispatchAnalyticsEvent) {
|
|
210
|
+
dispatchAnalyticsEvent({
|
|
211
|
+
action: ACTION.INVALID_PROSEMIRROR_DOCUMENT,
|
|
212
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
213
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
214
|
+
attributes: {
|
|
215
|
+
errorStack: err instanceof Error ? err.stack : String(err)
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
if (dispatchAnalyticsEvent) {
|
|
222
|
+
findAndTrackUnsupportedContentNodes(parsedDoc, schema, dispatchAnalyticsEvent);
|
|
223
|
+
}
|
|
224
|
+
return parsedDoc;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
if (dispatchAnalyticsEvent) {
|
|
227
|
+
dispatchAnalyticsEvent({
|
|
228
|
+
action: ACTION.DOCUMENT_PROCESSING_ERROR,
|
|
229
|
+
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
230
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
231
|
+
nonPrivacySafeAttributes: {
|
|
232
|
+
errorStack: e instanceof Error ? e.stack : String(e)
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// eslint-disable-next-line no-console
|
|
238
|
+
console.error(`Error processing document:\n${e instanceof Error ? e.message : String(e)}\n\n`, JSON.stringify(node));
|
|
239
|
+
if (isProseMirrorSchemaCheckError(e)) {
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function isProseMirrorSchemaCheckError(error) {
|
|
246
|
+
return error instanceof RangeError && (!!error.message.match(/^Invalid collection of marks for node/) || !!error.message.match(/^Invalid content for node/));
|
|
247
|
+
}
|
|
248
|
+
const maySanitizePrivateContent = (entity, providerFactory, sanitizePrivateContent) => {
|
|
249
|
+
if (sanitizePrivateContent && providerFactory) {
|
|
250
|
+
return sanitizeNodeForPrivacy(entity, providerFactory);
|
|
251
|
+
}
|
|
252
|
+
return entity;
|
|
253
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NodeSelection, TextSelection } from 'prosemirror-state';
|
|
2
2
|
import { ReplaceAroundStep, ReplaceStep } from 'prosemirror-transform';
|
|
3
|
+
import { hasParentNodeOfType } from 'prosemirror-utils';
|
|
3
4
|
import { closest } from './dom';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -78,4 +79,7 @@ export const isValidPosition = (pos, state) => {
|
|
|
78
79
|
return true;
|
|
79
80
|
}
|
|
80
81
|
return false;
|
|
82
|
+
};
|
|
83
|
+
export const isInLayoutColumn = state => {
|
|
84
|
+
return hasParentNodeOfType(state.schema.nodes.layoutSection)(state.selection);
|
|
81
85
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { traverse } from '@atlaskit/adf-utils/traverse';
|
|
2
|
+
import { isResolvingMentionProvider } from '@atlaskit/mention/resource';
|
|
3
|
+
/**
|
|
4
|
+
* Sanitises a document where some content should not be in the document (e.g. mention names).
|
|
5
|
+
*
|
|
6
|
+
* It is expected that these names we be resolved separately (e.g. when rendering
|
|
7
|
+
* a node view).
|
|
8
|
+
*/
|
|
9
|
+
export function sanitizeNodeForPrivacy(json, providerFactory) {
|
|
10
|
+
const mentionNames = new Map();
|
|
11
|
+
let hasCacheableMentions = false;
|
|
12
|
+
const sanitizedJSON = traverse(json, {
|
|
13
|
+
mention: node => {
|
|
14
|
+
if (node.attrs && node.attrs.text) {
|
|
15
|
+
hasCacheableMentions = true;
|
|
16
|
+
// Remove @ prefix
|
|
17
|
+
const text = node.attrs.text;
|
|
18
|
+
const name = text.startsWith('@') ? text.slice(1) : text;
|
|
19
|
+
mentionNames.set(node.attrs.id, name);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
...node,
|
|
23
|
+
attrs: {
|
|
24
|
+
...node.attrs,
|
|
25
|
+
text: ''
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
if (hasCacheableMentions && providerFactory) {
|
|
31
|
+
const handler = (_name, providerPromise) => {
|
|
32
|
+
if (providerPromise) {
|
|
33
|
+
providerPromise.then(provider => {
|
|
34
|
+
if (isResolvingMentionProvider(provider)) {
|
|
35
|
+
mentionNames.forEach((name, id) => {
|
|
36
|
+
provider.cacheMentionName(id, name);
|
|
37
|
+
});
|
|
38
|
+
mentionNames.clear();
|
|
39
|
+
providerFactory.unsubscribe('mentionProvider', handler);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
providerFactory.subscribe('mentionProvider', handler);
|
|
45
|
+
}
|
|
46
|
+
return sanitizedJSON;
|
|
47
|
+
}
|
|
@@ -3,7 +3,7 @@ export { getExtensionLozengeData } from './macro';
|
|
|
3
3
|
export { default as browser } from './browser';
|
|
4
4
|
export { default as ErrorReporter } from './error-reporter';
|
|
5
5
|
export { isPastDate, timestampToIsoFormat, timestampToString, timestampToTaskContext, timestampToUTCDate, todayTimestampInUTC } from './date';
|
|
6
|
-
export { isElementInTableCell, isTextSelection, isLastItemMediaGroup, setNodeSelection, setTextSelection, nonNullable, stepAddsOneOf, stepHasSlice, extractSliceFromStep, isValidPosition, isEmptyParagraph } from './editor-core-utils';
|
|
6
|
+
export { isElementInTableCell, isTextSelection, isLastItemMediaGroup, setNodeSelection, setTextSelection, nonNullable, stepAddsOneOf, stepHasSlice, extractSliceFromStep, isValidPosition, isEmptyParagraph, isInLayoutColumn } from './editor-core-utils';
|
|
7
7
|
export { withImageLoader } from './imageLoader';
|
|
8
8
|
export { absoluteBreakoutWidth, calcBreakoutWidth, calcWideWidth, breakoutConsts, calculateBreakoutStyles, calcBreakoutWidthPx } from './breakout';
|
|
9
9
|
export { findChangedNodesFromTransaction, validNode, validateNodes, isType, isParagraph, isText, isLinkMark, SelectedState, isNodeSelectedOrInRange, isSupportedInParent, isMediaNode, isNodeBeforeMediaNode } from './nodes';
|
|
@@ -39,4 +39,7 @@ export { isFromCurrentDomain, LinkMatcher, normalizeUrl, linkifyContent, getLink
|
|
|
39
39
|
|
|
40
40
|
// prosemirror-history does not export its plugin key
|
|
41
41
|
export const pmHistoryPluginKey = 'history$';
|
|
42
|
-
export { gridTypeForLayout } from './grid';
|
|
42
|
+
export { gridTypeForLayout } from './grid';
|
|
43
|
+
export { nodesBetweenChanged, getStepRange, isEmptyDocument, processRawValue, hasDocAsParent, bracketTyped } from './document';
|
|
44
|
+
export { floatingLayouts, isRichMediaInsideOfBlockNode, calculateSnapPoints, alignAttributes } from './rich-media-utils';
|
|
45
|
+
export { sanitizeNodeForPrivacy } from './filter/privacy-filter';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { findParentNodeOfTypeClosestToPos } from 'prosemirror-utils';
|
|
2
|
+
import { akEditorBreakoutPadding } from '@atlaskit/editor-shared-styles';
|
|
3
|
+
import { shouldAddDefaultWrappedWidth } from '../ui/MediaSingle';
|
|
4
|
+
import { calcPxFromColumns, wrappedLayouts } from '../ui/MediaSingle/grid';
|
|
5
|
+
export const nonWrappedLayouts = ['center', 'wide', 'full-width'];
|
|
6
|
+
export const floatingLayouts = ['wrap-left', 'wrap-right'];
|
|
7
|
+
export const isRichMediaInsideOfBlockNode = (view, pos) => {
|
|
8
|
+
if (typeof pos !== 'number' || isNaN(pos) || !view) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const $pos = view.state.doc.resolve(pos);
|
|
12
|
+
const {
|
|
13
|
+
expand,
|
|
14
|
+
nestedExpand,
|
|
15
|
+
layoutColumn
|
|
16
|
+
} = view.state.schema.nodes;
|
|
17
|
+
return !!findParentNodeOfTypeClosestToPos($pos, [expand, nestedExpand, layoutColumn]);
|
|
18
|
+
};
|
|
19
|
+
export const alignAttributes = (layout, oldAttrs, gridSize = 12, originalWidth, lineLength) => {
|
|
20
|
+
let width = oldAttrs.width;
|
|
21
|
+
const oldLayout = oldAttrs.layout;
|
|
22
|
+
const oldLayoutIsNonWrapped = nonWrappedLayouts.indexOf(oldLayout) > -1;
|
|
23
|
+
const newLayoutIsNonWrapped = nonWrappedLayouts.indexOf(layout) > -1;
|
|
24
|
+
const newLayoutIsWrapped = wrappedLayouts.indexOf(layout) > -1;
|
|
25
|
+
const oldLayoutIsWrapped = wrappedLayouts.indexOf(oldLayout) > -1;
|
|
26
|
+
if (oldLayoutIsNonWrapped && shouldAddDefaultWrappedWidth(layout, originalWidth, lineLength)) {
|
|
27
|
+
// 'full-width' or 'wide' or 'center' -> 'wrap-left' or 'wrap-right' or 'align-end' or 'align-start'
|
|
28
|
+
if (!width || width >= 100 || oldLayout !== 'center' // == 'full-width' or 'wide'
|
|
29
|
+
) {
|
|
30
|
+
width = 50;
|
|
31
|
+
}
|
|
32
|
+
} else if (layout !== oldLayout && ['full-width', 'wide'].indexOf(oldLayout) > -1) {
|
|
33
|
+
// 'full-width' -> 'center' or 'wide'
|
|
34
|
+
// 'wide' -> 'center' or 'full-width'
|
|
35
|
+
// unset width
|
|
36
|
+
width = undefined;
|
|
37
|
+
} else if (width) {
|
|
38
|
+
const cols = Math.round(width / 100 * gridSize);
|
|
39
|
+
let targetCols = cols;
|
|
40
|
+
if (oldLayoutIsWrapped && newLayoutIsNonWrapped) {
|
|
41
|
+
// wrap -> center needs to align to even grid
|
|
42
|
+
targetCols = Math.floor(targetCols / 2) * 2;
|
|
43
|
+
width = undefined;
|
|
44
|
+
} else if (oldLayoutIsNonWrapped && newLayoutIsWrapped) {
|
|
45
|
+
// Can be here only if
|
|
46
|
+
// 'full-width' or 'wide' or 'center' -> 'wrap-left' or 'wrap-right' or 'align-end' or 'align-start'
|
|
47
|
+
// AND
|
|
48
|
+
// !originalWidth || !lineLength || small image
|
|
49
|
+
// AND
|
|
50
|
+
// width defined!
|
|
51
|
+
|
|
52
|
+
// cannot resize to full column width, and cannot resize to 1 column
|
|
53
|
+
if (cols <= 1) {
|
|
54
|
+
targetCols = 2;
|
|
55
|
+
} else if (cols >= gridSize) {
|
|
56
|
+
targetCols = 10;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (targetCols !== cols) {
|
|
60
|
+
width = targetCols / gridSize * 100;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
...oldAttrs,
|
|
65
|
+
layout,
|
|
66
|
+
width
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export function calculateSnapPoints({
|
|
70
|
+
$pos,
|
|
71
|
+
akEditorWideLayoutWidth,
|
|
72
|
+
allowBreakoutSnapPoints,
|
|
73
|
+
containerWidth,
|
|
74
|
+
gridSize,
|
|
75
|
+
gridWidth,
|
|
76
|
+
insideInlineLike,
|
|
77
|
+
insideLayout,
|
|
78
|
+
isVideoFile,
|
|
79
|
+
lineLength,
|
|
80
|
+
offsetLeft,
|
|
81
|
+
wrappedLayout
|
|
82
|
+
}) {
|
|
83
|
+
const snapTargets = [];
|
|
84
|
+
for (let i = 0; i < gridWidth; i++) {
|
|
85
|
+
const pxFromColumns = calcPxFromColumns(i, lineLength, gridWidth);
|
|
86
|
+
snapTargets.push(insideLayout ? pxFromColumns : pxFromColumns - offsetLeft);
|
|
87
|
+
}
|
|
88
|
+
// full width
|
|
89
|
+
snapTargets.push(lineLength - offsetLeft);
|
|
90
|
+
const columns = wrappedLayout || insideInlineLike ? 1 : 2;
|
|
91
|
+
const minimumWidth = calcPxFromColumns(columns, lineLength, gridSize);
|
|
92
|
+
let snapPoints = snapTargets.filter(width => width >= minimumWidth);
|
|
93
|
+
if (!$pos) {
|
|
94
|
+
return snapPoints;
|
|
95
|
+
}
|
|
96
|
+
snapPoints = isVideoFile ? snapPoints.filter(width => width > 320) : snapPoints;
|
|
97
|
+
const isTopLevel = $pos.parent.type.name === 'doc';
|
|
98
|
+
if (isTopLevel && allowBreakoutSnapPoints) {
|
|
99
|
+
snapPoints.push(akEditorWideLayoutWidth);
|
|
100
|
+
const fullWidthPoint = containerWidth - akEditorBreakoutPadding;
|
|
101
|
+
if (fullWidthPoint > akEditorWideLayoutWidth) {
|
|
102
|
+
snapPoints.push(fullWidthPoint);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// EDM-1107: Ensure new snapPoints are sorted with existing points
|
|
107
|
+
snapPoints = snapPoints.sort((a, b) => a - b);
|
|
108
|
+
return snapPoints;
|
|
109
|
+
}
|
package/dist/es2019/version.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, BROWSER_FREEZE_INTERACTION_TYPE, CONTENT_COMPONENT, DELETE_DIRECTION, EVENT_TYPE, FLOATING_CONTROLS_TITLE, FULL_WIDTH_MODE, GAP_CURSOR_POSITION, INDENT_DIRECTION, INDENT_TYPE, INPUT_METHOD, LAYOUT_TYPE, LINK_REPRESENTATION, LINK_RESOURCE, LINK_STATUS, LIST_TEXT_SCENARIOS, JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST, OUTDENT_SCENARIOS, MODE, PLATFORMS, PUNC, PasteContents, PasteSources, PasteTypes, RESOLVE_METHOD, SELECTION_TYPE, SELECTION_POSITION, SMART_LINK_TYPE, SYMBOL, SmartLinkNodeContexts, TABLE_ACTION, TABLE_BREAKOUT, TARGET_SELECTION_SOURCE, TOOLBAR_ACTION_SUBJECT_ID, TRIGGER_METHOD, USER_CONTEXT } from './types';
|
|
2
2
|
export { fireAnalyticsEvent } from './fire-analytics-event';
|
|
3
|
-
export { getAnalyticsEventsFromTransaction } from './utils';
|
|
3
|
+
export { getAnalyticsEventsFromTransaction } from './utils';
|
|
4
|
+
export { buildEditLinkPayload, buildVisitedLinkPayload, buildOpenedSettingsPayload, unlinkPayload } from './linking-utils';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from './types';
|
|
2
|
+
export var buildEditLinkPayload = function buildEditLinkPayload(type) {
|
|
3
|
+
return {
|
|
4
|
+
action: ACTION.CLICKED,
|
|
5
|
+
actionSubject: type === ACTION_SUBJECT_ID.HYPERLINK ? ACTION_SUBJECT.HYPERLINK : ACTION_SUBJECT.SMART_LINK,
|
|
6
|
+
actionSubjectId: ACTION_SUBJECT_ID.EDIT_LINK,
|
|
7
|
+
attributes: type !== ACTION_SUBJECT_ID.HYPERLINK ? {
|
|
8
|
+
display: type
|
|
9
|
+
} : {},
|
|
10
|
+
eventType: EVENT_TYPE.UI
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
var mapLinkTypeToCardAppearance = function mapLinkTypeToCardAppearance(type) {
|
|
14
|
+
switch (type) {
|
|
15
|
+
case ACTION_SUBJECT_ID.CARD_INLINE:
|
|
16
|
+
{
|
|
17
|
+
return 'inline';
|
|
18
|
+
}
|
|
19
|
+
case ACTION_SUBJECT_ID.CARD_BLOCK:
|
|
20
|
+
{
|
|
21
|
+
return 'block';
|
|
22
|
+
}
|
|
23
|
+
case ACTION_SUBJECT_ID.EMBEDS:
|
|
24
|
+
{
|
|
25
|
+
return 'embed';
|
|
26
|
+
}
|
|
27
|
+
default:
|
|
28
|
+
{
|
|
29
|
+
return 'url';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export var buildVisitedLinkPayload = function buildVisitedLinkPayload(type) {
|
|
34
|
+
return type === ACTION_SUBJECT_ID.HYPERLINK ? {
|
|
35
|
+
action: ACTION.VISITED,
|
|
36
|
+
actionSubject: ACTION_SUBJECT.HYPERLINK,
|
|
37
|
+
actionSubjectId: undefined,
|
|
38
|
+
attributes: {
|
|
39
|
+
inputMethod: INPUT_METHOD.TOOLBAR
|
|
40
|
+
},
|
|
41
|
+
eventType: EVENT_TYPE.TRACK
|
|
42
|
+
} : {
|
|
43
|
+
action: ACTION.VISITED,
|
|
44
|
+
actionSubject: ACTION_SUBJECT.SMART_LINK,
|
|
45
|
+
actionSubjectId: type,
|
|
46
|
+
attributes: {
|
|
47
|
+
inputMethod: INPUT_METHOD.TOOLBAR
|
|
48
|
+
},
|
|
49
|
+
eventType: EVENT_TYPE.TRACK
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export var buildOpenedSettingsPayload = function buildOpenedSettingsPayload(type) {
|
|
53
|
+
return {
|
|
54
|
+
action: ACTION.CLICKED,
|
|
55
|
+
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
56
|
+
actionSubjectId: ACTION_SUBJECT_ID.GOTO_SMART_LINK_SETTINGS,
|
|
57
|
+
attributes: {
|
|
58
|
+
inputMethod: INPUT_METHOD.TOOLBAR,
|
|
59
|
+
display: mapLinkTypeToCardAppearance(type)
|
|
60
|
+
},
|
|
61
|
+
eventType: EVENT_TYPE.UI
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export var unlinkPayload = function unlinkPayload(type) {
|
|
65
|
+
return {
|
|
66
|
+
action: ACTION.UNLINK,
|
|
67
|
+
actionSubject: type === ACTION_SUBJECT_ID.HYPERLINK ? ACTION_SUBJECT.HYPERLINK : ACTION_SUBJECT.SMART_LINK,
|
|
68
|
+
actionSubjectId: type === ACTION_SUBJECT_ID.HYPERLINK ? undefined : type,
|
|
69
|
+
attributes: {
|
|
70
|
+
inputMethod: INPUT_METHOD.TOOLBAR
|
|
71
|
+
},
|
|
72
|
+
eventType: EVENT_TYPE.TRACK
|
|
73
|
+
};
|
|
74
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import { NodeSelection } from 'prosemirror-state';
|
|
3
|
+
import { hasParentNodeOfType } from 'prosemirror-utils';
|
|
4
|
+
import { DEFAULT_EMBED_CARD_WIDTH } from '@atlaskit/editor-shared-styles';
|
|
5
|
+
import EditorAlignImageCenter from '@atlaskit/icon/glyph/editor/align-image-center';
|
|
6
|
+
import EditorAlignImageLeft from '@atlaskit/icon/glyph/editor/align-image-left';
|
|
7
|
+
import EditorAlignImageRight from '@atlaskit/icon/glyph/editor/align-image-right';
|
|
8
|
+
import FullWidthIcon from '@atlaskit/icon/glyph/editor/media-full-width';
|
|
9
|
+
import WideIcon from '@atlaskit/icon/glyph/editor/media-wide';
|
|
10
|
+
import WrapLeftIcon from '@atlaskit/icon/glyph/editor/media-wrap-left';
|
|
11
|
+
import WrapRightIcon from '@atlaskit/icon/glyph/editor/media-wrap-right';
|
|
12
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../../analytics';
|
|
13
|
+
import { insideTable } from '../../core-utils';
|
|
14
|
+
import commonMessages, { mediaAndEmbedToolbarMessages as toolbarMessages } from '../../messages';
|
|
15
|
+
import { alignAttributes, isInLayoutColumn } from '../../utils';
|
|
16
|
+
|
|
17
|
+
// Workaround as we don't want to import this package into `editor-common`
|
|
18
|
+
// We'll get type errors if this gets out of sync with `editor-plugin-width`.
|
|
19
|
+
var alignmentIcons = [{
|
|
20
|
+
id: 'editor.media.alignLeft',
|
|
21
|
+
value: 'align-start',
|
|
22
|
+
icon: EditorAlignImageLeft
|
|
23
|
+
}, {
|
|
24
|
+
id: 'editor.media.alignCenter',
|
|
25
|
+
value: 'center',
|
|
26
|
+
icon: EditorAlignImageCenter
|
|
27
|
+
}, {
|
|
28
|
+
id: 'editor.media.alignRight',
|
|
29
|
+
value: 'align-end',
|
|
30
|
+
icon: EditorAlignImageRight
|
|
31
|
+
}];
|
|
32
|
+
var wrappingIcons = [{
|
|
33
|
+
id: 'editor.media.wrapLeft',
|
|
34
|
+
value: 'wrap-left',
|
|
35
|
+
icon: WrapLeftIcon
|
|
36
|
+
}, {
|
|
37
|
+
id: 'editor.media.wrapRight',
|
|
38
|
+
value: 'wrap-right',
|
|
39
|
+
icon: WrapRightIcon
|
|
40
|
+
}];
|
|
41
|
+
var breakoutIcons = [{
|
|
42
|
+
value: 'wide',
|
|
43
|
+
icon: WideIcon
|
|
44
|
+
}, {
|
|
45
|
+
value: 'full-width',
|
|
46
|
+
icon: FullWidthIcon
|
|
47
|
+
}];
|
|
48
|
+
var layoutToMessages = {
|
|
49
|
+
'wrap-left': toolbarMessages.wrapLeft,
|
|
50
|
+
center: commonMessages.alignImageCenter,
|
|
51
|
+
'wrap-right': toolbarMessages.wrapRight,
|
|
52
|
+
wide: commonMessages.layoutWide,
|
|
53
|
+
'full-width': commonMessages.layoutFullWidth,
|
|
54
|
+
'align-end': commonMessages.alignImageRight,
|
|
55
|
+
'align-start': commonMessages.alignImageLeft
|
|
56
|
+
};
|
|
57
|
+
var getNodeWidth = function getNodeWidth(node, schema) {
|
|
58
|
+
var embedCard = schema.nodes.embedCard;
|
|
59
|
+
if (node.type === embedCard) {
|
|
60
|
+
return node.attrs.originalWidth || DEFAULT_EMBED_CARD_WIDTH;
|
|
61
|
+
}
|
|
62
|
+
return node.firstChild && node.firstChild.attrs.width || node.attrs.width;
|
|
63
|
+
};
|
|
64
|
+
var makeAlign = function makeAlign(layout, nodeType, widthPluginDependencyApi, analyticsApi) {
|
|
65
|
+
return function (state, dispatch) {
|
|
66
|
+
var _ref = state.selection,
|
|
67
|
+
node = _ref.node;
|
|
68
|
+
var previousLayoutType = node.attrs.layout;
|
|
69
|
+
var mediaSingle = state.schema.nodes.mediaSingle;
|
|
70
|
+
if (!dispatch) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
var widthPluginState = widthPluginDependencyApi === null || widthPluginDependencyApi === void 0 ? void 0 : widthPluginDependencyApi.sharedState.currentState();
|
|
74
|
+
if (!node || node.type !== nodeType || !widthPluginState) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
var nodeWidth = getNodeWidth(node, state.schema);
|
|
78
|
+
var newAttrs = alignAttributes(layout, node.attrs, undefined, nodeWidth, widthPluginState.lineLength);
|
|
79
|
+
var tr = state.tr.setNodeMarkup(state.selection.from, undefined, newAttrs);
|
|
80
|
+
tr.setMeta('scrollIntoView', false);
|
|
81
|
+
// when image captions are enabled, the wrong node gets selected after
|
|
82
|
+
// setNodeMarkup is called
|
|
83
|
+
tr.setSelection(NodeSelection.create(tr.doc, state.selection.from));
|
|
84
|
+
var paragraph = tr.doc.type.schema.nodes.paragraph;
|
|
85
|
+
|
|
86
|
+
// see https://product-fabric.atlassian.net/browse/ED-15518 insert a new paragraph when an embedded card is wrapped left or right
|
|
87
|
+
if (layout.startsWith('wrap') && paragraph && !tr.doc.nodeAt(state.selection.to) && (insideTable(state) || isInLayoutColumn(state))) {
|
|
88
|
+
tr.insert(state.selection.to, paragraph.createAndFill());
|
|
89
|
+
}
|
|
90
|
+
analyticsApi === null || analyticsApi === void 0 ? void 0 : analyticsApi.attachAnalyticsEvent({
|
|
91
|
+
eventType: EVENT_TYPE.TRACK,
|
|
92
|
+
action: ACTION.SELECTED,
|
|
93
|
+
actionSubject: ACTION_SUBJECT[node.type === mediaSingle ? 'MEDIA_SINGLE' : 'EMBEDS'],
|
|
94
|
+
actionSubjectId: ACTION_SUBJECT_ID.RICH_MEDIA_LAYOUT,
|
|
95
|
+
attributes: {
|
|
96
|
+
previousLayoutType: previousLayoutType,
|
|
97
|
+
currentLayoutType: layout
|
|
98
|
+
}
|
|
99
|
+
})(tr);
|
|
100
|
+
dispatch(tr);
|
|
101
|
+
return true;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
var mapIconsToToolbarItem = function mapIconsToToolbarItem(icons, layout, intl, nodeType, widthPluginDependencyApi, analyticsApi) {
|
|
105
|
+
return icons.map(function (toolbarItem) {
|
|
106
|
+
var id = toolbarItem.id,
|
|
107
|
+
value = toolbarItem.value;
|
|
108
|
+
return {
|
|
109
|
+
id: id,
|
|
110
|
+
type: 'button',
|
|
111
|
+
icon: toolbarItem.icon,
|
|
112
|
+
title: intl.formatMessage(layoutToMessages[value]),
|
|
113
|
+
selected: layout === value,
|
|
114
|
+
onClick: makeAlign(value, nodeType, widthPluginDependencyApi, analyticsApi)
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
var shouldHideLayoutToolbar = function shouldHideLayoutToolbar(selection, _ref2, allowResizingInTables) {
|
|
119
|
+
var nodes = _ref2.nodes;
|
|
120
|
+
return hasParentNodeOfType([nodes.bodiedExtension, nodes.listItem, nodes.expand, nodes.nestedExpand].concat(_toConsumableArray(allowResizingInTables ? [] : [nodes.table])).filter(Boolean))(selection);
|
|
121
|
+
};
|
|
122
|
+
var buildLayoutButtons = function buildLayoutButtons(state, intl, nodeType, widthPluginDependencyApi, analyticsApi, allowResizing, allowResizingInTables) {
|
|
123
|
+
var allowWrapping = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : true;
|
|
124
|
+
var allowAlignment = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : true;
|
|
125
|
+
var selection = state.selection;
|
|
126
|
+
if (!(selection instanceof NodeSelection) || !selection.node || !nodeType || shouldHideLayoutToolbar(selection, state.schema, allowResizingInTables)) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
var layout = selection.node.attrs.layout;
|
|
130
|
+
var alignmentToolbarItems = allowAlignment ? mapIconsToToolbarItem(alignmentIcons, layout, intl, nodeType, widthPluginDependencyApi, analyticsApi) : [];
|
|
131
|
+
var wrappingToolbarItems = allowWrapping ? mapIconsToToolbarItem(wrappingIcons, layout, intl, nodeType, widthPluginDependencyApi, analyticsApi) : [];
|
|
132
|
+
var breakOutToolbarItems = !allowResizing ? mapIconsToToolbarItem(breakoutIcons, layout, intl, nodeType, widthPluginDependencyApi, analyticsApi) : [];
|
|
133
|
+
var items = [].concat(_toConsumableArray(alignmentToolbarItems), _toConsumableArray(getSeparatorBetweenAlignmentAndWrapping(allowAlignment, allowWrapping)), _toConsumableArray(wrappingToolbarItems), _toConsumableArray(getSeparatorBeforeBreakoutItems(allowAlignment, allowWrapping, allowResizing)), _toConsumableArray(breakOutToolbarItems));
|
|
134
|
+
return items;
|
|
135
|
+
};
|
|
136
|
+
var getSeparatorBetweenAlignmentAndWrapping = function getSeparatorBetweenAlignmentAndWrapping(allowAlignment, allowWrapping) {
|
|
137
|
+
return allowAlignment && allowWrapping ? [{
|
|
138
|
+
type: 'separator'
|
|
139
|
+
}] : [];
|
|
140
|
+
};
|
|
141
|
+
var getSeparatorBeforeBreakoutItems = function getSeparatorBeforeBreakoutItems(allowAlignment, allowWrapping, allowResizing) {
|
|
142
|
+
return !allowResizing && (allowAlignment || allowWrapping) ? [{
|
|
143
|
+
type: 'separator'
|
|
144
|
+
}] : [];
|
|
145
|
+
};
|
|
146
|
+
export default buildLayoutButtons;
|
package/dist/esm/card/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { addLinkMetadata, getLinkMetadataFromTransaction, commandWithMetadata } from './utils';
|
|
1
|
+
export { addLinkMetadata, getLinkMetadataFromTransaction, commandWithMetadata } from './utils';
|
|
2
|
+
export { default as buildLayoutButtons } from './MediaAndEmbedsToolbar';
|