@instructure/canvas-rce 5.13.2 → 5.13.6

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.
Files changed (130) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/es/bridge/Bridge.js +0 -4
  3. package/es/defaultTinymceConfig.js +3 -3
  4. package/es/enhance-user-content/enhance_user_content.js +31 -3
  5. package/es/index.js +2 -0
  6. package/es/rce/RCE.js +3 -1
  7. package/es/rce/RCEVariants.js +121 -0
  8. package/es/rce/RCEWrapper.js +96 -47
  9. package/es/rce/RCEWrapperProps.js +5 -2
  10. package/es/rce/StatusBar.js +67 -17
  11. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +1 -0
  12. package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +6 -1
  13. package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +9 -9
  14. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +25 -3
  15. package/es/rce/plugins/instructure_rce_external_tools/plugin.js +4 -1
  16. package/es/rce/plugins/shared/CanvasContentTray.js +6 -158
  17. package/es/rce/plugins/shared/ContentSelection.js +1 -1
  18. package/es/rce/plugins/shared/Filter.js +0 -17
  19. package/es/rce/plugins/shared/FixedContentTray.js +7 -4
  20. package/es/rce/plugins/shared/ImageOptionsForm.js +3 -2
  21. package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +160 -0
  22. package/es/rce/plugins/shared/Upload/ComputerPanel.js +1 -0
  23. package/es/rce/plugins/shared/Upload/PanelFilter.js +144 -0
  24. package/es/rce/plugins/shared/Upload/UploadFile.js +10 -2
  25. package/es/rce/plugins/shared/Upload/UploadFileModal.js +47 -11
  26. package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +20 -20
  27. package/es/rce/plugins/shared/Upload/index.js +19 -0
  28. package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +70 -0
  29. package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +510 -0
  30. package/es/rce/plugins/shared/ai_tools/aiicons.js +59 -0
  31. package/es/rce/plugins/shared/ai_tools/index.js +20 -0
  32. package/es/rce/plugins/shared/canvasContentUtils.js +190 -0
  33. package/es/rce/plugins/shared/do-fetch-api-effect/defaultFetchOptions.js +31 -0
  34. package/es/rce/plugins/shared/do-fetch-api-effect/doFetchApi.js +85 -0
  35. package/es/rce/plugins/shared/do-fetch-api-effect/get-cookie.js +29 -0
  36. package/es/rce/plugins/shared/do-fetch-api-effect/index.js +22 -0
  37. package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +116 -0
  38. package/es/rce/plugins/shared/do-fetch-api-effect/query-string-encoding.js +51 -0
  39. package/es/rce/plugins/shared/useFilterSettings.js +35 -0
  40. package/es/sidebar/actions/upload.js +5 -2
  41. package/es/translations/locales/ar.js +64 -1
  42. package/es/translations/locales/ca.js +65 -2
  43. package/es/translations/locales/cy.js +64 -1
  44. package/es/translations/locales/da-x-k12.js +65 -2
  45. package/es/translations/locales/da.js +65 -2
  46. package/es/translations/locales/de.js +65 -2
  47. package/es/translations/locales/el.js +9 -0
  48. package/es/translations/locales/en-AU-x-unimelb.js +65 -2
  49. package/es/translations/locales/en-GB-x-ukhe.js +65 -2
  50. package/es/translations/locales/en.js +65 -2
  51. package/es/translations/locales/en_AU.js +65 -2
  52. package/es/translations/locales/en_CA.js +65 -2
  53. package/es/translations/locales/en_CY.js +65 -2
  54. package/es/translations/locales/en_GB.js +65 -2
  55. package/es/translations/locales/es.js +64 -1
  56. package/es/translations/locales/es_ES.js +64 -1
  57. package/es/translations/locales/fa_IR.js +9 -0
  58. package/es/translations/locales/fi.js +64 -1
  59. package/es/translations/locales/fr.js +65 -2
  60. package/es/translations/locales/fr_CA.js +65 -2
  61. package/es/translations/locales/ga.js +62 -2
  62. package/es/translations/locales/he.js +9 -0
  63. package/es/translations/locales/hi.js +119 -2
  64. package/es/translations/locales/ht.js +65 -2
  65. package/es/translations/locales/hu.js +15 -3
  66. package/es/translations/locales/hy.js +9 -0
  67. package/es/translations/locales/id.js +65 -2
  68. package/es/translations/locales/is.js +65 -2
  69. package/es/translations/locales/it.js +65 -2
  70. package/es/translations/locales/ja.js +65 -2
  71. package/es/translations/locales/ko.js +3 -0
  72. package/es/translations/locales/mi.js +65 -2
  73. package/es/translations/locales/ms.js +64 -1
  74. package/es/translations/locales/nb-x-k12.js +65 -2
  75. package/es/translations/locales/nb.js +65 -2
  76. package/es/translations/locales/nl.js +65 -2
  77. package/es/translations/locales/nn.js +15 -3
  78. package/es/translations/locales/pl.js +64 -1
  79. package/es/translations/locales/pt.js +64 -1
  80. package/es/translations/locales/pt_BR.js +65 -2
  81. package/es/translations/locales/ru.js +64 -1
  82. package/es/translations/locales/sl.js +65 -2
  83. package/es/translations/locales/sv-x-k12.js +65 -2
  84. package/es/translations/locales/sv.js +65 -2
  85. package/es/translations/locales/th.js +64 -1
  86. package/es/translations/locales/tr.js +9 -0
  87. package/es/translations/locales/uk_UA.js +9 -0
  88. package/es/translations/locales/vi.js +64 -1
  89. package/es/translations/locales/zh-Hans.js +64 -1
  90. package/es/translations/locales/zh-Hant.js +65 -2
  91. package/es/translations/locales/zh.js +64 -1
  92. package/es/translations/locales/zh_HK.js +65 -2
  93. package/es/translations/tinymce/ar_SA.js +4 -0
  94. package/es/translations/tinymce/bg_BG.js +4 -0
  95. package/es/translations/tinymce/ca.js +4 -0
  96. package/es/translations/tinymce/cs.js +4 -0
  97. package/es/translations/tinymce/cy.js +4 -0
  98. package/es/translations/tinymce/da.js +4 -0
  99. package/es/translations/tinymce/de.js +4 -0
  100. package/es/translations/tinymce/el.js +4 -0
  101. package/es/translations/tinymce/es.js +4 -0
  102. package/es/translations/tinymce/fa_IR.js +4 -0
  103. package/es/translations/tinymce/fr_FR.js +4 -0
  104. package/es/translations/tinymce/ga.js +4 -0
  105. package/es/translations/tinymce/he_IL.js +4 -0
  106. package/es/translations/tinymce/hu_HU.js +4 -0
  107. package/es/translations/tinymce/hy.js +4 -0
  108. package/es/translations/tinymce/id.js +4 -0
  109. package/es/translations/tinymce/it.js +4 -0
  110. package/es/translations/tinymce/ja.js +4 -0
  111. package/es/translations/tinymce/ko_KR.js +4 -0
  112. package/es/translations/tinymce/nb_NO.js +4 -0
  113. package/es/translations/tinymce/nl.js +4 -0
  114. package/es/translations/tinymce/pl.js +4 -0
  115. package/es/translations/tinymce/pt_BR.js +4 -0
  116. package/es/translations/tinymce/pt_PT.js +4 -0
  117. package/es/translations/tinymce/ro.js +4 -0
  118. package/es/translations/tinymce/ru.js +4 -0
  119. package/es/translations/tinymce/ru_RU.js +5 -1
  120. package/es/translations/tinymce/sl.js +4 -0
  121. package/es/translations/tinymce/sr.js +4 -0
  122. package/es/translations/tinymce/sv_SE.js +4 -0
  123. package/es/translations/tinymce/th.js +5 -1
  124. package/es/translations/tinymce/tr_TR.js +4 -0
  125. package/es/translations/tinymce/uk_UA.js +4 -0
  126. package/es/translations/tinymce/vi_VN.js +4 -0
  127. package/es/translations/tinymce/zh_CN.js +4 -0
  128. package/es/translations/tinymce/zh_TW.js +4 -0
  129. package/jest/jest-setup.js +1 -0
  130. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,47 @@ 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.13.5 - 2024-09-25
