@instructure/canvas-rce 5.13.5 → 5.14.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 +32 -1
- package/{es/rce/__mocks__/styleMock.js → __mocks__/@instructure/studio-player/_mockStudioPlayer.js} +5 -2
- package/es/defaultTinymceConfig.js +2 -2
- package/es/enhance-user-content/enhance_user_content.js +31 -3
- package/es/rce/RCEWrapper.js +11 -34
- package/es/rce/RceHtmlEditor.js +14 -65
- package/es/rce/plugins/instructure_equation/EquationEditorModal/index.js +12 -4
- package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +7 -3
- package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +1 -0
- package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +6 -3
- package/es/rce/plugins/instructure_record/clickCallback.js +27 -22
- package/es/rce/plugins/shared/ContentSelection.js +16 -4
- package/es/translations/locales/ca.js +1 -1
- package/es/translations/locales/ga.js +3 -0
- package/jest/jest-setup.js +14 -0
- package/jest.config.js +4 -3
- package/package.json +54 -53
- package/es/rce/__mocks__/_mockCryptoEs.js +0 -124
- package/es/rce/__mocks__/tinymceReact.js +0 -55
- package/es/rce/plugins/shared/__mocks__/screenfull.js +0 -24
- package/es/rce/plugins/tinymce-a11y-checker/rules/__mocks__/index.js +0 -53
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,38 @@ 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
|
-
## 5.
|
|
8
|
+
## 5.14.0 - 2024-10-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- New optional media player for upload previews
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Keyboard trap when switching to the HTML Editor
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Upgraded React to 18
|
|
21
|
+
|
|
22
|
+
## 5.13.6 - 2024-09-25
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- File links with data-canvas-previewable='false' will no longer try to preview
|
|
27
|
+
- Change backgroundless buttons to "primary" theme color to be more visible
|
|
28
|
+
- Fix LTI tool scrolling issue on small iOS devices
|
|
29
|
+
- Adding missing translation strings
|
|
30
|
+
- Fixed some types of non-Canvas files from trying to preview like Canvas files
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Allow links with data-old-link to replace the existing src or href with the contents
|
|
35
|
+
of the data-old-link attribute
|
|
36
|
+
- Added IDs to multiple objects missing IDs
|
|
37
|
+
- Add loading spinners to image uploads
|
|
38
|
+
|
|
39
|
+
## 5.13.5 - 2024-08-12
|
|
9
40
|
|
|
10
41
|
### Fixed
|
|
11
42
|
|
package/{es/rce/__mocks__/styleMock.js → __mocks__/@instructure/studio-player/_mockStudioPlayer.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (C)
|
|
2
|
+
* Copyright (C) 2024 - present Instructure, Inc.
|
|
3
3
|
*
|
|
4
4
|
* This file is part of Canvas.
|
|
5
5
|
*
|
|
@@ -15,4 +15,7 @@
|
|
|
15
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
StudioPlayer: () => null
|
|
21
|
+
};
|
|
@@ -72,8 +72,8 @@ const defaultTinymceConfig = {
|
|
|
72
72
|
// then edited.
|
|
73
73
|
//
|
|
74
74
|
// this list needs to be kept in sync with the list in gems/canvas_sanitize/lib/canvas_sanitize/canvas_sanitize.rb
|
|
75
|
-
valid_elements: '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|role],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class],strong/b,em/i,strike/s,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt|title|hspace|vspace|width|height|align|role],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],map[name],area[shape|coords|href|alt|target],bdo,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,kbd,q[cite],samp,small,tt,var,big,figure,figcaption,source[media|width|height|sizes|src|srcset|type],track,mark,article,aside,details,footer,header,nav,section,summary,time',
|
|
76
|
-
extended_valid_elements: '@[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-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],iframe[id|data-media-type|title|src|width|height|name|align|style|class|sandbox|allowfullscreen|webkitallowfullscreen|mozallowfullscreen|allow],i[iclass],a[hidden|href|target|rel|media|hreflang|type|charset|name|rev|shape|coords|download|alt],#p,li[value],-ol[reversed|start|type|compact],pre[width],table[border|summary|width|frame|rules|cellspacing|cellpadding|bgcolor],tbody[char|charoff|valign],td[colspan|rowspan|headers|abbr|axis|scope|align|char|charoff|valign|nowrap|bgcolor|width|height],tfoot[char|charoff|valign],th[colspan|rowspan|headers|scope|abbr|axis|align|char|charoff|valign|nowrap|bgcolor|width|height],thead[char|charoff|valign],tr[char|charoff|valign|bgcolor],-ul[compact],video[name|src|allowfullscreen|muted|poster|width|height|controls|playsinline],audio[name|src|muted|controls],annotation[href|xref|definitionURL|encoding|cd|name|src],annotation-xml[href|xref|definitionURL|encoding|cd|name|src],maction[href|xref|mathcolor|mathbackground|actiontype|selection],maligngroup[href|xref|mathcolor|mathbackground|groupalign],malignmark[href|xref|mathcolor|mathbackground|edge],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],menclose[href|xref|mathcolor|mathbackground|notation],merror[href|xref|mathcolor|mathbackground],mfenced[href|xref|mathcolor|mathbackground|open|close|separators],mfrac[href|xref|mathcolor|mathbackground|linethickness|munalign|denomalign|bevelled],mglyph[href|xref|mathcolor|mathbackground|src|alt|width|height|valign],mi[href|xref|mathcolor|mathbackground|mathvariant|mathsize],mlabeledtr[href|xref|mathcolor|mathbackground],mlongdiv[href|xref|mathcolor|mathbackground|longdivstyle|align|stackalign|charalign|charspacing],mmultiscripts[href|xref|mathcolor|mathbackground|subscriptshift|superscriptshift],mn[href|xref|mathcolor|mathbackground|mathvariant|mathsize],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],mover[href|xref|mathcolor|mathbackground|accent|align],mpadded[href|xref|mathcolor|mathbackground|height|depth|width|lspace|voffset],mphantom[href|xref|mathcolor|mathbackground],mprescripts[href|xref|mathcolor|mathbackground],mroot[href|xref|mathcolor|mathbackground],mrow[href|xref|mathcolor|mathbackground],ms[href|xref|mathcolor|mathbackground|mathvariant|mathsize|lquote|rquote],mscarries[href|xref|mathcolor|mathbackground|position|location|crossout|scriptsizemultiplier],mscarry[href|xref|mathcolor|mathbackground|location|crossout],msgroup[href|xref|mathcolor|mathbackground|position|shift],msline[href|xref|mathcolor|mathbackground|position|length|leftoverhang|rightoverhang|mslinethickness],mspace[href|xref|mathcolor|mathbackground|mathvariant|mathsize],msqrt[href|xref|mathcolor|mathbackground],msrow[href|xref|mathcolor|mathbackground|position],mstack[href|xref|mathcolor|mathbackground|align|stackalign|charalign|charspacing],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],msub[href|xref|mathcolor|mathbackground|subscriptshift],msubsup[href|xref|mathcolor|mathbackground|subscriptshift|superscriptshift],msup[href|xref|mathcolor|mathbackground|superscriptshift],mtable[href|xref|mathcolor|mathbackground|align|rowalign|columnalign|groupalign|alignmentscope|columnwidth|width|rowspacing|columnspacing|rowlines|columnlines|frame|framespacing|equalrows|equalcolumns|displaystyle|side|minlabelspacing],mtd[href|xref|mathcolor|mathbackground|rowspan|columnspan|rowalign|columnalign|groupalign],mtext[href|xref|mathcolor|mathbackground|mathvariant|mathsize|width|height|depth|linebreak],mtr[href|xref|mathcolor|mathbackground|rowalign|columnalign|groupalign],munder[href|xref|mathcolor|mathbackground|accentunder|align],munderover[href|xref|mathcolor|mathbackground|accent|accentunder|align],none[href|xref|mathcolor|mathbackground],semantics[href|xref|definitionURL|encoding],picture,ruby,rp,rt,wbr' + // the svg necessary for the uploading placeholder's spinner
|
|
75
|
+
valid_elements: '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|role],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|data-old-link],strong/b,em/i,strike/s,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt|title|hspace|vspace|width|height|align|role|data-old-link],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],map[name],area[shape|coords|href|alt|target],bdo,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,kbd,q[cite],samp,small,tt,var,big,figure,figcaption,source[media|width|height|sizes|src|srcset|type|data-old-link],track,mark,article,aside,details,footer,header,nav,section,summary,time',
|
|
76
|
+
extended_valid_elements: '@[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-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],iframe[id|data-media-type|title|src|width|height|name|align|style|class|sandbox|allowfullscreen|webkitallowfullscreen|mozallowfullscreen|allow|data-old-link],i[iclass],a[hidden|href|target|rel|media|hreflang|type|charset|name|rev|shape|coords|download|alt],#p,li[value],-ol[reversed|start|type|compact],pre[width],table[border|summary|width|frame|rules|cellspacing|cellpadding|bgcolor],tbody[char|charoff|valign],td[colspan|rowspan|headers|abbr|axis|scope|align|char|charoff|valign|nowrap|bgcolor|width|height],tfoot[char|charoff|valign],th[colspan|rowspan|headers|scope|abbr|axis|align|char|charoff|valign|nowrap|bgcolor|width|height],thead[char|charoff|valign],tr[char|charoff|valign|bgcolor],-ul[compact],video[name|src|allowfullscreen|muted|poster|width|height|controls|playsinline],audio[name|src|muted|controls],annotation[href|xref|definitionURL|encoding|cd|name|src],annotation-xml[href|xref|definitionURL|encoding|cd|name|src],maction[href|xref|mathcolor|mathbackground|actiontype|selection],maligngroup[href|xref|mathcolor|mathbackground|groupalign],malignmark[href|xref|mathcolor|mathbackground|edge],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],menclose[href|xref|mathcolor|mathbackground|notation],merror[href|xref|mathcolor|mathbackground],mfenced[href|xref|mathcolor|mathbackground|open|close|separators],mfrac[href|xref|mathcolor|mathbackground|linethickness|munalign|denomalign|bevelled],mglyph[href|xref|mathcolor|mathbackground|src|alt|width|height|valign],mi[href|xref|mathcolor|mathbackground|mathvariant|mathsize],mlabeledtr[href|xref|mathcolor|mathbackground],mlongdiv[href|xref|mathcolor|mathbackground|longdivstyle|align|stackalign|charalign|charspacing],mmultiscripts[href|xref|mathcolor|mathbackground|subscriptshift|superscriptshift],mn[href|xref|mathcolor|mathbackground|mathvariant|mathsize],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],mover[href|xref|mathcolor|mathbackground|accent|align],mpadded[href|xref|mathcolor|mathbackground|height|depth|width|lspace|voffset],mphantom[href|xref|mathcolor|mathbackground],mprescripts[href|xref|mathcolor|mathbackground],mroot[href|xref|mathcolor|mathbackground],mrow[href|xref|mathcolor|mathbackground],ms[href|xref|mathcolor|mathbackground|mathvariant|mathsize|lquote|rquote],mscarries[href|xref|mathcolor|mathbackground|position|location|crossout|scriptsizemultiplier],mscarry[href|xref|mathcolor|mathbackground|location|crossout],msgroup[href|xref|mathcolor|mathbackground|position|shift],msline[href|xref|mathcolor|mathbackground|position|length|leftoverhang|rightoverhang|mslinethickness],mspace[href|xref|mathcolor|mathbackground|mathvariant|mathsize],msqrt[href|xref|mathcolor|mathbackground],msrow[href|xref|mathcolor|mathbackground|position],mstack[href|xref|mathcolor|mathbackground|align|stackalign|charalign|charspacing],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],msub[href|xref|mathcolor|mathbackground|subscriptshift],msubsup[href|xref|mathcolor|mathbackground|subscriptshift|superscriptshift],msup[href|xref|mathcolor|mathbackground|superscriptshift],mtable[href|xref|mathcolor|mathbackground|align|rowalign|columnalign|groupalign|alignmentscope|columnwidth|width|rowspacing|columnspacing|rowlines|columnlines|frame|framespacing|equalrows|equalcolumns|displaystyle|side|minlabelspacing],mtd[href|xref|mathcolor|mathbackground|rowspan|columnspan|rowalign|columnalign|groupalign],mtext[href|xref|mathcolor|mathbackground|mathvariant|mathsize|width|height|depth|linebreak],mtr[href|xref|mathcolor|mathbackground|rowalign|columnalign|groupalign],munder[href|xref|mathcolor|mathbackground|accentunder|align],munderover[href|xref|mathcolor|mathbackground|accent|accentunder|align],none[href|xref|mathcolor|mathbackground],semantics[href|xref|definitionURL|encoding],picture,ruby,rp,rt,wbr' + // the svg necessary for the uploading placeholder's spinner
|
|
77
77
|
'svg[*],g[*],circle[*]',
|
|
78
78
|
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',
|
|
79
79
|
// tiny's external link create/edit dialog config
|
|
@@ -151,7 +151,12 @@ export function enhanceUserContent() {
|
|
|
151
151
|
/**
|
|
152
152
|
* When used inside of an LTI tool, this contains the canvas global id of the tool.
|
|
153
153
|
*/
|
|
154
|
-
containingCanvasLtiToolId
|
|
154
|
+
containingCanvasLtiToolId,
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Contingency plan in case new instfs media links cause problems in rich content.
|
|
158
|
+
*/
|
|
159
|
+
replaceInstFSLinksWithOldLinks
|
|
155
160
|
} = opts;
|
|
156
161
|
getTranslations(locale).then(() => {
|
|
157
162
|
formatMessage.setup({
|
|
@@ -193,7 +198,30 @@ export function enhanceUserContent() {
|
|
|
193
198
|
img.setAttribute('alt', formatMessage('This image is currently unavailable'));
|
|
194
199
|
}
|
|
195
200
|
});
|
|
196
|
-
setData(unenhanced_elem, 'unenhanced_content_html', unenhanced_elem.innerHTML); //
|
|
201
|
+
setData(unenhanced_elem, 'unenhanced_content_html', unenhanced_elem.innerHTML); // If instfs links are causing content problems,
|
|
202
|
+
// use this to show users old links instead
|
|
203
|
+
|
|
204
|
+
if (replaceInstFSLinksWithOldLinks) {
|
|
205
|
+
const attributes = ['href', 'src'];
|
|
206
|
+
const selector = '[href], [src]';
|
|
207
|
+
const oldLinkAttribute = 'data-old-link';
|
|
208
|
+
unenhanced_elem.querySelectorAll(selector).forEach(element => {
|
|
209
|
+
const oldLink = element.getAttribute(oldLinkAttribute);
|
|
210
|
+
|
|
211
|
+
if (!oldLink) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (const a of attributes) {
|
|
216
|
+
const newLink = element.getAttribute(a);
|
|
217
|
+
|
|
218
|
+
if (newLink && newLink != oldLink) {
|
|
219
|
+
element.setAttribute(a, oldLink);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
} // guarantee relative links point to canvas
|
|
224
|
+
|
|
197
225
|
|
|
198
226
|
if (canvasOrigin) {
|
|
199
227
|
const attributes = ['href', 'src'];
|
|
@@ -260,7 +288,7 @@ export function enhanceUserContent() {
|
|
|
260
288
|
const href = buildUrl(file_link.href); // Don't attempt to enhance links with no href
|
|
261
289
|
|
|
262
290
|
if (!href) return;
|
|
263
|
-
const matchesCanvasFile = href.pathname.match(/(?:\/(courses|groups|users)
|
|
291
|
+
const matchesCanvasFile = href.pathname.match(/(?:\/(courses|groups|users)\/\d+)?\/files\/([\d~]+)(?=[!*'();:@&=+$,/?#\[\]]|$)/);
|
|
264
292
|
|
|
265
293
|
if (!matchesCanvasFile) {
|
|
266
294
|
// a bug in the new RCE added instructure_file_link class name to all links
|
package/es/rce/RCEWrapper.js
CHANGED
|
@@ -272,10 +272,6 @@ class RCEWrapper extends React.Component {
|
|
|
272
272
|
this.handleFocus(event);
|
|
273
273
|
};
|
|
274
274
|
|
|
275
|
-
this.handleFocusHtmlEditor = event => {
|
|
276
|
-
this.handleFocus(event);
|
|
277
|
-
};
|
|
278
|
-
|
|
279
275
|
this.handleBlurEditor = (event, _editor) => {
|
|
280
276
|
const ifr = this.iframe;
|
|
281
277
|
ifr && ifr.parentElement.classList.remove('active');
|
|
@@ -906,7 +902,8 @@ class RCEWrapper extends React.Component {
|
|
|
906
902
|
rce_transform_loaded_content = false,
|
|
907
903
|
media_links_use_attachment_id = false,
|
|
908
904
|
rce_find_replace = false,
|
|
909
|
-
file_verifiers_for_quiz_links = false
|
|
905
|
+
file_verifiers_for_quiz_links = false,
|
|
906
|
+
consolidated_media_player = false
|
|
910
907
|
} = this.props.features;
|
|
911
908
|
return {
|
|
912
909
|
new_math_equation_handling,
|
|
@@ -914,7 +911,8 @@ class RCEWrapper extends React.Component {
|
|
|
914
911
|
rce_transform_loaded_content,
|
|
915
912
|
media_links_use_attachment_id,
|
|
916
913
|
file_verifiers_for_quiz_links,
|
|
917
|
-
rce_find_replace
|
|
914
|
+
rce_find_replace,
|
|
915
|
+
consolidated_media_player
|
|
918
916
|
};
|
|
919
917
|
}
|
|
920
918
|
|
|
@@ -1314,19 +1312,6 @@ class RCEWrapper extends React.Component {
|
|
|
1314
1312
|
break;
|
|
1315
1313
|
|
|
1316
1314
|
case PRETTY_HTML_EDITOR_VIEW:
|
|
1317
|
-
{
|
|
1318
|
-
const cmta = this._elementRef.current.querySelector('.CodeMirror textarea');
|
|
1319
|
-
|
|
1320
|
-
if (cmta) {
|
|
1321
|
-
cmta.focus();
|
|
1322
|
-
} else {
|
|
1323
|
-
window.setTimeout(() => {
|
|
1324
|
-
var _this$_elementRef$cur3;
|
|
1325
|
-
|
|
1326
|
-
(_this$_elementRef$cur3 = this._elementRef.current.querySelector('.CodeMirror textarea')) === null || _this$_elementRef$cur3 === void 0 ? void 0 : _this$_elementRef$cur3.focus();
|
|
1327
|
-
}, 200);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
1315
|
break;
|
|
1331
1316
|
|
|
1332
1317
|
case RAW_HTML_EDITOR_VIEW:
|
|
@@ -1400,7 +1385,7 @@ class RCEWrapper extends React.Component {
|
|
|
1400
1385
|
// we often need a moment to see if focus comes back
|
|
1401
1386
|
event && event.persist && event.persist();
|
|
1402
1387
|
this.blurTimer = window.setTimeout(() => {
|
|
1403
|
-
var _this$_elementRef$
|
|
1388
|
+
var _this$_elementRef$cur3, _event$focusedEditor, _event$relatedTarget, _event$relatedTarget$;
|
|
1404
1389
|
|
|
1405
1390
|
this.blurTimer = 0;
|
|
1406
1391
|
|
|
@@ -1410,7 +1395,7 @@ class RCEWrapper extends React.Component {
|
|
|
1410
1395
|
return;
|
|
1411
1396
|
}
|
|
1412
1397
|
|
|
1413
|
-
if ((_this$_elementRef$
|
|
1398
|
+
if ((_this$_elementRef$cur3 = this._elementRef.current) !== null && _this$_elementRef$cur3 !== void 0 && _this$_elementRef$cur3.contains(document.activeElement)) {
|
|
1414
1399
|
// focus is still somewhere w/in me
|
|
1415
1400
|
return;
|
|
1416
1401
|
}
|
|
@@ -1763,21 +1748,14 @@ class RCEWrapper extends React.Component {
|
|
|
1763
1748
|
}
|
|
1764
1749
|
|
|
1765
1750
|
setEditorView(view) {
|
|
1766
|
-
var _this$_elementRef$cur5;
|
|
1767
|
-
|
|
1768
1751
|
switch (view) {
|
|
1769
|
-
case RAW_HTML_EDITOR_VIEW:
|
|
1770
|
-
this.mceInstance().hide();
|
|
1771
|
-
break;
|
|
1772
|
-
|
|
1773
|
-
case PRETTY_HTML_EDITOR_VIEW:
|
|
1774
|
-
this.mceInstance().hide();
|
|
1775
|
-
(_this$_elementRef$cur5 = this._elementRef.current.querySelector('.CodeMirror')) === null || _this$_elementRef$cur5 === void 0 ? void 0 : _this$_elementRef$cur5.CodeMirror.setCursor(0, 0);
|
|
1776
|
-
break;
|
|
1777
|
-
|
|
1778
1752
|
case WYSIWYG_VIEW:
|
|
1779
1753
|
this.setCode(this.textareaValue());
|
|
1780
1754
|
this.mceInstance().show();
|
|
1755
|
+
break;
|
|
1756
|
+
|
|
1757
|
+
default:
|
|
1758
|
+
this.mceInstance().hide();
|
|
1781
1759
|
}
|
|
1782
1760
|
}
|
|
1783
1761
|
|
|
@@ -1806,8 +1784,7 @@ class RCEWrapper extends React.Component {
|
|
|
1806
1784
|
onChange: value => {
|
|
1807
1785
|
this.getTextarea().value = value;
|
|
1808
1786
|
this.handleTextareaChange();
|
|
1809
|
-
}
|
|
1810
|
-
onFocus: this.handleFocusHtmlEditor
|
|
1787
|
+
}
|
|
1811
1788
|
})));
|
|
1812
1789
|
}
|
|
1813
1790
|
|
package/es/rce/RceHtmlEditor.js
CHANGED
|
@@ -18,38 +18,12 @@
|
|
|
18
18
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
19
19
|
import { func, string } from 'prop-types';
|
|
20
20
|
import formatMessage from '../format-message';
|
|
21
|
-
import {
|
|
21
|
+
import { SourceCodeEditor } from '@instructure/ui-source-code-editor';
|
|
22
22
|
import beautify from 'js-beautify';
|
|
23
|
-
const RceHtmlEditor = /*#__PURE__*/React.forwardRef((
|
|
24
|
-
let {
|
|
25
|
-
onFocus,
|
|
26
|
-
...props
|
|
27
|
-
} = _ref;
|
|
23
|
+
const RceHtmlEditor = /*#__PURE__*/React.forwardRef((props, editorRef) => {
|
|
28
24
|
const [code, setCode] = useState(props.code);
|
|
29
25
|
const label = formatMessage('html code editor');
|
|
30
26
|
const [dir, setDir] = useState(getComputedStyle(document.body, null).direction);
|
|
31
|
-
const [codeMirrorEditorDiv, setCodeMirrorEditorDiv] = useState(null);
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
;
|
|
34
|
-
|
|
35
|
-
(async () => {
|
|
36
|
-
const p = new Promise(resolve => {
|
|
37
|
-
const timerid = setInterval(() => {
|
|
38
|
-
// scoping querySelector to the container div makes sure we're targeting this CodeEditor
|
|
39
|
-
// The CodeMirror docs (https://codemirror.net/doc/manual.html#styling)
|
|
40
|
-
// say this is the element we use to set the editor's height
|
|
41
|
-
const editor = editorRef.current.querySelector('.CodeMirror');
|
|
42
|
-
|
|
43
|
-
if (editor) {
|
|
44
|
-
clearInterval(timerid);
|
|
45
|
-
setCodeMirrorEditorDiv(editor);
|
|
46
|
-
resolve();
|
|
47
|
-
}
|
|
48
|
-
}, 60);
|
|
49
|
-
});
|
|
50
|
-
await p;
|
|
51
|
-
})();
|
|
52
|
-
}, [editorRef]);
|
|
53
27
|
useEffect(() => {
|
|
54
28
|
setCode(beautify.html(props.code)); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
29
|
}, []);
|
|
@@ -78,23 +52,7 @@ const RceHtmlEditor = /*#__PURE__*/React.forwardRef((_ref, editorRef) => {
|
|
|
78
52
|
|
|
79
53
|
setDir(getComputedStyle(editorRef.current || document.body, null).direction);
|
|
80
54
|
}, [dir, editorRef]);
|
|
81
|
-
|
|
82
|
-
if (codeMirrorEditorDiv) {
|
|
83
|
-
codeMirrorEditorDiv.CodeMirror.setSize(null, props.height);
|
|
84
|
-
codeMirrorEditorDiv.style.margin = '0';
|
|
85
|
-
codeMirrorEditorDiv.style.border = '0';
|
|
86
|
-
}
|
|
87
|
-
}, [codeMirrorEditorDiv, props.height]);
|
|
88
|
-
const isFocused = useRef(false); // move cursor to the top of the html code when the editor is focused for the first time
|
|
89
|
-
|
|
90
|
-
const handleFocus = useCallback((editor, event) => {
|
|
91
|
-
if (!isFocused.current) {
|
|
92
|
-
editor.setCursor(0, 0);
|
|
93
|
-
isFocused.current = true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
onFocus(event);
|
|
97
|
-
}, [onFocus]); // setting height on the container keeps the RCE toolbar from jumping
|
|
55
|
+
const direction = ['ltr', 'rtl'].includes(dir) ? dir : 'ltr'; // setting height on the container keeps the RCE toolbar from jumping
|
|
98
56
|
|
|
99
57
|
return /*#__PURE__*/React.createElement("div", {
|
|
100
58
|
ref: editorRef,
|
|
@@ -104,39 +62,30 @@ const RceHtmlEditor = /*#__PURE__*/React.forwardRef((_ref, editorRef) => {
|
|
|
104
62
|
overflow: 'hidden',
|
|
105
63
|
textAlign: 'start'
|
|
106
64
|
}
|
|
107
|
-
}, /*#__PURE__*/React.createElement(
|
|
65
|
+
}, /*#__PURE__*/React.createElement(SourceCodeEditor, {
|
|
108
66
|
label: label,
|
|
109
67
|
language: "html",
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
'Shift-Tab': false
|
|
118
|
-
},
|
|
119
|
-
screenReaderLabel: label,
|
|
120
|
-
direction: dir,
|
|
121
|
-
rtlMoveVisually: true
|
|
122
|
-
},
|
|
68
|
+
lineNumbers: true,
|
|
69
|
+
lineWrapping: true,
|
|
70
|
+
autofocus: true,
|
|
71
|
+
spellcheck: true,
|
|
72
|
+
direction: direction,
|
|
73
|
+
rtlMoveVisually: true,
|
|
74
|
+
height: props.height,
|
|
123
75
|
value: code,
|
|
124
76
|
onChange: value => {
|
|
125
77
|
setCode(value);
|
|
126
78
|
props.onChange(value);
|
|
127
|
-
}
|
|
128
|
-
onFocus: handleFocus
|
|
79
|
+
}
|
|
129
80
|
}));
|
|
130
81
|
});
|
|
131
82
|
RceHtmlEditor.propTypes = {
|
|
132
83
|
code: string.isRequired,
|
|
133
84
|
height: string,
|
|
134
|
-
onChange: func
|
|
135
|
-
onFocus: func
|
|
85
|
+
onChange: func
|
|
136
86
|
};
|
|
137
87
|
RceHtmlEditor.defaultProps = {
|
|
138
88
|
height: 'auto',
|
|
139
|
-
onChange: _value => {}
|
|
140
|
-
onFocus: () => {}
|
|
89
|
+
onChange: _value => {}
|
|
141
90
|
};
|
|
142
91
|
export default RceHtmlEditor;
|
|
@@ -77,7 +77,7 @@ export default class EquationEditorModal extends Component {
|
|
|
77
77
|
onModalDismiss,
|
|
78
78
|
onEquationSubmit
|
|
79
79
|
} = this.props;
|
|
80
|
-
const output = this.state.advanced ? this.state.workingFormula : this.
|
|
80
|
+
const output = this.state.advanced ? this.state.workingFormula : this.getMathFiled();
|
|
81
81
|
|
|
82
82
|
if (output) {
|
|
83
83
|
onEquationSubmit(output);
|
|
@@ -99,7 +99,7 @@ export default class EquationEditorModal extends Component {
|
|
|
99
99
|
this.toggleAdvanced = () => {
|
|
100
100
|
this.setState(state => {
|
|
101
101
|
if (state.advanced) {
|
|
102
|
-
this.
|
|
102
|
+
this.setMathField(state.workingFormula || '');
|
|
103
103
|
return {
|
|
104
104
|
advanced: false,
|
|
105
105
|
workingFormula: ''
|
|
@@ -107,7 +107,7 @@ export default class EquationEditorModal extends Component {
|
|
|
107
107
|
} else {
|
|
108
108
|
return {
|
|
109
109
|
advanced: true,
|
|
110
|
-
workingFormula: this.
|
|
110
|
+
workingFormula: this.getMathFiled()
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
});
|
|
@@ -281,7 +281,7 @@ export default class EquationEditorModal extends Component {
|
|
|
281
281
|
this.registerBasicEditorListener();
|
|
282
282
|
this.setPreviewElementContent();
|
|
283
283
|
this.stubMacros();
|
|
284
|
-
if (!this.state.advanced) this.
|
|
284
|
+
if (!this.state.advanced) this.setMathField(this.state.workingFormula);
|
|
285
285
|
this.insertNewRange();
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -303,6 +303,14 @@ export default class EquationEditorModal extends Component {
|
|
|
303
303
|
});
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
+
setMathField(formula) {
|
|
307
|
+
this.mathField.setValue(formula);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
getMathFiled() {
|
|
311
|
+
return this.mathField.getValue();
|
|
312
|
+
}
|
|
313
|
+
|
|
306
314
|
}
|
|
307
315
|
EquationEditorModal.debounceRate = 1000;
|
|
308
316
|
EquationEditorModal.propTypes = {
|
|
@@ -20,6 +20,7 @@ import ReactDOM from 'react-dom';
|
|
|
20
20
|
import bridge from '../../../../bridge';
|
|
21
21
|
import { asAudioElement, findMediaPlayerIframe } from '../../shared/ContentSelection';
|
|
22
22
|
import AudioOptionsTray from '.';
|
|
23
|
+
import RCEGlobals from '../../../RCEGlobals';
|
|
23
24
|
export const CONTAINER_ID = 'instructure-audio-options-tray-container';
|
|
24
25
|
export default class TrayController {
|
|
25
26
|
constructor() {
|
|
@@ -87,14 +88,17 @@ export default class TrayController {
|
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
_applyAudioOptions(audioOptions) {
|
|
90
|
-
|
|
91
|
+
const hasAttachmentId = RCEGlobals.getFeatures().media_links_use_attachment_id && audioOptions.attachment_id;
|
|
92
|
+
|
|
93
|
+
if (!hasAttachmentId && (!audioOptions.media_object_id || audioOptions.media_object_id === 'undefined')) {
|
|
91
94
|
return;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
const container = this._audioContainer;
|
|
95
98
|
return audioOptions.updateMediaObject({
|
|
96
99
|
media_object_id: audioOptions.media_object_id,
|
|
97
|
-
subtitles: audioOptions.subtitles
|
|
100
|
+
subtitles: audioOptions.subtitles,
|
|
101
|
+
attachment_id: audioOptions.attachment_id
|
|
98
102
|
}).then(() => container === null || container === void 0 ? void 0 : container.contentWindow.location.reload()).catch(ex => {
|
|
99
103
|
// eslint-disable-next-line no-console
|
|
100
104
|
console.error('Failed updating audio captions', ex);
|
|
@@ -109,7 +113,7 @@ export default class TrayController {
|
|
|
109
113
|
window.addEventListener('message', event => {
|
|
110
114
|
var _event$data;
|
|
111
115
|
|
|
112
|
-
if ((event === null || event === void 0 ? void 0 : (_event$data = event.data) === null || _event$data === void 0 ? void 0 : _event$data.subject) ===
|
|
116
|
+
if ((event === null || event === void 0 ? void 0 : (_event$data = event.data) === null || _event$data === void 0 ? void 0 : _event$data.subject) === 'media_tracks_response') {
|
|
113
117
|
var _event$data2;
|
|
114
118
|
|
|
115
119
|
cb(event === null || event === void 0 ? void 0 : (_event$data2 = event.data) === null || _event$data2 === void 0 ? void 0 : _event$data2.payload);
|
|
@@ -146,12 +146,15 @@ export default class TrayController {
|
|
|
146
146
|
// If not, we can't update the MediaObject in the canvas db.
|
|
147
147
|
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
const hasMediaId = videoOptions.media_object_id && videoOptions.media_object_id !== 'undefined' || data.attachment_id && data.attachment_id !== 'undefined';
|
|
150
|
+
|
|
151
|
+
if (hasMediaId && !videoOptions.editLocked) {
|
|
150
152
|
videoOptions.updateMediaObject(data).then(_r => {
|
|
151
153
|
if (this.$videoContainer && videoOptions.displayAs === 'embed') {
|
|
152
154
|
this.$videoContainer.contentWindow.postMessage({
|
|
153
155
|
subject: 'reload_media',
|
|
154
|
-
media_object_id: videoOptions.media_object_id
|
|
156
|
+
media_object_id: videoOptions.media_object_id,
|
|
157
|
+
attachment_id: data.attachment_id
|
|
155
158
|
}, bridge.canvasOrigin);
|
|
156
159
|
}
|
|
157
160
|
}).catch(ex => {
|
|
@@ -185,7 +188,7 @@ export default class TrayController {
|
|
|
185
188
|
window.addEventListener('message', event => {
|
|
186
189
|
var _event$data;
|
|
187
190
|
|
|
188
|
-
if ((event === null || event === void 0 ? void 0 : (_event$data = event.data) === null || _event$data === void 0 ? void 0 : _event$data.subject) ===
|
|
191
|
+
if ((event === null || event === void 0 ? void 0 : (_event$data = event.data) === null || _event$data === void 0 ? void 0 : _event$data.subject) === 'media_tracks_response') {
|
|
189
192
|
var _event$data2;
|
|
190
193
|
|
|
191
194
|
cb(event === null || event === void 0 ? void 0 : (_event$data2 = event.data) === null || _event$data2 === void 0 ? void 0 : _event$data2.payload);
|
|
@@ -79,27 +79,32 @@ export default function (ed, document) {
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
const trayProps = Bridge.trayProps.get(ed);
|
|
82
|
-
ReactDOM.render( /*#__PURE__*/React.createElement(StoreProvider, trayProps, contentProps =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
82
|
+
ReactDOM.render( /*#__PURE__*/React.createElement(StoreProvider, trayProps, contentProps => {
|
|
83
|
+
var _RCEGlobals$getFeatur;
|
|
84
|
+
|
|
85
|
+
return /*#__PURE__*/React.createElement(UploadMedia, {
|
|
86
|
+
"data-mce-component": true,
|
|
87
|
+
rcsConfig: {
|
|
88
|
+
contextType: ed.settings.canvas_rce_user_context.type,
|
|
89
|
+
contextId: ed.settings.canvas_rce_user_context.id,
|
|
90
|
+
origin: originFromHost(contentProps.host),
|
|
91
|
+
headers: headerFor(contentProps.jwt)
|
|
92
|
+
},
|
|
93
|
+
userLocale: Bridge.userLocale,
|
|
94
|
+
mountNode: instuiPopupMountNode,
|
|
95
|
+
open: true,
|
|
96
|
+
liveRegion: () => document.getElementById('flash_screenreader_holder'),
|
|
97
|
+
onStartUpload: fileProps => handleStartUpload(fileProps),
|
|
98
|
+
onUploadComplete: (err, data) => handleUpload(err, data, contentProps.mediaUploadComplete, uploadBookmark),
|
|
99
|
+
onDismiss: handleDismiss,
|
|
100
|
+
tabs: {
|
|
101
|
+
record: true,
|
|
102
|
+
upload: true
|
|
103
|
+
},
|
|
104
|
+
uploadMediaTranslations: Bridge.uploadMediaTranslations,
|
|
105
|
+
media_links_use_attachment_id: RCEGlobals.getFeatures().media_links_use_attachment_id,
|
|
106
|
+
useStudioPlayer: (_RCEGlobals$getFeatur = RCEGlobals.getFeatures()) === null || _RCEGlobals$getFeatur === void 0 ? void 0 : _RCEGlobals$getFeatur.consolidated_media_player
|
|
107
|
+
});
|
|
108
|
+
}), container);
|
|
104
109
|
});
|
|
105
110
|
}
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
import { fromImageEmbed, fromVideoEmbed } from '../instructure_image/ImageEmbedOptions';
|
|
19
|
-
import { isOnlyTextSelected } from '../../contentInsertionUtils';
|
|
19
|
+
import { isOnlyTextSelected } from '../../contentInsertionUtils'; // eslint-disable-next-line import/no-nodejs-modules
|
|
20
|
+
|
|
20
21
|
import * as url from 'url';
|
|
21
22
|
import formatMessage from '../../../format-message';
|
|
22
23
|
import { isStudioEmbeddedMedia } from './StudioLtiSupportUtils';
|
|
24
|
+
import RCEGlobals from '../../RCEGlobals';
|
|
23
25
|
const FILE_DOWNLOAD_PATH_REGEX = /^\/(courses\/\d+\/)?files\/\d+\/download$/;
|
|
24
26
|
export const LINK_TYPE = 'link';
|
|
25
27
|
export const FILE_LINK_TYPE = 'file-link';
|
|
@@ -75,7 +77,7 @@ export function asLink($element, editor) {
|
|
|
75
77
|
const contentType = $link.getAttribute('data-course-type');
|
|
76
78
|
const fileName = $link.getAttribute('title');
|
|
77
79
|
const published = $link.getAttribute('data-published') === 'true';
|
|
78
|
-
const isPreviewable = $link.
|
|
80
|
+
const isPreviewable = $link.getAttribute('data-canvas-previewable') === 'true' || $link.classList.contains('instructure_scribd_file'); // needed to cover docs linked while there was a bug didn't add the data attr.
|
|
79
81
|
|
|
80
82
|
return {
|
|
81
83
|
$element: $link,
|
|
@@ -143,6 +145,15 @@ export function asAudioElement($element) {
|
|
|
143
145
|
} catch (e) {}
|
|
144
146
|
}
|
|
145
147
|
|
|
148
|
+
if (RCEGlobals.getFeatures().media_links_use_attachment_id) {
|
|
149
|
+
const source = $audioIframe.getAttribute('src');
|
|
150
|
+
const matches = source === null || source === void 0 ? void 0 : source.match(/\/media_attachments_iframe\/(\d+)/);
|
|
151
|
+
|
|
152
|
+
if (matches) {
|
|
153
|
+
audioOptions.attachmentId = matches[1];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
146
157
|
return audioOptions;
|
|
147
158
|
}
|
|
148
159
|
|
|
@@ -211,7 +222,7 @@ export function isImageEmbed($element) {
|
|
|
211
222
|
}
|
|
212
223
|
|
|
213
224
|
function isMediaElement($element, mediaType) {
|
|
214
|
-
var _tinymceIframeShim$fi;
|
|
225
|
+
var _tinymceIframeShim$fi, _tinymceIframeShim$ge;
|
|
215
226
|
|
|
216
227
|
// the video is hosted in an iframe, but tinymce
|
|
217
228
|
// wraps it in a span with swizzled attribute names
|
|
@@ -226,8 +237,9 @@ function isMediaElement($element, mediaType) {
|
|
|
226
237
|
}
|
|
227
238
|
|
|
228
239
|
const media_obj_id = tinymceIframeShim.getAttribute('data-mce-p-data-media-id');
|
|
240
|
+
const is_media_attachment_iframe = (_tinymceIframeShim$ge = tinymceIframeShim.getAttribute('data-mce-p-src')) === null || _tinymceIframeShim$ge === void 0 ? void 0 : _tinymceIframeShim$ge.includes('media_attachments_iframe');
|
|
229
241
|
|
|
230
|
-
if (!media_obj_id) {
|
|
242
|
+
if (!media_obj_id && !is_media_attachment_iframe) {
|
|
231
243
|
return false;
|
|
232
244
|
}
|
|
233
245
|
|
package/jest/jest-setup.js
CHANGED
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
// Several components use aphrodite, which tries to manipulate the dom
|
|
20
20
|
// on a timer which expires after the test completes and the document no longer exists
|
|
21
21
|
import {StyleSheetTestUtils} from 'aphrodite'
|
|
22
|
+
// eslint-disable-next-line import/no-nodejs-modules
|
|
23
|
+
import {TextDecoder, TextEncoder} from 'util'
|
|
24
|
+
|
|
25
|
+
global.TextEncoder = TextEncoder
|
|
26
|
+
global.TextDecoder = TextDecoder
|
|
22
27
|
|
|
23
28
|
/**
|
|
24
29
|
* We want to ensure errors and warnings get appropriate eyes. If
|
|
@@ -45,6 +50,15 @@ const ignoredErrors = [
|
|
|
45
50
|
/You seem to have overlapping act\(\) calls/,
|
|
46
51
|
/A theme registry has already been initialized/,
|
|
47
52
|
/Warning: Failed prop type: Invalid prop `color` of value `secondary` supplied to `CondensedButton`, expected one of \["primary","primary-inverse"\]./,
|
|
53
|
+
/ReactDOM.render is no longer supported in React 18/,
|
|
54
|
+
/Warning: Failed %s type: %s%s/,
|
|
55
|
+
/Warning: %s: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.%s/,
|
|
56
|
+
/Warning: `ReactDOMTestUtils.act` is deprecated in favor of `React.act`. Import `act` from `react` instead of `react-dom\/test-utils`. See https:\/\/react.dev\/warnings\/react-dom-test-utils for more info./,
|
|
57
|
+
/Warning: `ReactDOMTestUtils.act` is deprecated in favor of `React.act`. Import `act` from `react` instead of `react-dom\/test-utils`./,
|
|
58
|
+
/Warning: unmountComponentAtNode is deprecated and will be removed in the next major release. Switch to the createRoot API. Learn more: https:\/\/reactjs.org\/link\/switch-to-createroot/,
|
|
59
|
+
/Warning: findDOMNode is deprecated and will be removed in the next major release. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https:\/\/reactjs.org\/link\/strict-mode-find-node/,
|
|
60
|
+
/Warning: %s uses the legacy childContextTypes API which is no longer supported and will be removed in the next major release. Use React.createContext\(\) instead/,
|
|
61
|
+
/Warning: %s uses the legacy contextTypes API which is no longer supported and will be removed in the next major release. Use React.createContext\(\) with static contextType instead./,
|
|
48
62
|
]
|
|
49
63
|
const globalWarn = global.console.warn
|
|
50
64
|
const ignoredWarnings = [
|
package/jest.config.js
CHANGED
|
@@ -34,6 +34,7 @@ module.exports = {
|
|
|
34
34
|
],
|
|
35
35
|
],
|
|
36
36
|
setupFilesAfterEnv: [
|
|
37
|
+
'@testing-library/jest-dom',
|
|
37
38
|
'<rootDir>/jest/jest-setup-framework.js',
|
|
38
39
|
'<rootDir>/../../jest/stubInstUi.js',
|
|
39
40
|
],
|
|
@@ -48,6 +49,8 @@ module.exports = {
|
|
|
48
49
|
// mock the tinymce-react Editor component
|
|
49
50
|
'@tinymce/tinymce-react': '<rootDir>/src/rce/__mocks__/tinymceReact.jsx',
|
|
50
51
|
'crypto-es': '<rootDir>/src/rce/__mocks__/_mockCryptoEs.ts',
|
|
52
|
+
'@instructure/studio-player':
|
|
53
|
+
'<rootDir>/__mocks__/@instructure/studio-player/_mockStudioPlayer.js',
|
|
51
54
|
},
|
|
52
55
|
|
|
53
56
|
transform: {
|
|
@@ -60,9 +63,7 @@ module.exports = {
|
|
|
60
63
|
['@babel/preset-react', {}],
|
|
61
64
|
['@babel/preset-typescript', {}],
|
|
62
65
|
],
|
|
63
|
-
plugins: [
|
|
64
|
-
['@babel/plugin-proposal-decorators', {legacy: true}],
|
|
65
|
-
],
|
|
66
|
+
plugins: [['@babel/plugin-proposal-decorators', {legacy: true}]],
|
|
66
67
|
},
|
|
67
68
|
],
|
|
68
69
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/canvas-rce",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.14.0",
|
|
4
4
|
"description": "A component wrapping Canvas's usage of Tinymce",
|
|
5
5
|
"main": "es/index.js",
|
|
6
6
|
"owner": "LF",
|
|
@@ -76,60 +76,60 @@
|
|
|
76
76
|
"instrument": false
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@instructure/canvas-theme": "
|
|
79
|
+
"@instructure/canvas-theme": "8.56.4",
|
|
80
80
|
"@instructure/canvas-media": "*",
|
|
81
|
-
"@instructure/debounce": "
|
|
82
|
-
"@instructure/emotion": "
|
|
81
|
+
"@instructure/debounce": "8.56.4",
|
|
82
|
+
"@instructure/emotion": "8.56.4",
|
|
83
83
|
"@instructure/k5uploader": "*",
|
|
84
84
|
"@instructure/media-capture": "^9.0.0",
|
|
85
|
-
"@instructure/theme-registry": "
|
|
86
|
-
"@instructure/ui-a11y-content": "
|
|
87
|
-
"@instructure/ui-a11y-utils": "
|
|
88
|
-
"@instructure/ui-alerts": "
|
|
89
|
-
"@instructure/ui-avatar": "
|
|
90
|
-
"@instructure/ui-badge": "
|
|
91
|
-
"@instructure/ui-billboard": "
|
|
92
|
-
"@instructure/ui-buttons": "
|
|
93
|
-
"@instructure/ui-checkbox": "
|
|
94
|
-
"@instructure/ui-code-editor": "
|
|
95
|
-
"@instructure/ui-color-utils": "
|
|
96
|
-
"@instructure/ui-file-drop": "
|
|
97
|
-
"@instructure/ui-flex": "
|
|
98
|
-
"@instructure/ui-focusable": "
|
|
99
|
-
"@instructure/ui-form-field": "
|
|
100
|
-
"@instructure/ui-grid": "
|
|
101
|
-
"@instructure/ui-heading": "
|
|
102
|
-
"@instructure/ui-icons": "
|
|
103
|
-
"@instructure/ui-img": "
|
|
104
|
-
"@instructure/ui-link": "
|
|
105
|
-
"@instructure/ui-list": "
|
|
85
|
+
"@instructure/theme-registry": "8.56.4",
|
|
86
|
+
"@instructure/ui-a11y-content": "8.56.4",
|
|
87
|
+
"@instructure/ui-a11y-utils": "8.56.4",
|
|
88
|
+
"@instructure/ui-alerts": "8.56.4",
|
|
89
|
+
"@instructure/ui-avatar": "8.56.4",
|
|
90
|
+
"@instructure/ui-badge": "8.56.4",
|
|
91
|
+
"@instructure/ui-billboard": "8.56.4",
|
|
92
|
+
"@instructure/ui-buttons": "8.56.4",
|
|
93
|
+
"@instructure/ui-checkbox": "8.56.4",
|
|
94
|
+
"@instructure/ui-source-code-editor": "8.56.4",
|
|
95
|
+
"@instructure/ui-color-utils": "8.56.4",
|
|
96
|
+
"@instructure/ui-file-drop": "8.56.4",
|
|
97
|
+
"@instructure/ui-flex": "8.56.4",
|
|
98
|
+
"@instructure/ui-focusable": "8.56.4",
|
|
99
|
+
"@instructure/ui-form-field": "8.56.4",
|
|
100
|
+
"@instructure/ui-grid": "8.56.4",
|
|
101
|
+
"@instructure/ui-heading": "8.56.4",
|
|
102
|
+
"@instructure/ui-icons": "8.56.4",
|
|
103
|
+
"@instructure/ui-img": "8.56.4",
|
|
104
|
+
"@instructure/ui-link": "8.56.4",
|
|
105
|
+
"@instructure/ui-list": "8.56.4",
|
|
106
106
|
"@instructure/ui-media-player": "^9.0.0",
|
|
107
|
-
"@instructure/ui-menu": "
|
|
108
|
-
"@instructure/ui-modal": "
|
|
109
|
-
"@instructure/ui-motion": "
|
|
110
|
-
"@instructure/ui-number-input": "
|
|
111
|
-
"@instructure/ui-overlays": "
|
|
112
|
-
"@instructure/ui-pagination": "
|
|
113
|
-
"@instructure/ui-popover": "
|
|
114
|
-
"@instructure/ui-radio-input": "
|
|
115
|
-
"@instructure/ui-react-utils": "
|
|
116
|
-
"@instructure/ui-simple-select": "
|
|
117
|
-
"@instructure/ui-spinner": "
|
|
118
|
-
"@instructure/ui-svg-images": "
|
|
119
|
-
"@instructure/ui-table": "
|
|
120
|
-
"@instructure/ui-tabs": "
|
|
121
|
-
"@instructure/ui-text-area": "
|
|
122
|
-
"@instructure/ui-text-input": "
|
|
123
|
-
"@instructure/ui-text": "
|
|
124
|
-
"@instructure/ui-themes": "
|
|
125
|
-
"@instructure/ui-toggle-details": "
|
|
126
|
-
"@instructure/ui-tooltip": "
|
|
127
|
-
"@instructure/ui-tray": "
|
|
128
|
-
"@instructure/ui-tree-browser": "
|
|
129
|
-
"@instructure/ui-truncate-text": "
|
|
130
|
-
"@instructure/ui-utils": "
|
|
131
|
-
"@instructure/ui-view": "
|
|
132
|
-
"@instructure/uid": "
|
|
107
|
+
"@instructure/ui-menu": "8.56.4",
|
|
108
|
+
"@instructure/ui-modal": "8.56.4",
|
|
109
|
+
"@instructure/ui-motion": "8.56.4",
|
|
110
|
+
"@instructure/ui-number-input": "8.56.4",
|
|
111
|
+
"@instructure/ui-overlays": "8.56.4",
|
|
112
|
+
"@instructure/ui-pagination": "8.56.4",
|
|
113
|
+
"@instructure/ui-popover": "8.56.4",
|
|
114
|
+
"@instructure/ui-radio-input": "8.56.4",
|
|
115
|
+
"@instructure/ui-react-utils": "8.56.4",
|
|
116
|
+
"@instructure/ui-simple-select": "8.56.4",
|
|
117
|
+
"@instructure/ui-spinner": "8.56.4",
|
|
118
|
+
"@instructure/ui-svg-images": "8.56.4",
|
|
119
|
+
"@instructure/ui-table": "8.56.4",
|
|
120
|
+
"@instructure/ui-tabs": "8.56.4",
|
|
121
|
+
"@instructure/ui-text-area": "8.56.4",
|
|
122
|
+
"@instructure/ui-text-input": "8.56.4",
|
|
123
|
+
"@instructure/ui-text": "8.56.4",
|
|
124
|
+
"@instructure/ui-themes": "8.56.4",
|
|
125
|
+
"@instructure/ui-toggle-details": "8.56.4",
|
|
126
|
+
"@instructure/ui-tooltip": "8.56.4",
|
|
127
|
+
"@instructure/ui-tray": "8.56.4",
|
|
128
|
+
"@instructure/ui-tree-browser": "8.56.4",
|
|
129
|
+
"@instructure/ui-truncate-text": "8.56.4",
|
|
130
|
+
"@instructure/ui-utils": "8.56.4",
|
|
131
|
+
"@instructure/ui-view": "8.56.4",
|
|
132
|
+
"@instructure/uid": "8.56.4",
|
|
133
133
|
"@sheerun/mutationobserver-shim": "^0.3.2",
|
|
134
134
|
"@tinymce/tinymce-react": "~3.8.4",
|
|
135
135
|
"aphrodite": "^2",
|
|
@@ -149,10 +149,10 @@
|
|
|
149
149
|
"minimatch": "~3.0.4",
|
|
150
150
|
"moment-timezone": "^0.5.45",
|
|
151
151
|
"prop-types": "^15",
|
|
152
|
-
"react": "^
|
|
152
|
+
"react": "^18",
|
|
153
153
|
"react-aria-live": "^2",
|
|
154
154
|
"react-color": "^2.13.4",
|
|
155
|
-
"react-dom": "^
|
|
155
|
+
"react-dom": "^18",
|
|
156
156
|
"react-draggable": "^3.3.0",
|
|
157
157
|
"react-redux": "^5",
|
|
158
158
|
"react-transition-group": "^1",
|
|
@@ -178,6 +178,7 @@
|
|
|
178
178
|
"@testing-library/react": "^12",
|
|
179
179
|
"@testing-library/react-hooks": "^5",
|
|
180
180
|
"@testing-library/user-event": "^14",
|
|
181
|
+
"@types/testing-library__jest-dom": "^5.0.0",
|
|
181
182
|
"axe-testcafe": "^3",
|
|
182
183
|
"babel-loader": "^9.1.3",
|
|
183
184
|
"babel-plugin-dynamic-import-node": "^2.2.0",
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2023 - present Instructure, Inc.
|
|
3
|
-
*
|
|
4
|
-
* This file is part of Canvas.
|
|
5
|
-
*
|
|
6
|
-
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
-
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
-
* Software Foundation, version 3 of the License.
|
|
9
|
-
*
|
|
10
|
-
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
-
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
-
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
-
* details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
-
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
|
-
export default {
|
|
19
|
-
lib: {
|
|
20
|
-
Base: {},
|
|
21
|
-
WordArray: {},
|
|
22
|
-
BufferedBlockAlgorithm: {},
|
|
23
|
-
Hasher: {},
|
|
24
|
-
Cipher: {},
|
|
25
|
-
StreamCipher: {},
|
|
26
|
-
BlockCipherMode: {},
|
|
27
|
-
BlockCipher: {},
|
|
28
|
-
CipherParams: {},
|
|
29
|
-
SerializableCipher: {},
|
|
30
|
-
PasswordBasedCipher: {}
|
|
31
|
-
},
|
|
32
|
-
x64: {
|
|
33
|
-
Word: {},
|
|
34
|
-
WordArray: {}
|
|
35
|
-
},
|
|
36
|
-
enc: {
|
|
37
|
-
Hex: {},
|
|
38
|
-
Latin1: {},
|
|
39
|
-
Utf8: {
|
|
40
|
-
parse: () => {}
|
|
41
|
-
},
|
|
42
|
-
Utf16: {},
|
|
43
|
-
Utf16BE: {},
|
|
44
|
-
Utf16LE: {},
|
|
45
|
-
Base64: {},
|
|
46
|
-
Base64url: {}
|
|
47
|
-
},
|
|
48
|
-
algo: {
|
|
49
|
-
HMAC: {},
|
|
50
|
-
MD5: {},
|
|
51
|
-
SHA1: {},
|
|
52
|
-
SHA224: {},
|
|
53
|
-
SHA256: {},
|
|
54
|
-
SHA384: {},
|
|
55
|
-
SHA512: {},
|
|
56
|
-
SHA3: {},
|
|
57
|
-
RIPEMD160: {},
|
|
58
|
-
PBKDF2: {},
|
|
59
|
-
EvpKDF: {},
|
|
60
|
-
AES: {},
|
|
61
|
-
DES: {},
|
|
62
|
-
TripleDES: {},
|
|
63
|
-
Rabbit: {},
|
|
64
|
-
RabbitLegacy: {},
|
|
65
|
-
RC4: {},
|
|
66
|
-
RC4Drop: {},
|
|
67
|
-
Blowfish: {}
|
|
68
|
-
},
|
|
69
|
-
mode: {
|
|
70
|
-
CBC: {},
|
|
71
|
-
CFB: {},
|
|
72
|
-
CTR: {},
|
|
73
|
-
CTRGladman: {},
|
|
74
|
-
ECB: {},
|
|
75
|
-
OFB: {}
|
|
76
|
-
},
|
|
77
|
-
pad: {
|
|
78
|
-
Pkcs7: {},
|
|
79
|
-
AnsiX923: {},
|
|
80
|
-
Iso10126: {},
|
|
81
|
-
Iso97971: {},
|
|
82
|
-
NoPadding: {},
|
|
83
|
-
ZeroPadding: {}
|
|
84
|
-
},
|
|
85
|
-
format: {
|
|
86
|
-
OpenSSL: {},
|
|
87
|
-
Hex: {}
|
|
88
|
-
},
|
|
89
|
-
kdf: {
|
|
90
|
-
OpenSSL: {}
|
|
91
|
-
},
|
|
92
|
-
MD5: {},
|
|
93
|
-
HmacMD5: {},
|
|
94
|
-
SHA1: {},
|
|
95
|
-
HmacSHA1: {},
|
|
96
|
-
SHA224: {},
|
|
97
|
-
HmacSHA224: {},
|
|
98
|
-
SHA256: {},
|
|
99
|
-
HmacSHA256: {},
|
|
100
|
-
SHA384: {},
|
|
101
|
-
HmacSHA384: {},
|
|
102
|
-
SHA512: {},
|
|
103
|
-
HmacSHA512: {},
|
|
104
|
-
SHA3: {},
|
|
105
|
-
HmacSHA3: {},
|
|
106
|
-
RIPEMD160: {},
|
|
107
|
-
HmacRIPEMD160: {},
|
|
108
|
-
PBKDF2: {},
|
|
109
|
-
EvpKDF: {},
|
|
110
|
-
AES: {},
|
|
111
|
-
DES: {},
|
|
112
|
-
TripleDES: {},
|
|
113
|
-
Rabbit: {},
|
|
114
|
-
RabbitLegacy: {},
|
|
115
|
-
RC4: {
|
|
116
|
-
encrypt: () => {},
|
|
117
|
-
decrypt: () => {}
|
|
118
|
-
},
|
|
119
|
-
RC4Drop: {
|
|
120
|
-
encrypt: () => {},
|
|
121
|
-
decrypt: () => {}
|
|
122
|
-
},
|
|
123
|
-
Blowfish: {}
|
|
124
|
-
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2021 - present Instructure, Inc.
|
|
3
|
-
*
|
|
4
|
-
* This file is part of Canvas.
|
|
5
|
-
*
|
|
6
|
-
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
-
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
-
* Software Foundation, version 3 of the License.
|
|
9
|
-
*
|
|
10
|
-
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
-
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
-
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
-
* details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
-
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/*
|
|
20
|
-
* This is a mock for the @tinymce/tinymce-react Editor component
|
|
21
|
-
* and the inner tinymce editor object
|
|
22
|
-
* jest.config.js moduleNameMapper has jest load this
|
|
23
|
-
* file in response to
|
|
24
|
-
* import {Editor} from '@tinymce/tinymce-react'
|
|
25
|
-
* in RCEWrapper.js
|
|
26
|
-
*/
|
|
27
|
-
import React, { useEffect, useRef } from 'react';
|
|
28
|
-
import FakeEditor from '../__tests__/FakeEditor';
|
|
29
|
-
export function Editor(props) {
|
|
30
|
-
const editorRef = useRef(null);
|
|
31
|
-
const textareaRef = useRef(null);
|
|
32
|
-
const tinymceEditor = useRef(new FakeEditor(props));
|
|
33
|
-
window.tinymce.editors[0] = tinymceEditor.current;
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
tinymceEditor.current.on('change', handleChange);
|
|
36
|
-
props.onInit && props.onInit({}, tinymceEditor.current); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
function handleChange(event) {
|
|
40
|
-
var _props$onEditorChange;
|
|
41
|
-
|
|
42
|
-
(_props$onEditorChange = props.onEditorChange) === null || _props$onEditorChange === void 0 ? void 0 : _props$onEditorChange.call(props, event.target.value);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
46
|
-
ref: editorRef
|
|
47
|
-
}, /*#__PURE__*/React.createElement("textarea", {
|
|
48
|
-
ref: textareaRef,
|
|
49
|
-
id: props.id,
|
|
50
|
-
name: props.textareaName,
|
|
51
|
-
value: props.initialValue,
|
|
52
|
-
onInput: handleChange,
|
|
53
|
-
onChange: handleChange
|
|
54
|
-
}));
|
|
55
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2019 - present Instructure, Inc.
|
|
3
|
-
*
|
|
4
|
-
* This file is part of Canvas.
|
|
5
|
-
*
|
|
6
|
-
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
-
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
-
* Software Foundation, version 3 of the License.
|
|
9
|
-
*
|
|
10
|
-
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
-
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
-
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
-
* details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
-
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
|
-
const screenfull = {
|
|
19
|
-
on() {},
|
|
20
|
-
|
|
21
|
-
off() {}
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
export default screenfull;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2023 - present Instructure, Inc.
|
|
3
|
-
*
|
|
4
|
-
* This file is part of Canvas.
|
|
5
|
-
*
|
|
6
|
-
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
-
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
-
* Software Foundation, version 3 of the License.
|
|
9
|
-
*
|
|
10
|
-
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
-
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
-
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
-
* details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
-
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
|
-
export default [{
|
|
19
|
-
test: jest.fn().mockReturnValue(false),
|
|
20
|
-
data: jest.fn().mockReturnValue({
|
|
21
|
-
select: 'a',
|
|
22
|
-
checkbox: true,
|
|
23
|
-
color: 'rgba(40, 100, 200, 0.6)',
|
|
24
|
-
text: 'Text'
|
|
25
|
-
}),
|
|
26
|
-
form: jest.fn().mockReturnValue([{
|
|
27
|
-
label: 'Select Field',
|
|
28
|
-
dataKey: 'select',
|
|
29
|
-
options: [['a', 'A'], ['b', 'B']]
|
|
30
|
-
}, {
|
|
31
|
-
label: 'Select Field',
|
|
32
|
-
dataKey: 'checkbox',
|
|
33
|
-
checkbox: true
|
|
34
|
-
}, {
|
|
35
|
-
label: 'Select Field',
|
|
36
|
-
dataKey: 'color',
|
|
37
|
-
color: true
|
|
38
|
-
}, {
|
|
39
|
-
label: 'Text Field',
|
|
40
|
-
dataKey: 'text',
|
|
41
|
-
disabledIf: () => true
|
|
42
|
-
}, {
|
|
43
|
-
label: 'Text Area',
|
|
44
|
-
dataKey: 'textarea',
|
|
45
|
-
textarea: true
|
|
46
|
-
}]),
|
|
47
|
-
rootNode: jest.fn(),
|
|
48
|
-
update: jest.fn(),
|
|
49
|
-
message: jest.fn().mockReturnValue('Error Message'),
|
|
50
|
-
why: jest.fn().mockReturnValue('Why Text'),
|
|
51
|
-
link: 'http://some-url',
|
|
52
|
-
linkText: jest.fn().mockReturnValue('Link for learning more')
|
|
53
|
-
}];
|