@instructure/canvas-rce 5.15.7 → 7.0.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 +43 -0
- package/Dockerfile +1 -1
- package/es/bridge/Bridge.d.ts +6 -0
- package/es/common/browser.js +2 -2
- package/es/common/fileUrl.js +13 -3
- package/es/defaultTinymceConfig.js +165 -4
- package/es/enhance-user-content/enhance_user_content.js +1 -1
- package/es/enhance-user-content/instructure_helper.js +7 -3
- package/es/rce/RCEGlobals.d.ts +0 -2
- package/es/rce/RCEGlobals.js +0 -1
- package/es/rce/RCEVariants.d.ts +1 -1
- package/es/rce/RCEVariants.js +8 -8
- package/es/rce/RCEWrapper.d.ts +0 -2
- package/es/rce/RCEWrapper.js +6 -27
- package/es/rce/contentRendering.js +3 -2
- package/es/rce/plugins/instructure_equation/EquationEditorModal/index.d.ts +1 -1
- package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +4 -7
- package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +33 -9
- package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.d.ts +1 -1
- package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +1 -2
- package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.d.ts +13 -3
- package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +12 -4
- package/es/rce/plugins/instructure_record/mediaTranslations.d.ts +3 -0
- package/es/rce/plugins/instructure_record/mediaTranslations.js +4 -1
- package/es/rce/plugins/shared/ContentSelection.js +4 -7
- package/es/rce/plugins/shared/DimensionsInput/DimensionInput.d.ts +4 -2
- package/es/rce/plugins/shared/DimensionsInput/DimensionInput.js +10 -3
- package/es/rce/plugins/shared/DimensionsInput/index.d.ts +2 -0
- package/es/rce/plugins/shared/DimensionsInput/index.js +9 -5
- package/es/rce/plugins/shared/ImageOptionsForm.d.ts +4 -1
- package/es/rce/plugins/shared/ImageOptionsForm.js +13 -3
- package/es/rce/plugins/shared/Upload/UrlPanel.d.ts +9 -3
- package/es/rce/plugins/shared/Upload/UrlPanel.js +13 -4
- package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +1 -1
- package/es/rce/plugins/shared/fileTypeUtils.js +1 -1
- package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +3 -2
- package/es/rce/plugins/tinymce-a11y-checker/plugin.js +50 -52
- package/es/rce/plugins/tinymce-a11y-checker/utils/dom.d.ts +6 -0
- package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +15 -0
- package/es/rce/plugins/tinymce-a11y-checker/utils/rule-enhancer.d.ts +14 -0
- package/es/rce/plugins/tinymce-a11y-checker/utils/rule-enhancer.js +53 -0
- package/es/rce/screenreaderOnFormat.d.ts +2 -0
- package/es/rce/screenreaderOnFormat.js +109 -0
- package/es/rce/style.js +29 -29
- package/es/rcs/api.d.ts +4 -1
- package/es/rcs/api.js +9 -13
- package/es/translations/locales/ar.js +42 -0
- package/es/translations/locales/ca.js +42 -0
- package/es/translations/locales/cy.js +42 -0
- package/es/translations/locales/da-x-k12.js +42 -0
- package/es/translations/locales/da.js +42 -0
- package/es/translations/locales/de.js +42 -0
- package/es/translations/locales/en-AU-x-unimelb.js +42 -0
- package/es/translations/locales/en-GB-x-ukhe.js +42 -0
- package/es/translations/locales/en.js +54 -0
- package/es/translations/locales/en_AU.js +42 -0
- package/es/translations/locales/en_CA.js +42 -0
- package/es/translations/locales/en_CY.js +42 -0
- package/es/translations/locales/en_GB.js +42 -0
- package/es/translations/locales/es.js +42 -0
- package/es/translations/locales/es_ES.js +42 -0
- package/es/translations/locales/fi.js +42 -0
- package/es/translations/locales/fr.js +42 -0
- package/es/translations/locales/fr_CA.js +42 -0
- package/es/translations/locales/ga.js +114 -0
- package/es/translations/locales/hi.js +42 -0
- package/es/translations/locales/ht.js +42 -0
- package/es/translations/locales/id.js +42 -0
- package/es/translations/locales/is.js +42 -0
- package/es/translations/locales/it.js +42 -0
- package/es/translations/locales/ja.js +42 -0
- package/es/translations/locales/mi.js +42 -0
- package/es/translations/locales/ms.js +42 -0
- package/es/translations/locales/nb-x-k12.js +42 -0
- package/es/translations/locales/nb.js +42 -0
- package/es/translations/locales/nl.js +42 -0
- package/es/translations/locales/pl.js +42 -0
- package/es/translations/locales/pt.js +42 -0
- package/es/translations/locales/pt_BR.js +42 -0
- package/es/translations/locales/ru.js +42 -0
- package/es/translations/locales/sl.js +42 -0
- package/es/translations/locales/sv-x-k12.js +42 -0
- package/es/translations/locales/sv.js +42 -0
- package/es/translations/locales/th.js +42 -0
- package/es/translations/locales/vi.js +42 -0
- package/es/translations/locales/zh-Hans.js +42 -0
- package/es/translations/locales/zh-Hant.js +42 -0
- package/es/translations/locales/zh.js +42 -0
- package/es/translations/locales/zh_HK.js +42 -0
- package/es/util/loadingPlaceholder.js +4 -3
- package/package.json +55 -54
- package/coverage/canvas-rce-jest.xml +0 -7028
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## 7.0.0 - 2025-03-31
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Screen readers for RCE toolbar on mobile platform
|
|
13
|
+
- Axios CSRF vulnerability
|
|
14
|
+
- Mailto link insertion
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Upgraded Instui to v10
|
|
19
|
+
- Refactored deprecated plugins to prepare for tinymce upgrade
|
|
20
|
+
- Removed media_links_use_attachment_id feature flag
|
|
21
|
+
|
|
22
|
+
## 6.0.0 - 2025-03-20
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Upgraded to Node 20 LTS
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Redirect focus on invalid save in Image Options tray
|
|
31
|
+
- Whitelist the aria-description attribute
|
|
32
|
+
- Flag external links when they have multi-part TLDs
|
|
33
|
+
- Save changes to alt text when it is the only thing that changes
|
|
34
|
+
- Screenreader reads out content inside raw HTML editor
|
|
35
|
+
- Validations in Upload Media modal
|
|
36
|
+
- Increased Link header size
|
|
37
|
+
|
|
38
|
+
## 5.15.8 - 2025-02-20
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Fixed invalid `querySelectorAll` selector (`:not(.not_external, .external)`)
|
|
43
|
+
that caused errors in older Chrome versions (87 and below). Updated to
|
|
44
|
+
`:not(.not_external):not(.external)` for improved browser compatibility
|
|
45
|
+
- Improved external link handling logic in canvas-rce
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Jest test to ensure the fix does not introduce regressions
|
|
50
|
+
|
|
8
51
|
## 5.15.0 - 2025-02-12
|
|
9
52
|
|
|
10
53
|
- Lazy load iframe and images by default
|
package/Dockerfile
CHANGED
package/es/bridge/Bridge.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ export default class Bridge {
|
|
|
31
31
|
ADDED_CAPTION: string;
|
|
32
32
|
DELETED_CAPTION: string;
|
|
33
33
|
PROGRESS_LABEL: string;
|
|
34
|
+
SELECT_SUPPORTED_FILE_TYPE: string;
|
|
35
|
+
CHOOSE_FILE_TO_UPLOAD: string;
|
|
36
|
+
ENTER_FILE_NAME: string;
|
|
34
37
|
};
|
|
35
38
|
SelectStrings: {
|
|
36
39
|
USE_ARROWS: string;
|
|
@@ -113,6 +116,9 @@ export default class Bridge {
|
|
|
113
116
|
ADDED_CAPTION: string;
|
|
114
117
|
DELETED_CAPTION: string;
|
|
115
118
|
PROGRESS_LABEL: string;
|
|
119
|
+
SELECT_SUPPORTED_FILE_TYPE: string;
|
|
120
|
+
CHOOSE_FILE_TO_UPLOAD: string;
|
|
121
|
+
ENTER_FILE_NAME: string;
|
|
116
122
|
};
|
|
117
123
|
SelectStrings: {
|
|
118
124
|
USE_ARROWS: string;
|
package/es/common/browser.js
CHANGED
package/es/common/fileUrl.js
CHANGED
|
@@ -21,18 +21,28 @@
|
|
|
21
21
|
// in mocha tests.
|
|
22
22
|
|
|
23
23
|
import RCEGlobals from '../rce/RCEGlobals';
|
|
24
|
+
const CONTACT_PROTOCOLS = ['mailto:', 'tel:', 'skype:'];
|
|
25
|
+
function parseUrl(url, canvasOrigin = window.location.origin) {
|
|
26
|
+
try {
|
|
27
|
+
// If the URL is already absolute, use it as-is
|
|
28
|
+
return new URL(url);
|
|
29
|
+
} catch {
|
|
30
|
+
return new URL(`${canvasOrigin}${url.startsWith('/') ? '' : '/'}${url}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
24
33
|
function parseCanvasUrl(url, canvasOrigin = window.location.origin) {
|
|
25
34
|
if (!url) {
|
|
26
35
|
return null;
|
|
27
36
|
}
|
|
28
37
|
try {
|
|
29
|
-
|
|
30
|
-
const fullUrl = url.startsWith('http') ? url : `${canvasOrigin}${url.startsWith('/') ? '' : '/'}${url}`;
|
|
31
|
-
const parsed = new URL(fullUrl);
|
|
38
|
+
const parsed = parseUrl(url, canvasOrigin);
|
|
32
39
|
const canvasUrl = new URL(canvasOrigin);
|
|
33
40
|
if (parsed.host && canvasUrl.host !== parsed.host) {
|
|
34
41
|
return null;
|
|
35
42
|
}
|
|
43
|
+
if (CONTACT_PROTOCOLS.includes(parsed.protocol)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
36
46
|
|
|
37
47
|
// Convert URLSearchParams to query object
|
|
38
48
|
const query = {};
|
|
@@ -16,6 +16,23 @@
|
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
function elemsToTinyStringConfig(list) {
|
|
20
|
+
return Object.entries(list).map(pair => {
|
|
21
|
+
const [tag, attrs] = pair;
|
|
22
|
+
if (attrs.length === 0) {
|
|
23
|
+
return tag;
|
|
24
|
+
} else {
|
|
25
|
+
const attrStr = attrs.map(attr => {
|
|
26
|
+
if (typeof attr === 'string') {
|
|
27
|
+
return attr;
|
|
28
|
+
} else if (typeof attr === 'object') {
|
|
29
|
+
return Object.entries(attr).map(([key, value]) => `${key}=${value}`);
|
|
30
|
+
}
|
|
31
|
+
}).join('|');
|
|
32
|
+
return `${tag}[${attrStr}]`;
|
|
33
|
+
}
|
|
34
|
+
}).join();
|
|
35
|
+
}
|
|
19
36
|
const defaultTinymceConfig = {
|
|
20
37
|
// ============================================================================
|
|
21
38
|
// Values in this section have acceptable defaults which you may want
|
|
@@ -73,10 +90,154 @@ const defaultTinymceConfig = {
|
|
|
73
90
|
// then edited.
|
|
74
91
|
//
|
|
75
92
|
// this list needs to be kept in sync with the list in gems/canvas_sanitize/lib/canvas_sanitize/canvas_sanitize.rb
|
|
76
|
-
valid_elements:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
93
|
+
valid_elements: elemsToTinyStringConfig({
|
|
94
|
+
'@': ['id', 'class', 'style', 'title', 'dir<ltr?rtl', 'lang', 'xml::lang', 'role'],
|
|
95
|
+
'a': ['rel', 'rev', 'charset', 'hreflang', 'tabindex', 'accesskey', 'type', 'name', 'href', 'target', 'title', 'class', 'data-old-link'],
|
|
96
|
+
'strong/b': [],
|
|
97
|
+
'em/i': [],
|
|
98
|
+
'strike/s': [],
|
|
99
|
+
'u': [],
|
|
100
|
+
'#p': [],
|
|
101
|
+
'-ol': ['type', 'compact'],
|
|
102
|
+
'-ul': ['type', 'compact'],
|
|
103
|
+
'-li': [],
|
|
104
|
+
'br': [],
|
|
105
|
+
'img': ['longdesc', 'usemap', 'src', 'border', 'alt', 'title', 'hspace', 'vspace', 'width', 'height', 'align', 'role', 'data-old-link'],
|
|
106
|
+
'-sub': [],
|
|
107
|
+
'-sup': [],
|
|
108
|
+
'-blockquote': ['cite'],
|
|
109
|
+
'-table': [{
|
|
110
|
+
'border': '0'
|
|
111
|
+
}, 'cellspacing', 'cellpadding', 'width', 'frame', 'rules', 'height', 'align', 'summary', 'bgcolor', 'background', 'bordercolor'],
|
|
112
|
+
'-tr': ['rowspan', 'width', 'height', 'align', 'valign', 'bgcolor', 'background', 'bordercolor'],
|
|
113
|
+
'tbody': [],
|
|
114
|
+
'thead': [],
|
|
115
|
+
'tfoot': [],
|
|
116
|
+
'#td': ['colspan', 'rowspan', 'width', 'height', 'align', 'valign', 'bgcolor', 'background', 'bordercolor', 'scope'],
|
|
117
|
+
'#th': ['colspan', 'rowspan', 'width', 'height', 'align', 'valign', 'scope'],
|
|
118
|
+
'caption': [],
|
|
119
|
+
'-div': [],
|
|
120
|
+
'-span': [],
|
|
121
|
+
'-code': [],
|
|
122
|
+
'-pre': [],
|
|
123
|
+
'address': [],
|
|
124
|
+
'-h1': [],
|
|
125
|
+
'-h2': [],
|
|
126
|
+
'-h3': [],
|
|
127
|
+
'-h4': [],
|
|
128
|
+
'-h5': [],
|
|
129
|
+
'-h6': [],
|
|
130
|
+
'hr': ['size', 'noshade'],
|
|
131
|
+
'-font': ['face', 'size', 'color'],
|
|
132
|
+
'dd': [],
|
|
133
|
+
'dl': [],
|
|
134
|
+
'dt': [],
|
|
135
|
+
'cite': [],
|
|
136
|
+
'abbr': [],
|
|
137
|
+
'acronym': [],
|
|
138
|
+
'del': ['datetime', 'cite'],
|
|
139
|
+
'ins': ['datetime', 'cite'],
|
|
140
|
+
'object': ['classid', 'width', 'height', 'codebase', '*'],
|
|
141
|
+
'param': ['name', 'value', '_value'],
|
|
142
|
+
'embed': ['type', 'width', 'height', 'src', '*'],
|
|
143
|
+
'map': ['name'],
|
|
144
|
+
'area': ['shape', 'coords', 'href', 'alt', 'target'],
|
|
145
|
+
'bdo': [],
|
|
146
|
+
'col': ['align', 'char', 'charoff', 'span', 'valign', 'width'],
|
|
147
|
+
'colgroup': ['align', 'char', 'charoff', 'span', 'valign', 'width'],
|
|
148
|
+
'dfn': [],
|
|
149
|
+
'kbd': [],
|
|
150
|
+
'q': ['cite'],
|
|
151
|
+
'samp': [],
|
|
152
|
+
'small': [],
|
|
153
|
+
'tt': [],
|
|
154
|
+
'var': [],
|
|
155
|
+
'big': [],
|
|
156
|
+
'figure': [],
|
|
157
|
+
'figcaption': [],
|
|
158
|
+
'source': ['media', 'width', 'height', 'sizes', 'src', 'srcset', 'type', 'data-old-link'],
|
|
159
|
+
'track': [],
|
|
160
|
+
'mark': [],
|
|
161
|
+
'article': [],
|
|
162
|
+
'aside': [],
|
|
163
|
+
'details': [],
|
|
164
|
+
'footer': [],
|
|
165
|
+
'header': [],
|
|
166
|
+
'nav': [],
|
|
167
|
+
'section': [],
|
|
168
|
+
'summary': [],
|
|
169
|
+
'time': []
|
|
170
|
+
}),
|
|
171
|
+
extended_valid_elements: elemsToTinyStringConfig({
|
|
172
|
+
'@': ['id', 'accesskey', 'class', 'dir', 'lang', 'style', 'tabindex', 'title', 'contenteditable', 'contextmenu', 'draggable', 'dropzone', 'hidden', 'longdesc', 'spellcheck', 'translate', 'align', 'role', 'aria-labelledby', 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-describedby', 'aria-description', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-autocomplete', 'aria-checked', 'aria-disabled', 'aria-expanded', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-level', 'aria-multiline', 'aria-multiselectable', 'aria-orientation', 'aria-pressed', 'aria-readonly', 'aria-required', 'aria-selected', 'aria-sort', 'aria-valuemax', 'aria-valuemin', 'aria-valuenow', 'aria-valuetext'],
|
|
173
|
+
'iframe': ['id', 'data-media-type', 'title', 'src', 'width', 'height', 'name', 'align', 'style', 'class', 'sandbox', 'loading', 'allowfullscreen', 'webkitallowfullscreen', 'mozallowfullscreen', 'allow', 'data-old-link'],
|
|
174
|
+
'i': ['iclass'],
|
|
175
|
+
'a': ['hidden', 'href', 'target', 'rel', 'media', 'hreflang', 'type', 'charset', 'name', 'rev', 'shape', 'coords', 'download', 'alt'],
|
|
176
|
+
'#p': [],
|
|
177
|
+
'li': ['value'],
|
|
178
|
+
'-ol': ['reversed', 'start', 'type', 'compact'],
|
|
179
|
+
'pre': ['width'],
|
|
180
|
+
'table': ['border', 'summary', 'width', 'frame', 'rules', 'cellspacing', 'cellpadding', 'bgcolor'],
|
|
181
|
+
'tbody': ['char', 'charoff', 'valign'],
|
|
182
|
+
'td': ['colspan', 'rowspan', 'headers', 'abbr', 'axis', 'scope', 'align', 'char', 'charoff', 'valign', 'nowrap', 'bgcolor', 'width', 'height'],
|
|
183
|
+
'tfoot': ['char', 'charoff', 'valign'],
|
|
184
|
+
'th': ['colspan', 'rowspan', 'headers', 'scope', 'abbr', 'axis', 'align', 'char', 'charoff', 'valign', 'nowrap', 'bgcolor', 'width', 'height'],
|
|
185
|
+
'thead': ['char', 'charoff', 'valign'],
|
|
186
|
+
'tr': ['char', 'charoff', 'valign', 'bgcolor'],
|
|
187
|
+
'-ul': ['compact'],
|
|
188
|
+
'video': ['name', 'src', 'allowfullscreen', 'muted', 'poster', 'width', 'height', 'controls', 'playsinline'],
|
|
189
|
+
'audio': ['name', 'src', 'muted', 'controls'],
|
|
190
|
+
'annotation': ['href', 'xref', 'definitionURL', 'encoding', 'cd', 'name', 'src'],
|
|
191
|
+
'annotation-xml': ['href', 'xref', 'definitionURL', 'encoding', 'cd', 'name', 'src'],
|
|
192
|
+
'maction': ['href', 'xref', 'mathcolor', 'mathbackground', 'actiontype', 'selection'],
|
|
193
|
+
'maligngroup': ['href', 'xref', 'mathcolor', 'mathbackground', 'groupalign'],
|
|
194
|
+
'malignmark': ['href', 'xref', 'mathcolor', 'mathbackground', 'edge'],
|
|
195
|
+
'math': ['xmlns', 'href', 'xref', 'display', 'maxwidth', 'overflow', 'altimg', 'altimg-width', 'altimg-height', 'altimg-valign', 'alttext', 'cdgroup', 'mathcolor', 'mathbackground', 'scriptlevel', 'displaystyle', 'scriptsizemultiplier', 'scriptminsize', 'infixlinebreakstyle', 'decimalpoint', 'mathvariant', 'mathsize', 'width', 'height', 'valign', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast', 'depth', 'lquote', 'rquote', 'linethickness', 'munalign', 'denomalign', 'bevelled', 'voffset', 'open', 'close', 'separators', 'notation', 'subscriptshift', 'superscriptshift', 'accentunder', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'side', 'minlabelspacing', 'rowspan', 'columnspan', 'edge', 'stackalign', 'charalign', 'charspacing', 'longdivstyle', 'position', 'shift', 'location', 'crossout', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness', 'selection'],
|
|
196
|
+
'menclose': ['href', 'xref', 'mathcolor', 'mathbackground', 'notation'],
|
|
197
|
+
'merror': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
198
|
+
'mfenced': ['href', 'xref', 'mathcolor', 'mathbackground', 'open', 'close', 'separators'],
|
|
199
|
+
'mfrac': ['href', 'xref', 'mathcolor', 'mathbackground', 'linethickness', 'munalign', 'denomalign', 'bevelled'],
|
|
200
|
+
'mglyph': ['href', 'xref', 'mathcolor', 'mathbackground', 'src', 'alt', 'width', 'height', 'valign'],
|
|
201
|
+
'mi': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'],
|
|
202
|
+
'mlabeledtr': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
203
|
+
'mlongdiv': ['href', 'xref', 'mathcolor', 'mathbackground', 'longdivstyle', 'align', 'stackalign', 'charalign', 'charspacing'],
|
|
204
|
+
'mmultiscripts': ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift', 'superscriptshift'],
|
|
205
|
+
'mn': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'],
|
|
206
|
+
'mo': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast'],
|
|
207
|
+
'mover': ['href', 'xref', 'mathcolor', 'mathbackground', 'accent', 'align'],
|
|
208
|
+
'mpadded': ['href', 'xref', 'mathcolor', 'mathbackground', 'height', 'depth', 'width', 'lspace', 'voffset'],
|
|
209
|
+
'mphantom': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
210
|
+
'mprescripts': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
211
|
+
'mroot': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
212
|
+
'mrow': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
213
|
+
'ms': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'lquote', 'rquote'],
|
|
214
|
+
'mscarries': ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'location', 'crossout', 'scriptsizemultiplier'],
|
|
215
|
+
'mscarry': ['href', 'xref', 'mathcolor', 'mathbackground', 'location', 'crossout'],
|
|
216
|
+
'msgroup': ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'shift'],
|
|
217
|
+
'msline': ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness'],
|
|
218
|
+
'mspace': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'],
|
|
219
|
+
'msqrt': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
220
|
+
'msrow': ['href', 'xref', 'mathcolor', 'mathbackground', 'position'],
|
|
221
|
+
'mstack': ['href', 'xref', 'mathcolor', 'mathbackground', 'align', 'stackalign', 'charalign', 'charspacing'],
|
|
222
|
+
'mstyle': ['href', 'xref', 'mathcolor', 'mathbackground', 'scriptlevel', 'displaystyle', 'scriptsizemultiplier', 'scriptminsize', 'infixlinebreakstyle', 'decimalpoint', 'mathvariant', 'mathsize', 'width', 'height', 'valign', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast', 'depth', 'lquote', 'rquote', 'linethickness', 'munalign', 'denomalign', 'bevelled', 'voffset', 'open', 'close', 'separators', 'notation', 'subscriptshift', 'superscriptshift', 'accentunder', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'side', 'minlabelspacing', 'rowspan', 'columnspan', 'edge', 'stackalign', 'charalign', 'charspacing', 'longdivstyle', 'position', 'shift', 'location', 'crossout', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness', 'selection'],
|
|
223
|
+
'msub': ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift'],
|
|
224
|
+
'msubsup': ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift', 'superscriptshift'],
|
|
225
|
+
'msup': ['href', 'xref', 'mathcolor', 'mathbackground', 'superscriptshift'],
|
|
226
|
+
'mtable': ['href', 'xref', 'mathcolor', 'mathbackground', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'width', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'displaystyle', 'side', 'minlabelspacing'],
|
|
227
|
+
'mtd': ['href', 'xref', 'mathcolor', 'mathbackground', 'rowspan', 'columnspan', 'rowalign', 'columnalign', 'groupalign'],
|
|
228
|
+
'mtext': ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'width', 'height', 'depth', 'linebreak'],
|
|
229
|
+
'mtr': ['href', 'xref', 'mathcolor', 'mathbackground', 'rowalign', 'columnalign', 'groupalign'],
|
|
230
|
+
'munder': ['href', 'xref', 'mathcolor', 'mathbackground', 'accentunder', 'align'],
|
|
231
|
+
'munderover': ['href', 'xref', 'mathcolor', 'mathbackground', 'accent', 'accentunder', 'align'],
|
|
232
|
+
'none': ['href', 'xref', 'mathcolor', 'mathbackground'],
|
|
233
|
+
'semantics': ['href', 'xref', 'definitionURL', 'encoding'],
|
|
234
|
+
'picture': [],
|
|
235
|
+
'ruby': [],
|
|
236
|
+
'rp': [],
|
|
237
|
+
'rt': [],
|
|
238
|
+
'g': ['*'],
|
|
239
|
+
'circle': ['*']
|
|
240
|
+
}),
|
|
80
241
|
non_empty_elements: 'td th iframe video audio object script a i area base basefont br col frame hr img input isindex link meta param embed source wbr track ruby',
|
|
81
242
|
// tiny's external link create/edit dialog config
|
|
82
243
|
target_list: false,
|
|
@@ -242,7 +242,7 @@ export function enhanceUserContent(container = document, opts = {}) {
|
|
|
242
242
|
iframeElem.setAttribute('src', src.replace('display=in_rce', 'display=borderless'));
|
|
243
243
|
}
|
|
244
244
|
});
|
|
245
|
-
unenhanced_elem.querySelectorAll('a:not(.not_external
|
|
245
|
+
unenhanced_elem.querySelectorAll('a:not(.not_external):not(.external)').forEach(childLink => {
|
|
246
246
|
if (!isExternalLink(childLink, canvasOrigin)) return;
|
|
247
247
|
if (childLink.tagName === 'IMG' || childLink.querySelectorAll('img').length > 0) return;
|
|
248
248
|
childLink.classList.add('external');
|
|
@@ -21,6 +21,7 @@ import { showFlashAlert } from '../common/FlashAlert';
|
|
|
21
21
|
import { isPreviewable, loadDocPreview, removeLoadingImage, showLoadingImage } from './doc_previews';
|
|
22
22
|
import { show } from './jqueryish_funcs';
|
|
23
23
|
import { parseUrlOrNull } from '../util/url-util';
|
|
24
|
+
import psl from 'psl';
|
|
24
25
|
const youTubeRegEx = /^https?:\/\/(www\.youtube\.com\/watch.*v(=|\/)|youtu\.be\/)([^&#]*)/;
|
|
25
26
|
export function youTubeID(path) {
|
|
26
27
|
const match = path.match(youTubeRegEx);
|
|
@@ -31,9 +32,12 @@ export function youTubeID(path) {
|
|
|
31
32
|
}
|
|
32
33
|
export function getTld(hostname) {
|
|
33
34
|
hostname = (hostname || '').split(':')[0];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
if (hostname.includes('inseng.test')) {
|
|
36
|
+
const parts = hostname.split('.');
|
|
37
|
+
return parts.slice(-3).join('.');
|
|
38
|
+
}
|
|
39
|
+
const parsed = psl.parse(hostname);
|
|
40
|
+
return parsed.domain || hostname;
|
|
37
41
|
}
|
|
38
42
|
export function isExternalLink(element, canvasOrigin = window.location.origin) {
|
|
39
43
|
let canvasHost;
|
package/es/rce/RCEGlobals.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
export default instance;
|
|
2
2
|
export type Features = {
|
|
3
|
-
media_links_use_attachment_id: boolean;
|
|
4
3
|
file_verifiers_for_quiz_links: boolean;
|
|
5
4
|
};
|
|
6
5
|
declare const instance: RCEGlobals;
|
|
7
6
|
/**
|
|
8
7
|
* @typedef {Object} Features
|
|
9
|
-
* @property {boolean} media_links_use_attachment_id
|
|
10
8
|
* @property {boolean} file_verifiers_for_quiz_links
|
|
11
9
|
*/
|
|
12
10
|
declare class RCEGlobals {
|
package/es/rce/RCEGlobals.js
CHANGED
package/es/rce/RCEVariants.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ export type RCEVariant = (typeof RCEVariantValues)[number];
|
|
|
13
13
|
export declare function getMenubarForVariant(variant: RCEVariant): MenuBarSpec;
|
|
14
14
|
export declare function getMenuForVariant(variant: RCEVariant): MenusSpec;
|
|
15
15
|
export declare function getToolbarForVariant(variant: RCEVariant, ltiToolFavorites?: string[]): ToolbarGroupSetting[];
|
|
16
|
-
export declare function getStatusBarFeaturesForVariant(variant: RCEVariant,
|
|
16
|
+
export declare function getStatusBarFeaturesForVariant(variant: RCEVariant, aiTextTools?: boolean, isDesktop?: boolean): StatusBarFeature[];
|
|
17
17
|
export {};
|
package/es/rce/RCEVariants.js
CHANGED
|
@@ -121,16 +121,16 @@ export function getToolbarForVariant(variant, ltiToolFavorites = []) {
|
|
|
121
121
|
items: ['removeformat', 'table', 'instructure_equation', 'instructure_media_embed']
|
|
122
122
|
}];
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
const DESKTOP_FEATURES = ['keyboard_shortcuts', 'a11y_checker', 'word_count'];
|
|
125
|
+
const MOBILE_FEATURES = ['a11y_checker', 'word_count'];
|
|
126
|
+
const EXTENDED_FEATURES = ['html_view', 'fullscreen', 'resize_handle'];
|
|
127
|
+
export function getStatusBarFeaturesForVariant(variant, aiTextTools = false, isDesktop = true) {
|
|
128
128
|
if (variant === 'text-block') {
|
|
129
129
|
return [];
|
|
130
130
|
}
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
|
|
131
|
+
const platformFeatures = isDesktop ? DESKTOP_FEATURES : MOBILE_FEATURES;
|
|
132
|
+
if (variant === 'lite' || variant === 'text-only') {
|
|
133
|
+
return platformFeatures;
|
|
134
134
|
}
|
|
135
|
-
return
|
|
135
|
+
return [...platformFeatures, ...EXTENDED_FEATURES, ...(aiTextTools ? ['ai_tools'] : [])];
|
|
136
136
|
}
|
package/es/rce/RCEWrapper.d.ts
CHANGED
|
@@ -214,7 +214,6 @@ declare class RCEWrapper extends React.Component<RCEWrapperProps, RCEWrapperStat
|
|
|
214
214
|
new_math_equation_handling: unknown;
|
|
215
215
|
explicit_latex_typesetting: unknown;
|
|
216
216
|
rce_transform_loaded_content: unknown;
|
|
217
|
-
media_links_use_attachment_id: unknown;
|
|
218
217
|
file_verifiers_for_quiz_links: unknown;
|
|
219
218
|
rce_find_replace: unknown;
|
|
220
219
|
consolidated_media_player: unknown;
|
|
@@ -348,7 +347,6 @@ declare class RCEWrapper extends React.Component<RCEWrapperProps, RCEWrapperStat
|
|
|
348
347
|
type: string;
|
|
349
348
|
content: string;
|
|
350
349
|
};
|
|
351
|
-
setFocusAbilityForHeader: (focusable: boolean) => void;
|
|
352
350
|
componentWillUnmount(): void;
|
|
353
351
|
wrapOptions(options?: {}): {
|
|
354
352
|
readonly: boolean | undefined;
|
package/es/rce/RCEWrapper.js
CHANGED
|
@@ -19,6 +19,7 @@ import _pt from "prop-types";
|
|
|
19
19
|
|
|
20
20
|
import React, { Suspense } from 'react';
|
|
21
21
|
import { Editor } from '@tinymce/tinymce-react';
|
|
22
|
+
import tinymce from 'tinymce';
|
|
22
23
|
import _ from 'lodash';
|
|
23
24
|
import { StoreProvider } from './plugins/shared/StoreContext';
|
|
24
25
|
import { IconKeyboardShortcutsLine } from '@instructure/ui-icons';
|
|
@@ -63,6 +64,7 @@ import buildStyle from './style';
|
|
|
63
64
|
import { getMenubarForVariant, getMenuForVariant, getToolbarForVariant, getStatusBarFeaturesForVariant } from './RCEVariants';
|
|
64
65
|
import { focusFirstMenuButton, focusToolbar, isElementWithinTable, mergeMenu, mergeMenuItems, mergePlugins, mergeToolbar, parsePluginsToExclude, patchAutosavedContent } from './RCEWrapper.utils';
|
|
65
66
|
import { externalToolsForToolbar } from './plugins/instructure_rce_external_tools/util/externalToolsForToolbar';
|
|
67
|
+
import { initScreenreaderOnFormat } from './screenreaderOnFormat';
|
|
66
68
|
const RestoreAutoSaveModal = /*#__PURE__*/React.lazy(() => import('./RestoreAutoSaveModal'));
|
|
67
69
|
const RceHtmlEditor = /*#__PURE__*/React.lazy(() => import('./RceHtmlEditor'));
|
|
68
70
|
const ASYNC_FOCUS_TIMEOUT = 250;
|
|
@@ -267,13 +269,11 @@ class RCEWrapper extends React.Component {
|
|
|
267
269
|
if (event.code === 'F9' && event.altKey) {
|
|
268
270
|
event.preventDefault();
|
|
269
271
|
event.stopPropagation();
|
|
270
|
-
this.setFocusAbilityForHeader(true);
|
|
271
272
|
// @ts-expect-error
|
|
272
273
|
focusFirstMenuButton(this._elementRef.current);
|
|
273
274
|
} else if (event.code === 'F10' && event.altKey) {
|
|
274
275
|
event.preventDefault();
|
|
275
276
|
event.stopPropagation();
|
|
276
|
-
this.setFocusAbilityForHeader(true);
|
|
277
277
|
// @ts-expect-error
|
|
278
278
|
focusToolbar(this._elementRef.current);
|
|
279
279
|
} else if (event.code === 'F8' && event.altKey) {
|
|
@@ -311,6 +311,7 @@ class RCEWrapper extends React.Component {
|
|
|
311
311
|
// @ts-expect-error
|
|
312
312
|
textarea.value = this.getCode();
|
|
313
313
|
textarea.style.height = this.state.height;
|
|
314
|
+
textarea.removeAttribute('aria-hidden');
|
|
314
315
|
if (document.body.classList.contains('Underline-All-Links__enabled')) {
|
|
315
316
|
if (this.iframe?.contentDocument) {
|
|
316
317
|
this.iframe.contentDocument.body.classList.add('Underline-All-Links__enabled');
|
|
@@ -327,20 +328,6 @@ class RCEWrapper extends React.Component {
|
|
|
327
328
|
tinyapp.setAttribute('tabIndex', '-1');
|
|
328
329
|
}
|
|
329
330
|
|
|
330
|
-
// Adds a focusout event listener for handling screen reader navigation focus
|
|
331
|
-
const header = this._elementRef.current?.querySelector('.tox-editor-header');
|
|
332
|
-
if (header) {
|
|
333
|
-
// @ts-expect-error
|
|
334
|
-
header.addEventListener('focusout', e => {
|
|
335
|
-
// @ts-expect-error
|
|
336
|
-
const leavingHeader = !header.contains(e.relatedTarget);
|
|
337
|
-
if (leavingHeader) {
|
|
338
|
-
this.setFocusAbilityForHeader(false);
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
this.setFocusAbilityForHeader(false);
|
|
343
|
-
|
|
344
331
|
// Probably should do this in tinymce.scss, but we only want it in new rce
|
|
345
332
|
textarea.style.resize = 'none';
|
|
346
333
|
editor.on('keydown', this.handleKey);
|
|
@@ -350,6 +337,7 @@ class RCEWrapper extends React.Component {
|
|
|
350
337
|
// focus-trapping components, so they properly ignore trapping focus on click.
|
|
351
338
|
editor.on('click', () => window.document.body.click(), true);
|
|
352
339
|
editor.on('Cut Change input Undo Redo', debounce(this.handleInputChange, 1000));
|
|
340
|
+
initScreenreaderOnFormat(editor);
|
|
353
341
|
this.announceContextToolbars(editor);
|
|
354
342
|
if (this.isAutoSaving) {
|
|
355
343
|
this.initAutoSave(editor);
|
|
@@ -702,13 +690,6 @@ class RCEWrapper extends React.Component {
|
|
|
702
690
|
content: this.mceInstance().getContent()
|
|
703
691
|
};
|
|
704
692
|
};
|
|
705
|
-
this.setFocusAbilityForHeader = focusable => {
|
|
706
|
-
// Sets aria-hidden to prevent screen readers focus in RCE menus and toolbar
|
|
707
|
-
const header = this._elementRef.current?.querySelector('.tox-editor-header');
|
|
708
|
-
if (header) {
|
|
709
|
-
header.setAttribute('aria-hidden', focusable ? 'false' : 'true');
|
|
710
|
-
}
|
|
711
|
-
};
|
|
712
693
|
this.handleTextareaChange = () => {
|
|
713
694
|
if (this.isHidden()) {
|
|
714
695
|
this.setCode(this.textareaValue());
|
|
@@ -850,7 +831,6 @@ class RCEWrapper extends React.Component {
|
|
|
850
831
|
new_math_equation_handling = false,
|
|
851
832
|
explicit_latex_typesetting = false,
|
|
852
833
|
rce_transform_loaded_content = false,
|
|
853
|
-
media_links_use_attachment_id = false,
|
|
854
834
|
rce_find_replace = false,
|
|
855
835
|
file_verifiers_for_quiz_links = false,
|
|
856
836
|
consolidated_media_player = false
|
|
@@ -859,7 +839,6 @@ class RCEWrapper extends React.Component {
|
|
|
859
839
|
new_math_equation_handling,
|
|
860
840
|
explicit_latex_typesetting,
|
|
861
841
|
rce_transform_loaded_content,
|
|
862
|
-
media_links_use_attachment_id,
|
|
863
842
|
file_verifiers_for_quiz_links,
|
|
864
843
|
rce_find_replace,
|
|
865
844
|
consolidated_media_player
|
|
@@ -1729,7 +1708,7 @@ class RCEWrapper extends React.Component {
|
|
|
1729
1708
|
}
|
|
1730
1709
|
});
|
|
1731
1710
|
}
|
|
1732
|
-
const statusBarFeatures = getStatusBarFeaturesForVariant(this.variant, this.props.ai_text_tools);
|
|
1711
|
+
const statusBarFeatures = getStatusBarFeaturesForVariant(this.variant, this.props.ai_text_tools, tinymce.Env.deviceType.isDesktop());
|
|
1733
1712
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, this.style.css), /*#__PURE__*/React.createElement(StoreProvider, {
|
|
1734
1713
|
jwt: this.props.trayProps?.jwt,
|
|
1735
1714
|
refreshToken: this.props.trayProps?.refreshToken,
|
|
@@ -1751,7 +1730,7 @@ class RCEWrapper extends React.Component {
|
|
|
1751
1730
|
} : undefined,
|
|
1752
1731
|
onFocus: this.handleFocusRCE,
|
|
1753
1732
|
onBlur: this.handleBlurRCE
|
|
1754
|
-
}, this.state.shouldShowOnFocusButton && /*#__PURE__*/React.createElement(ShowOnFocusButton, {
|
|
1733
|
+
}, this.state.shouldShowOnFocusButton && tinymce.Env.deviceType.isDesktop() && /*#__PURE__*/React.createElement(ShowOnFocusButton, {
|
|
1755
1734
|
id: `show-on-focus-btn-${this.id}`,
|
|
1756
1735
|
onClick: this.openKBShortcutModal,
|
|
1757
1736
|
margin: "xx-small",
|
|
@@ -20,7 +20,7 @@ import React from 'react';
|
|
|
20
20
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
21
21
|
import { cleanUrl } from './contentInsertionUtils';
|
|
22
22
|
import formatMessage from '../format-message';
|
|
23
|
-
import {
|
|
23
|
+
import { videoDefaultSize, AUDIO_PLAYER_SIZE } from './plugins/instructure_record/VideoOptionsTray/TrayController';
|
|
24
24
|
import { mediaPlayerURLFromFile } from './plugins/shared/fileTypeUtils';
|
|
25
25
|
import { prepEmbedSrc, prepLinkedSrc, absoluteToRelativeUrl } from '../common/fileUrl';
|
|
26
26
|
export function renderLink(data, contents, canvasOrigin) {
|
|
@@ -97,6 +97,7 @@ export function renderImage(image, canvasOrigin, opts) {
|
|
|
97
97
|
}
|
|
98
98
|
export function renderVideo(video, canvasOrigin) {
|
|
99
99
|
const src = mediaPlayerURLFromFile(video, canvasOrigin);
|
|
100
|
+
const videoSize = videoDefaultSize();
|
|
100
101
|
return `
|
|
101
102
|
<iframe
|
|
102
103
|
allow="fullscreen"
|
|
@@ -105,7 +106,7 @@ export function renderVideo(video, canvasOrigin) {
|
|
|
105
106
|
data-media-type="video"
|
|
106
107
|
loading="lazy"
|
|
107
108
|
src="${src}"
|
|
108
|
-
style="width:${
|
|
109
|
+
style="width:${videoSize.width};height:${videoSize.height};display:inline-block;"
|
|
109
110
|
title="${formatMessage('Video player for {title}', {
|
|
110
111
|
title: video.title || video.name || video.text
|
|
111
112
|
})}"></iframe>
|
|
@@ -13,7 +13,7 @@ declare class EquationEditorModal extends React.Component<any, any, any> {
|
|
|
13
13
|
executeCommand: (cmd: any, advancedCmd: any) => void;
|
|
14
14
|
handleModalCancel: () => void;
|
|
15
15
|
handleModalDone: () => void;
|
|
16
|
-
renderMathInAdvancedPreview: import("@instructure/debounce").Debounced
|
|
16
|
+
renderMathInAdvancedPreview: import("@instructure/debounce").Debounced<() => void>;
|
|
17
17
|
setPreviewElementContent(): void;
|
|
18
18
|
toggleAdvanced: () => void;
|
|
19
19
|
toggleAndUpdatePreference: () => void;
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
|
|
19
19
|
import formatMessage from '../../../format-message';
|
|
20
20
|
import { scaleForHeight, scaleForWidth } from '../shared/DimensionUtils';
|
|
21
|
-
import RCEGlobals from '../../RCEGlobals';
|
|
22
21
|
export const MIN_HEIGHT = 10;
|
|
23
22
|
export const MIN_WIDTH = 10;
|
|
24
23
|
export const MIN_WIDTH_VIDEO = 320;
|
|
@@ -117,12 +116,10 @@ export function fromVideoEmbed($element) {
|
|
|
117
116
|
// bad json?
|
|
118
117
|
}
|
|
119
118
|
videoOptions.videoSize = imageSizeFromKnownOptions(videoOptions);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
videoOptions.attachmentId = matches[1];
|
|
125
|
-
}
|
|
119
|
+
const source = $videoIframe.getAttribute('src');
|
|
120
|
+
const matches = source?.match(/\/media_attachments_iframe\/(\d+)/);
|
|
121
|
+
if (matches) {
|
|
122
|
+
videoOptions.attachmentId = matches[1];
|
|
126
123
|
}
|
|
127
124
|
return videoOptions;
|
|
128
125
|
}
|