9
+
10
+ ### Fixed
11
+
12
+ - File links with data-canvas-previewable='false' will no longer try to preview
13
+ - Change backgroundless buttons to "primary" theme color to be more visible
14
+ - Fix LTI tool scrolling issue on small iOS devices
15
+ - Adding missing translation strings
16
+ - Fixed some types of non-Canvas files from trying to preview like Canvas files
17
+
18
+ ### Changed
19
+
20
+ - Allow links with data-old-link to replace the existing src or href with the contents
21
+ of the data-old-link attribute
22
+ - Added IDs to multiple objects missing IDs
23
+ - Add loading spinners to image uploads
24
+
25
+ ## 5.13.4 - 2024-08-12
26
+
27
+ ### Fixed
28
+
29
+ - RCE "Lato Extended" now properly uses the "Lato Extended" font
30
+
31
+ ## 5.13.4 - 2024-08-12
32
+
33
+ ### Changed
34
+
35
+ - Icon Maker tray now stays open until the user closes it with the close button
36
+
37
+ ## 5.13.3 - 2024-07-22
38
+
39
+ ### Fixed
40
+
41
+ - Icon Maker tray now stays open while an image upload modal is present
42
+
43
+ ## 5.13.2 - 2024-06-26
44
+
45
+ ### Changed
46
+
47
+ - Removed polyfill.io reference from README
48
+
8
49
  ## 5.13.1 - 2024-06-03
9
50
 
10
51
  ### Changed
@@ -252,8 +252,6 @@ export default class Bridge {
252
252
  const result = this.focusedEditor.insertImage(image);
253
253
  (_this$controller4 = this.controller(this.focusedEditor.id)) === null || _this$controller4 === void 0 ? void 0 : _this$controller4.hideTray();
254
254
  return result;
255
- } else {
256
- console.warn('clicked sidebar image without a focused editor');
257
255
  }
258
256
  }
259
257
 
@@ -264,8 +262,6 @@ export default class Bridge {
264
262
  if (!this.existingContentToLink()) {
265
263
  this.focusedEditor.insertImagePlaceholder(fileMetaProps);
266
264
  }
267
- } else {
268
- console.warn('clicked sidebar image without a focused editor');
269
265
  }
270
266
  }
271
267
 
@@ -51,7 +51,7 @@ const defaultTinymceConfig = {
51
51
  // this will always be provided by the RCE
52
52
  convert_urls: false,
53
53
  // fonts specified here need to either be web-safe or self-hosted and loaded in app/stylesheets/bundles/fonts.scss
54
- font_formats: "Lato=lato,Helvetica Neue,Helvetica,Arial,sans-serif; Balsamiq Sans=Balsamiq Sans,lato,Helvetica Neue,Helvetica,Arial,sans-serif; Architect's Daughter=Architects Daughter,lato,Helvetica Neue,Helvetica,Arial,sans-serif; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Courier New=courier new,courier; Georgia=georgia,palatino; Tahoma=tahoma,arial,helvetica,sans-serif; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva",
54
+ font_formats: "Lato Extended=Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Balsamiq Sans=Balsamiq Sans,Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Architect's Daughter=Architects Daughter,Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Courier New=courier new,courier; Georgia=georgia,palatino; Tahoma=tahoma,arial,helvetica,sans-serif; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva",
55
55
  language_load: false,
56
56
  language_url: 'none',
57
57
  toolbar_mode: 'floating',
@@ -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); // guarantee relative links point to canvas
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)\/(\d+))?\/files\/(\d+)/);
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/index.js CHANGED
@@ -26,6 +26,8 @@ export * from './enhance-user-content/index';
26
26
  export const defaultConfiguration = defaultTinymceConfig;
27
27
  export { instuiPopupMountNode } from './util/fullscreenHelpers';
28
28
  export { Mathml };
29
+ export { RCEVariantValues } from './rce/RCEVariants';
30
+ export { UploadFilePanelIds, handleSubmit, UploadFile } from './rce/plugins/shared/Upload';
29
31
  export function renderIntoDiv(editorEl, props, cb) {
30
32
  const language = normalizeLocale(props.language);
31
33
  setLocale(language);
package/es/rce/RCE.js CHANGED
@@ -58,6 +58,7 @@ const RCE = /*#__PURE__*/forwardRef(function RCE(props, rceRef) {
58
58
  rcsProps,
59
59
  use_rce_icon_maker,
60
60
  features,
61
+ variant,
61
62
  onFocus,
62
63
  onBlur,
63
64
  onInit,
@@ -104,7 +105,8 @@ const RCE = /*#__PURE__*/forwardRef(function RCE(props, rceRef) {
104
105
  selector: (editorOptions === null || editorOptions === void 0 ? void 0 : editorOptions.selector) || `#${textareaId}`,
105
106
  height,
106
107
  language: editorLanguage(props.language)
107
- }
108
+ },
109
+ variant
108
110
  };
109
111
  wrapInitCb(mirroredAttrs, iProps.editorOptions);
110
112
  return iProps;
@@ -0,0 +1,121 @@
1
+ /*
2
+ * Copyright (C) 2024 - 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
+ import formatMessage from '../format-message';
19
+ export const RCEVariantValues = ['full', 'lite', 'text-only'];
20
+ export function getMenubarForVariant(variant) {
21
+ if (variant === 'full') {
22
+ return 'edit view insert format tools table';
23
+ }
24
+
25
+ return '';
26
+ }
27
+ export function getMenuForVariant(variant) {
28
+ if (variant === 'full') {
29
+ return {
30
+ edit: {
31
+ title: formatMessage('Edit'),
32
+ items: `undo redo | cut copy paste | selectall`
33
+ },
34
+ format: {
35
+ title: formatMessage('Format'),
36
+ items: 'bold italic underline strikethrough superscript subscript codeformat | formats blockformats fontformats fontsizes align directionality | forecolor backcolor | removeformat'
37
+ },
38
+ insert: {
39
+ title: formatMessage('Insert'),
40
+ items: 'instructure_links instructure_image instructure_media instructure_document instructure_icon_maker | instructure_equation inserttable instructure_media_embed | hr'
41
+ },
42
+ tools: {
43
+ title: formatMessage('Tools'),
44
+ items: 'instructure_wordcount lti_tools_menuitem instructure_search_and_replace'
45
+ },
46
+ view: {
47
+ title: formatMessage('View'),
48
+ items: 'instructure_fullscreen instructure_exit_fullscreen instructure_html_view'
49
+ }
50
+ };
51
+ }
52
+
53
+ return {};
54
+ }
55
+ export function getToolbarForVariant(variant) {
56
+ let ltiToolFavorites = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
57
+
58
+ if (variant === 'lite') {
59
+ return [{
60
+ name: formatMessage('Styles'),
61
+ items: ['formatselect']
62
+ }, {
63
+ name: formatMessage('Formatting'),
64
+ items: ['bold', 'italic', 'underline', 'forecolor']
65
+ }, {
66
+ name: formatMessage('Content'),
67
+ items: ['instructure_links', 'instructure_image']
68
+ }, {
69
+ name: formatMessage('Lists'),
70
+ items: ['bullist']
71
+ }, {
72
+ name: formatMessage('Miscellaneous'),
73
+ items: ['instructure_equation']
74
+ }];
75
+ }
76
+
77
+ if (variant === 'text-only') {
78
+ return [{
79
+ name: formatMessage('Formatting'),
80
+ items: ['bold', 'italic', 'underline']
81
+ }, {
82
+ name: formatMessage('Content'),
83
+ items: ['instructure_links']
84
+ }];
85
+ }
86
+
87
+ return [{
88
+ name: formatMessage('Styles'),
89
+ items: ['fontsizeselect', 'formatselect']
90
+ }, {
91
+ name: formatMessage('Formatting'),
92
+ items: ['bold', 'italic', 'underline', 'forecolor', 'backcolor', 'inst_subscript', 'inst_superscript']
93
+ }, {
94
+ name: formatMessage('Content'),
95
+ items: ['instructure_links', 'instructure_image', 'instructure_record', 'instructure_documents', 'instructure_icon_maker']
96
+ }, {
97
+ name: formatMessage('External Tools'),
98
+ items: [...ltiToolFavorites, 'lti_tool_dropdown', 'lti_mru_button']
99
+ }, {
100
+ name: formatMessage('Alignment and Lists'),
101
+ items: ['align', 'bullist', 'inst_indent', 'inst_outdent']
102
+ }, {
103
+ name: formatMessage('Miscellaneous'),
104
+ items: ['removeformat', 'table', 'instructure_equation', 'instructure_media_embed']
105
+ }];
106
+ }
107
+ export function getStatusBarFeaturesForVariant(variant) {
108
+ let ai_text_tools = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
109
+
110
+ if (variant === 'lite' || variant === 'text-only') {
111
+ return ['keyboard_shortcuts', 'a11y_checker', 'word_count'];
112
+ }
113
+
114
+ const full_features = ['keyboard_shortcuts', 'a11y_checker', 'word_count', 'html_view', 'fullscreen', 'resize_handle'];
115
+
116
+ if (ai_text_tools) {
117
+ full_features.push('ai_tools');
118
+ }
119
+
120
+ return full_features;
121
+ }
@@ -60,6 +60,7 @@ import { IconMoreSolid } from '@instructure/ui-icons/es/svg';
60
60
  import EncryptedStorage from '../util/encrypted-storage';
61
61
  import buildStyle from './style';
62
62
  import { externalToolsForToolbar } from './plugins/instructure_rce_external_tools/RceToolWrapper';
63
+ import { getMenubarForVariant, getMenuForVariant, getToolbarForVariant, getStatusBarFeaturesForVariant } from './RCEVariants';
63
64
  const RestoreAutoSaveModal = /*#__PURE__*/React.lazy(() => import('./RestoreAutoSaveModal'));
64
65
  const RceHtmlEditor = /*#__PURE__*/React.lazy(() => import('./RceHtmlEditor'));
65
66
  const ASYNC_FOCUS_TIMEOUT = 250;
@@ -693,6 +694,72 @@ class RCEWrapper extends React.Component {
693
694
  }
694
695
  };
695
696
 
697
+ this.handleAIClick = () => {
698
+ import('./plugins/shared/ai_tools').then(module => {
699
+ this.AIToolsTray = module.AIToolsTray;
700
+ this.setState({
701
+ AIToolsOpen: true,
702
+ AITToolsFocusReturn: document.activeElement
703
+ });
704
+ }).catch(ex => {
705
+ // eslint-disable-next-line no-console
706
+ console.error('Failed loading the AIToolsTray', ex);
707
+ });
708
+ };
709
+
710
+ this.closeAITools = () => {
711
+ this.setState({
712
+ AIToolsOpen: false
713
+ });
714
+ };
715
+
716
+ this.AIToolsExited = () => {
717
+ if (this.state.AITToolsFocusReturn === this.iframe) {
718
+ // launched using a kb shortcut
719
+ // the iframe has focus so we need to forward it on to tinymce editor
720
+ this.editor.focus(false);
721
+ } else if (this.state.AITToolsFocusReturn === document.getElementById(`show-on-focus-btn-${this.id}`)) {
722
+ var _this$_showOnFocusBut2;
723
+
724
+ // launched from showOnFocus button
725
+ // edge case where focusing KBShortcutFocusReturn doesn't work
726
+ (_this$_showOnFocusBut2 = this._showOnFocusButton) === null || _this$_showOnFocusBut2 === void 0 ? void 0 : _this$_showOnFocusBut2.focus();
727
+ } else {
728
+ var _this$state$AITToolsF;
729
+
730
+ // launched from kb shortcut button on status bar
731
+ (_this$state$AITToolsF = this.state.AITToolsFocusReturn) === null || _this$state$AITToolsF === void 0 ? void 0 : _this$state$AITToolsF.focus();
732
+ }
733
+ };
734
+
735
+ this.handleInsertAIContent = content => {
736
+ const editor = this.mceInstance();
737
+ contentInsertion.insertContent(editor, content);
738
+ };
739
+
740
+ this.handleReplaceAIContent = content => {
741
+ const ed = this.mceInstance();
742
+ const selection = ed.selection;
743
+
744
+ if (selection.getContent().length > 0) {
745
+ selection.setContent(content);
746
+ } else {
747
+ ed.selection.select(ed.getBody(), true);
748
+ selection.setContent(content);
749
+ }
750
+ };
751
+
752
+ this.getCurrentContentForAI = () => {
753
+ const selected = this.mceInstance().selection.getContent();
754
+ return selected ? {
755
+ type: 'selection',
756
+ content: selected
757
+ } : {
758
+ type: 'full',
759
+ content: this.mceInstance().getContent()
760
+ };
761
+ };
762
+
696
763
  this.setFocusAbilityForHeader = focusable => {
697
764
  // Sets aria-hidden to prevent screen readers focus in RCE menus and toolbar
698
765
  const header = this._elementRef.current.querySelector('.tox-editor-header');
@@ -788,7 +855,8 @@ class RCEWrapper extends React.Component {
788
855
  prevHeight: _ht
789
856
  },
790
857
  a11yErrorsCount: 0,
791
- shouldShowEditor: typeof IntersectionObserver === 'undefined' || maxInitRenderedRCEs <= 0 || currentRCECount < maxInitRenderedRCEs
858
+ shouldShowEditor: typeof IntersectionObserver === 'undefined' || maxInitRenderedRCEs <= 0 || currentRCECount < maxInitRenderedRCEs,
859
+ AIToolsOpen: false
792
860
  };
793
861
  this._statusBarId = `${this.state.id}_statusbar`;
794
862
  this.pendingEventHandlers = [];
@@ -796,12 +864,15 @@ class RCEWrapper extends React.Component {
796
864
  this.pluginsToExclude = parsePluginsToExclude(((_props$editorOptions2 = props.editorOptions) === null || _props$editorOptions2 === void 0 ? void 0 : _props$editorOptions2.plugins) || []);
797
865
  this.resourceType = props.resourceType;
798
866
  this.resourceId = props.resourceId;
867
+ this.variant = window.RCE_VARIANT || props.variant; // to facilitate testing
868
+
799
869
  this.tinymceInitOptions = this.wrapOptions(props.editorOptions);
800
870
  alertHandler.alertFunc = this.addAlert;
801
871
  this.handleContentTrayClosing = this.handleContentTrayClosing.bind(this);
802
872
  this.resizeObserver = new ResizeObserver(_entries => {
803
873
  this._handleFullscreenResize();
804
874
  });
875
+ this.AIToolsTray = undefined;
805
876
  } // when the RCE is put into fullscreen we need to move the div
806
877
  // tinymce mounts popup menus into from the body to the rce-wrapper
807
878
  // or the menus wind up behind the RCE. I can't find a way to
@@ -979,7 +1050,7 @@ class RCEWrapper extends React.Component {
979
1050
  }
980
1051
 
981
1052
  replaceCode(code) {
982
- if (code !== "" && window.confirm(formatMessage('Content in the editor will be changed. Press Cancel to keep the original content.'))) {
1053
+ if (code !== '' && window.confirm(formatMessage('Content in the editor will be changed. Press Cancel to keep the original content.'))) {
983
1054
  this.mceInstance().setContent(code);
984
1055
  }
985
1056
  }
@@ -1551,54 +1622,15 @@ class RCEWrapper extends React.Component {
1551
1622
  // things like table resizing and stuff.
1552
1623
  content_css: options.content_css || [],
1553
1624
  content_style: contentCSS,
1554
- menubar: mergeMenuItems('edit view insert format tools table', possibleNewMenubarItems),
1625
+ menubar: mergeMenuItems(getMenubarForVariant(this.variant), possibleNewMenubarItems),
1555
1626
  // default menu options listed at https://www.tiny.cloud/docs/configure/editor-appearance/#menu
1556
1627
  // tinymce's default edit and table menus are fine
1557
1628
  // note: the tinymce paste command is used here instead of instructure_paste
1558
1629
  // since we currently can't effectively paste using the clipboard api anyway.
1559
1630
  // we include all the canvas specific items in the menu and toolbar
1560
1631
  // and rely on tinymce only showing them if the plugin is provided.
1561
- menu: mergeMenu({
1562
- edit: {
1563
- title: formatMessage('Edit'),
1564
- items: `undo redo | cut copy paste | selectall`
1565
- },
1566
- format: {
1567
- title: formatMessage('Format'),
1568
- items: 'bold italic underline strikethrough superscript subscript codeformat | formats blockformats fontformats fontsizes align directionality | forecolor backcolor | removeformat'
1569
- },
1570
- insert: {
1571
- title: formatMessage('Insert'),
1572
- items: 'instructure_links instructure_image instructure_media instructure_document instructure_icon_maker | instructure_equation inserttable instructure_media_embed | hr'
1573
- },
1574
- tools: {
1575
- title: formatMessage('Tools'),
1576
- items: 'instructure_wordcount lti_tools_menuitem instructure_search_and_replace'
1577
- },
1578
- view: {
1579
- title: formatMessage('View'),
1580
- items: 'instructure_fullscreen instructure_exit_fullscreen instructure_html_view'
1581
- }
1582
- }, options.menu),
1583
- toolbar: mergeToolbar([{
1584
- name: formatMessage('Styles'),
1585
- items: ['fontsizeselect', 'formatselect']
1586
- }, {
1587
- name: formatMessage('Formatting'),
1588
- items: ['bold', 'italic', 'underline', 'forecolor', 'backcolor', 'inst_subscript', 'inst_superscript']
1589
- }, {
1590
- name: formatMessage('Content'),
1591
- items: ['instructure_links', 'instructure_image', 'instructure_record', 'instructure_documents', 'instructure_icon_maker']
1592
- }, {
1593
- name: formatMessage('External Tools'),
1594
- items: [...this.ltiToolFavorites, 'lti_tool_dropdown', 'lti_mru_button']
1595
- }, {
1596
- name: formatMessage('Alignment and Lists'),
1597
- items: ['align', 'bullist', 'inst_indent', 'inst_outdent']
1598
- }, {
1599
- name: formatMessage('Miscellaneous'),
1600
- items: ['removeformat', 'table', 'instructure_equation', 'instructure_media_embed']
1601
- }], options.toolbar),
1632
+ menu: mergeMenu(getMenuForVariant(this.variant), options.menu),
1633
+ toolbar: mergeToolbar(getToolbarForVariant(this.variant, this.ltiToolFavorites), options.toolbar),
1602
1634
  contextmenu: '',
1603
1635
  // show the browser's native context menu
1604
1636
  toolbar_mode: 'sliding',
@@ -1797,6 +1829,7 @@ class RCEWrapper extends React.Component {
1797
1829
  });
1798
1830
  }
1799
1831
 
1832
+ const statusBarFeatures = getStatusBarFeaturesForVariant(this.variant, this.props.ai_text_tools);
1800
1833
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, this.style.css), /*#__PURE__*/React.createElement(StoreProvider, {
1801
1834
  jwt: (_this$props$trayProps5 = this.props.trayProps) === null || _this$props$trayProps5 === void 0 ? void 0 : _this$props$trayProps5.jwt,
1802
1835
  refreshToken: (_this$props$trayProps6 = this.props.trayProps) === null || _this$props$trayProps6 === void 0 ? void 0 : _this$props$trayProps6.refreshToken,
@@ -1811,6 +1844,9 @@ class RCEWrapper extends React.Component {
1811
1844
  key: this.id,
1812
1845
  className: `${this.style.classNames.root} rce-wrapper`,
1813
1846
  ref: this._elementRef,
1847
+ style: this.variant === 'full' ? {
1848
+ marginBottom: '.5rem'
1849
+ } : undefined,
1814
1850
  onFocus: this.handleFocusRCE,
1815
1851
  onBlur: this.handleBlurRCE
1816
1852
  }, this.state.shouldShowOnFocusButton && /*#__PURE__*/React.createElement(ShowOnFocusButton, {
@@ -1842,7 +1878,7 @@ class RCEWrapper extends React.Component {
1842
1878
  onNodeChange: this.onNodeChange,
1843
1879
  onEditorChange: this.onEditorChange,
1844
1880
  liveRegion: this.props.liveRegion
1845
- })), /*#__PURE__*/React.createElement(StatusBar, {
1881
+ })), statusBarFeatures.length > 0 && /*#__PURE__*/React.createElement(StatusBar, {
1846
1882
  id: this._statusBarId,
1847
1883
  rceIsFullscreen: this._isFullscreen(),
1848
1884
  readOnly: this.props.readOnly,
@@ -1860,7 +1896,9 @@ class RCEWrapper extends React.Component {
1860
1896
  onWordcountModalOpen: () => launchWordcountModal(this.mceInstance(), document, {
1861
1897
  skipEditorFocus: true
1862
1898
  }),
1863
- disabledPlugins: this.pluginsToExclude
1899
+ disabledPlugins: this.pluginsToExclude,
1900
+ features: statusBarFeatures,
1901
+ onAI: this.handleAIClick
1864
1902
  }), ((_this$props$trayProps10 = this.props.trayProps) === null || _this$props$trayProps10 === void 0 ? void 0 : _this$props$trayProps10.containingContext) && /*#__PURE__*/React.createElement(CanvasContentTray, Object.assign({
1865
1903
  mountNode: instuiPopupMountNode,
1866
1904
  key: this.id,
@@ -1875,6 +1913,16 @@ class RCEWrapper extends React.Component {
1875
1913
  onExited: this.KBShortcutModalExited,
1876
1914
  onDismiss: this.closeKBShortcutModal,
1877
1915
  open: this.state.KBShortcutModalOpen
1916
+ }), this.props.ai_text_tools && this.AIToolsTray && /*#__PURE__*/React.createElement(this.AIToolsTray, {
1917
+ open: this.state.AIToolsOpen,
1918
+ container: document.querySelector('[role="main"]'),
1919
+ mountNode: instuiPopupMountNode,
1920
+ contextId: trayProps.contextId,
1921
+ contextType: trayProps.contextId,
1922
+ currentContent: this.getCurrentContentForAI(),
1923
+ onClose: this.closeAITools,
1924
+ onInsertContent: this.handleInsertAIContent,
1925
+ onReplaceContent: this.handleReplaceAIContent
1878
1926
  }), this.state.confirmAutoSave ? /*#__PURE__*/React.createElement(Suspense, {
1879
1927
  fallback: /*#__PURE__*/React.createElement(Spinner, {
1880
1928
  renderTitle: renderLoading,
@@ -1909,7 +1957,8 @@ RCEWrapper.defaultProps = {
1909
1957
  maxInitRenderedRCEs: -1,
1910
1958
  features: {},
1911
1959
  timezone: (_Intl = Intl) === null || _Intl === void 0 ? void 0 : (_Intl$DateTimeFormat = _Intl.DateTimeFormat()) === null || _Intl$DateTimeFormat === void 0 ? void 0 : (_Intl$DateTimeFormat$ = _Intl$DateTimeFormat.resolvedOptions()) === null || _Intl$DateTimeFormat$ === void 0 ? void 0 : _Intl$DateTimeFormat$.timeZone,
1912
- canvasOrigin: ''
1960
+ canvasOrigin: '',
1961
+ variant: 'full'
1913
1962
  };
1914
1963
  RCEWrapper.skinCssInjected = false;
1915
1964
 
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import PropTypes from 'prop-types';
19
19
  import { trayPropTypes } from './plugins/shared/CanvasContentTray';
20
+ import { RCEVariantValues } from './RCEVariants';
20
21
  import { PRETTY_HTML_EDITOR_VIEW, RAW_HTML_EDITOR_VIEW, WYSIWYG_VIEW } from './StatusBar'; // This file contains the prop types for the RCEWrapper component, so that types can be shared without having
21
22
  // to refactor RCEWrapper.js into typescript.
22
23
 
@@ -49,7 +50,7 @@ export const ltiToolsPropType = PropTypes.arrayOf(PropTypes.shape({
49
50
  id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
50
51
  // is this a favorite tool?
51
52
  favorite: PropTypes.bool,
52
- always_on: PropTypes.bool,
53
+ on_by_default: PropTypes.bool,
53
54
  name: PropTypes.string,
54
55
  description: PropTypes.string,
55
56
  icon_url: PropTypes.string,
@@ -127,5 +128,7 @@ export const rceWrapperPropTypes = {
127
128
  flashAlertTimeout: PropTypes.number,
128
129
  timezone: PropTypes.string,
129
130
  userCacheKey: PropTypes.string,
130
- externalToolsConfig: externalToolsConfigPropType
131
+ externalToolsConfig: externalToolsConfigPropType,
132
+ ai_text_tools: PropTypes.bool,
133
+ variant: PropTypes.oneOf(RCEVariantValues)
131
134
  };