@instructure/canvas-rce 5.15.7 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/Dockerfile +1 -1
  3. package/es/bridge/Bridge.d.ts +6 -0
  4. package/es/common/browser.js +2 -2
  5. package/es/common/fileUrl.js +13 -3
  6. package/es/defaultTinymceConfig.js +165 -4
  7. package/es/enhance-user-content/enhance_user_content.js +1 -1
  8. package/es/enhance-user-content/instructure_helper.js +7 -3
  9. package/es/rce/RCEGlobals.d.ts +0 -2
  10. package/es/rce/RCEGlobals.js +0 -1
  11. package/es/rce/RCEVariants.d.ts +1 -1
  12. package/es/rce/RCEVariants.js +8 -8
  13. package/es/rce/RCEWrapper.d.ts +0 -2
  14. package/es/rce/RCEWrapper.js +6 -27
  15. package/es/rce/contentRendering.js +3 -2
  16. package/es/rce/plugins/instructure_equation/EquationEditorModal/index.d.ts +1 -1
  17. package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +4 -7
  18. package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +33 -9
  19. package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.d.ts +1 -1
  20. package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +1 -2
  21. package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.d.ts +13 -3
  22. package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +12 -4
  23. package/es/rce/plugins/instructure_record/mediaTranslations.d.ts +3 -0
  24. package/es/rce/plugins/instructure_record/mediaTranslations.js +4 -1
  25. package/es/rce/plugins/shared/ContentSelection.js +4 -7
  26. package/es/rce/plugins/shared/DimensionsInput/DimensionInput.d.ts +4 -2
  27. package/es/rce/plugins/shared/DimensionsInput/DimensionInput.js +10 -3
  28. package/es/rce/plugins/shared/DimensionsInput/index.d.ts +2 -0
  29. package/es/rce/plugins/shared/DimensionsInput/index.js +9 -5
  30. package/es/rce/plugins/shared/ImageOptionsForm.d.ts +4 -1
  31. package/es/rce/plugins/shared/ImageOptionsForm.js +13 -3
  32. package/es/rce/plugins/shared/Upload/UrlPanel.d.ts +9 -3
  33. package/es/rce/plugins/shared/Upload/UrlPanel.js +13 -4
  34. package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +1 -1
  35. package/es/rce/plugins/shared/fileTypeUtils.js +1 -1
  36. package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +3 -2
  37. package/es/rce/plugins/tinymce-a11y-checker/plugin.js +50 -52
  38. package/es/rce/plugins/tinymce-a11y-checker/utils/dom.d.ts +6 -0
  39. package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +15 -0
  40. package/es/rce/plugins/tinymce-a11y-checker/utils/rule-enhancer.d.ts +14 -0
  41. package/es/rce/plugins/tinymce-a11y-checker/utils/rule-enhancer.js +53 -0
  42. package/es/rce/screenreaderOnFormat.d.ts +2 -0
  43. package/es/rce/screenreaderOnFormat.js +109 -0
  44. package/es/rce/style.js +29 -29
  45. package/es/rcs/api.d.ts +4 -1
  46. package/es/rcs/api.js +9 -13
  47. package/es/translations/locales/ar.js +42 -0
  48. package/es/translations/locales/ca.js +42 -0
  49. package/es/translations/locales/cy.js +42 -0
  50. package/es/translations/locales/da-x-k12.js +42 -0
  51. package/es/translations/locales/da.js +42 -0
  52. package/es/translations/locales/de.js +42 -0
  53. package/es/translations/locales/en-AU-x-unimelb.js +42 -0
  54. package/es/translations/locales/en-GB-x-ukhe.js +42 -0
  55. package/es/translations/locales/en.js +54 -0
  56. package/es/translations/locales/en_AU.js +42 -0
  57. package/es/translations/locales/en_CA.js +42 -0
  58. package/es/translations/locales/en_CY.js +42 -0
  59. package/es/translations/locales/en_GB.js +42 -0
  60. package/es/translations/locales/es.js +42 -0
  61. package/es/translations/locales/es_ES.js +42 -0
  62. package/es/translations/locales/fi.js +42 -0
  63. package/es/translations/locales/fr.js +42 -0
  64. package/es/translations/locales/fr_CA.js +42 -0
  65. package/es/translations/locales/ga.js +114 -0
  66. package/es/translations/locales/hi.js +42 -0
  67. package/es/translations/locales/ht.js +42 -0
  68. package/es/translations/locales/id.js +42 -0
  69. package/es/translations/locales/is.js +42 -0
  70. package/es/translations/locales/it.js +42 -0
  71. package/es/translations/locales/ja.js +42 -0
  72. package/es/translations/locales/mi.js +42 -0
  73. package/es/translations/locales/ms.js +42 -0
  74. package/es/translations/locales/nb-x-k12.js +42 -0
  75. package/es/translations/locales/nb.js +42 -0
  76. package/es/translations/locales/nl.js +42 -0
  77. package/es/translations/locales/pl.js +42 -0
  78. package/es/translations/locales/pt.js +42 -0
  79. package/es/translations/locales/pt_BR.js +42 -0
  80. package/es/translations/locales/ru.js +42 -0
  81. package/es/translations/locales/sl.js +42 -0
  82. package/es/translations/locales/sv-x-k12.js +42 -0
  83. package/es/translations/locales/sv.js +42 -0
  84. package/es/translations/locales/th.js +42 -0
  85. package/es/translations/locales/vi.js +42 -0
  86. package/es/translations/locales/zh-Hans.js +42 -0
  87. package/es/translations/locales/zh-Hant.js +42 -0
  88. package/es/translations/locales/zh.js +42 -0
  89. package/es/translations/locales/zh_HK.js +42 -0
  90. package/es/util/loadingPlaceholder.js +4 -3
  91. package/package.json +55 -54
  92. package/coverage/canvas-rce-jest.xml +0 -7028
  93. package/tsconfig.tsbuildinfo +0 -1
@@ -130,4 +130,19 @@ export function createStyleString(styleObj) {
130
130
  export function hasTextNode(elem) {
131
131
  const nodes = Array.from(elem.childNodes);
132
132
  return nodes.some(x => x.nodeType === Node.TEXT_NODE);
133
+ }
134
+
135
+ /**
136
+ * Notifies TinyMCE that a change has been made
137
+ * This ensures that changes persist in the editor's state without requiring additional user actions
138
+ * @returns {void}
139
+ */
140
+ export function notifyTinyMCE() {
141
+ // Get the active TinyMCE editor instance
142
+ const editor = window.tinymce?.activeEditor;
143
+ if (editor) {
144
+ // Mark the content as dirty to ensure TinyMCE knows it has changed
145
+ editor.undoManager.add();
146
+ editor.fire('Change');
147
+ }
133
148
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Enhances a rule by wrapping its update method to notify TinyMCE of changes
3
+ * @param {Object} rule - The rule to enhance
4
+ * @param {Function} [enhanceMethod] - Optional custom method to notify TinyMCE
5
+ * @returns {Object} - The enhanced rule
6
+ */
7
+ export function enhanceRule(rule: Object, enhanceMethod?: Function): Object;
8
+ /**
9
+ * Enhances an array of rules by wrapping their update methods to notify TinyMCE of changes
10
+ * @param {Array} rules - The array of rules to enhance
11
+ * @param {Function} [enhanceMethod] - Optional custom method to notify TinyMCE
12
+ * @returns {Array} - The array of enhanced rules
13
+ */
14
+ export function enhanceRules(rules: any[], enhanceMethod?: Function): any[];
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Copyright (C) 2025 - 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
+ import { notifyTinyMCE } from './dom';
20
+
21
+ /**
22
+ * Enhances a rule by wrapping its update method to notify TinyMCE of changes
23
+ * @param {Object} rule - The rule to enhance
24
+ * @param {Function} [enhanceMethod] - Optional custom method to notify TinyMCE
25
+ * @returns {Object} - The enhanced rule
26
+ */
27
+ export function enhanceRule(rule, enhanceMethod = null) {
28
+ // Skip if the rule doesn't have an update method
29
+ if (!rule.update) {
30
+ return rule;
31
+ }
32
+ const enhance = enhanceMethod || notifyTinyMCE;
33
+ const enhancedRule = {
34
+ ...rule
35
+ };
36
+ const originalUpdate = rule.update;
37
+ enhancedRule.update = (elem, data) => {
38
+ const result = originalUpdate(elem, data);
39
+ enhance();
40
+ return result;
41
+ };
42
+ return enhancedRule;
43
+ }
44
+
45
+ /**
46
+ * Enhances an array of rules by wrapping their update methods to notify TinyMCE of changes
47
+ * @param {Array} rules - The array of rules to enhance
48
+ * @param {Function} [enhanceMethod] - Optional custom method to notify TinyMCE
49
+ * @returns {Array} - The array of enhanced rules
50
+ */
51
+ export function enhanceRules(rules, enhanceMethod = null) {
52
+ return rules.map(rule => enhanceRule(rule, enhanceMethod));
53
+ }
@@ -0,0 +1,2 @@
1
+ import type { Editor } from 'tinymce';
2
+ export declare const initScreenreaderOnFormat: (editor: Editor) => void;
@@ -0,0 +1,109 @@
1
+ /*
2
+ * Copyright (C) 2025 - 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
+ import formatMessage from '../format-message';
20
+ const screenreaderMessageHolderId = 'rce_message_screenreader_holder';
21
+ const getAlertContainer = () => {
22
+ let alertContainer = document.getElementById(screenreaderMessageHolderId);
23
+ if (!alertContainer) {
24
+ alertContainer = document.createElement('div');
25
+ alertContainer.id = screenreaderMessageHolderId;
26
+ alertContainer.setAttribute('role', 'status');
27
+ alertContainer.setAttribute('aria-live', 'assertive');
28
+ alertContainer.setAttribute('aria-relevant', 'additions');
29
+ alertContainer.setAttribute('aria-atomic', 'true');
30
+ // copied from Canvas' .screenreader-only
31
+ alertContainer.setAttribute('style', 'border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; transform: translatez(0);');
32
+ document.body.appendChild(alertContainer);
33
+ }
34
+ return alertContainer;
35
+ };
36
+ const announce = message => {
37
+ const alertContainer = getAlertContainer();
38
+ const messageElement = document.createElement('span');
39
+ messageElement.textContent = message;
40
+ alertContainer.replaceChildren(messageElement);
41
+ };
42
+ const handleFormatApply = event => {
43
+ switch (event.format) {
44
+ case 'bold':
45
+ announce(formatMessage('Bold applied'));
46
+ break;
47
+ case 'italic':
48
+ announce(formatMessage('Italic applied'));
49
+ break;
50
+ case 'underline':
51
+ announce(formatMessage('Underline applied'));
52
+ break;
53
+ case 'h1':
54
+ case 'h2':
55
+ case 'h3':
56
+ case 'h4':
57
+ case 'h5':
58
+ case 'h6':
59
+ announce(formatMessage('Heading {h} applied', {
60
+ h: event.format
61
+ }));
62
+ break;
63
+ case 'p':
64
+ announce(formatMessage('Paragraph applied'));
65
+ break;
66
+ case 'div':
67
+ announce(formatMessage('Div applied'));
68
+ break;
69
+ case 'address':
70
+ announce(formatMessage('Address applied'));
71
+ break;
72
+ }
73
+ };
74
+ const handleRemoveFormat = event => {
75
+ switch (event.format) {
76
+ case 'bold':
77
+ announce(formatMessage('Bold removed'));
78
+ break;
79
+ case 'italic':
80
+ announce(formatMessage('Italic removed'));
81
+ break;
82
+ case 'underline':
83
+ announce(formatMessage('Underline removed'));
84
+ break;
85
+ case 'h1':
86
+ case 'h2':
87
+ case 'h3':
88
+ case 'h4':
89
+ case 'h5':
90
+ case 'h6':
91
+ announce(formatMessage('Heading {h} removed', {
92
+ h: event.format
93
+ }));
94
+ break;
95
+ case 'p':
96
+ announce(formatMessage('Paragraph removed'));
97
+ break;
98
+ case 'div':
99
+ announce(formatMessage('Div removed'));
100
+ break;
101
+ case 'address':
102
+ announce(formatMessage('Address removed'));
103
+ break;
104
+ }
105
+ };
106
+ export const initScreenreaderOnFormat = editor => {
107
+ editor.on('FormatApply', handleFormatApply);
108
+ editor.on('FormatRemove', handleRemoveFormat);
109
+ };
package/es/rce/style.js CHANGED
@@ -62,44 +62,44 @@ export default function buildStyle() {
62
62
  break;
63
63
  case 'canvas-a11y':
64
64
  case 'canvas-high-contrast':
65
- themeCanvasButtonBackground = variables.colors.backgroundLight;
66
- themeCanvasSecondaryButtonBorderColor = variables.colors.borderMedium;
65
+ themeCanvasButtonBackground = variables.colors.contrasts.grey1111;
66
+ themeCanvasSecondaryButtonBorderColor = variables.colors.contrasts.grey1214;
67
67
  themeCanvasLinkDecoration = 'underline';
68
- themeCanvasFocusBorderColor = variables.colors.borderBrand;
68
+ themeCanvasFocusBorderColor = variables.colors.contrasts.blue4570;
69
69
  themeCanvasFocusBoxShadow = `0 0 0 2px ${variables.colors.brand}`;
70
70
  themeCanvasBrandColor = variables.colors.brand;
71
71
  break;
72
72
  default:
73
73
  themeCanvasLinkColor = variables.colors.link;
74
74
  themeCanvasLinkDecoration = 'none';
75
- themeCanvasTextColor = variables.colors.textDarkest;
75
+ themeCanvasTextColor = variables.colors.contrasts.grey125125;
76
76
  themeCanvasBrandColor = variables.colors.brand;
77
77
  themeCanvasFocusBorderColor = variables.borders.brand;
78
78
  themeCanvasFocusBoxShadow = `0 0 0 2px ${variables.colors.brand}`;
79
79
  themeCanvasEnabledColor = variables.borders.brand;
80
- themeCanvasPrimaryButtonBackground = variables.colors.backgroundBrand;
81
- themeCanvasPrimaryButtonColor = variables.colors.textLightest;
82
- themeCanvasPrimaryButtonHoverBackground = darken(variables.colors.backgroundBrand, 10);
83
- themeActiveMenuItemBackground = variables.colors.backgroundBrand;
84
- themeActiveMenuItemLabelColor = variables.colors.textLightest;
80
+ themeCanvasPrimaryButtonBackground = variables.colors.contrasts.blue4570;
81
+ themeCanvasPrimaryButtonColor = variables.colors.contrasts.white1010;
82
+ themeCanvasPrimaryButtonHoverBackground = darken(variables.colors.contrasts.blue4570, 10);
83
+ themeActiveMenuItemBackground = variables.colors.contrasts.blue4570;
84
+ themeActiveMenuItemLabelColor = variables.colors.contrasts.white1010;
85
85
  themeTableSelectorHighlightColor = alpha(lighten(variables.colors.brand, 10), 50);
86
- themeCanvasButtonBackground = variables.colors.backgroundLightest;
87
- themeCanvasSecondaryButtonBorderColor = darken(variables.colors.backgroundLight, 10);
86
+ themeCanvasButtonBackground = variables.colors.contrasts.white1010;
87
+ themeCanvasSecondaryButtonBorderColor = darken(variables.colors.contrasts.grey1111, 10);
88
88
  break;
89
89
  }
90
90
  const classNames = {
91
91
  root: 'canvas-rce__skins--root'
92
92
  };
93
- const toolbarButtonHoverBackgroundConst = darken(variables.colors.backgroundLightest, 5);
93
+ const toolbarButtonHoverBackgroundConst = darken(variables.colors.contrasts.white1010, 5);
94
94
  const tinySplitButtonChevronHoverBackgroundConst = darken(toolbarButtonHoverBackgroundConst, 10);
95
95
  const theme = {
96
96
  canvasBackgroundColor: variables.colors.white,
97
97
  canvasTextColor: themeCanvasTextColor,
98
- canvasErrorColor: variables.colors.textDanger,
99
- canvasWarningColor: variables.colors.textWarning,
100
- canvasInfoColor: variables.colors.textInfo,
101
- canvasSuccessColor: variables.colors.textSuccess,
102
- canvasBorderColor: variables.colors.borderMedium,
98
+ canvasErrorColor: variables.colors.contrasts.red4570,
99
+ canvasWarningColor: variables.colors.contrasts.orange4570,
100
+ canvasInfoColor: variables.colors.contrasts.blue4570,
101
+ canvasSuccessColor: variables.colors.contrasts.green4570,
102
+ canvasBorderColor: variables.colors.contrasts.grey1214,
103
103
  toolbarButtonHoverBackground: toolbarButtonHoverBackgroundConst,
104
104
  // copied from INSTUI "light" Button
105
105
  tinySplitButtonChevronHoverBackground: tinySplitButtonChevronHoverBackgroundConst,
@@ -112,10 +112,10 @@ export default function buildStyle() {
112
112
  // the instui default button
113
113
  canvasButtonBackground: themeCanvasButtonBackground,
114
114
  canvasButtonBorderColor: 'transparent',
115
- canvasButtonColor: variables.colors.textDarkest,
116
- canvasButtonHoverBackground: variables.colors.backgroundLightest,
115
+ canvasButtonColor: variables.colors.contrasts.grey125125,
116
+ canvasButtonHoverBackground: variables.colors.contrasts.white1010,
117
117
  canvasButtonHoverColor: variables.colors.brand,
118
- canvasButtonActiveBackground: variables.colors.backgroundLightest,
118
+ canvasButtonActiveBackground: variables.colors.contrasts.white1010,
119
119
  canvasButtonFontWeight: variables.typography.fontWeightNormal,
120
120
  canvasButtonFontSize: variables.typography.fontSizeMedium,
121
121
  canvasButtonLineHeight: variables.forms.inputHeightMedium,
@@ -125,19 +125,19 @@ export default function buildStyle() {
125
125
  canvasPrimaryButtonColor: themeCanvasPrimaryButtonColor,
126
126
  canvasPrimaryButtonBorderColor: 'transparent',
127
127
  canvasPrimaryButtonHoverBackground: themeCanvasPrimaryButtonHoverBackground,
128
- canvasPrimaryButtonHoverColor: variables.colors.textLightest,
128
+ canvasPrimaryButtonHoverColor: variables.colors.contrasts.white1010,
129
129
  // the instui secondary button
130
- canvasSecondaryButtonBackground: variables.colors.backgroundLight,
131
- canvasSecondaryButtonColor: variables.colors.textDarkest,
130
+ canvasSecondaryButtonBackground: variables.colors.contrasts.grey1111,
131
+ canvasSecondaryButtonColor: variables.colors.contrasts.grey125125,
132
132
  canvasSecondaryButtonBorderColor: themeCanvasSecondaryButtonBorderColor,
133
- canvasSecondaryButtonHoverBackground: darken(variables.colors.backgroundLight, 10),
134
- canvasSecondaryButtonHoverColor: variables.colors.textDarkest,
133
+ canvasSecondaryButtonHoverBackground: darken(variables.colors.contrasts.grey1111, 10),
134
+ canvasSecondaryButtonHoverColor: variables.colors.contrasts.grey125125,
135
135
  canvasFocusBorderColor: themeCanvasFocusBorderColor,
136
136
  canvasFocusBorderWidth: variables.borders.widthSmall,
137
137
  // canvas really uses widthMedium
138
138
  canvasFocusBoxShadow: themeCanvasFocusBoxShadow,
139
139
  canvasEnabledColor: themeCanvasEnabledColor,
140
- canvasEnabledBoxShadow: `inset 0 0 0.1875rem 0.0625rem ${darken(variables.colors.borderLightest, 25)}`,
140
+ canvasEnabledBoxShadow: `inset 0 0 0.1875rem 0.0625rem ${darken(variables.colors.contrasts.white1010, 25)}`,
141
141
  canvasFontFamily: variables.typography.fontFamily,
142
142
  canvasFontSize: '1rem',
143
143
  canvasFontSizeSmall: variables.typography.fontSizeSmall,
@@ -148,14 +148,14 @@ export default function buildStyle() {
148
148
  canvasModalHeadingFontWeight: variables.typography.fontWeightNormal,
149
149
  canvasModalBodyPadding: variables.spacing.medium,
150
150
  canvasModalFooterPadding: variables.spacing.small,
151
- canvasModalFooterBackground: variables.colors.backgroundLight,
151
+ canvasModalFooterBackground: variables.colors.contrasts.grey1111,
152
152
  canvasFormElementMargin: `0 0 ${variables.spacing.medium} 0`,
153
- canvasFormElementLabelColor: variables.colors.textDarkest,
153
+ canvasFormElementLabelColor: variables.colors.contrasts.grey125125,
154
154
  canvasFormElementLabelMargin: `0 0 ${variables.spacing.small} 0`,
155
155
  canvasFormElementLabelFontSize: variables.typography.fontSizeMedium,
156
156
  canvasFormElementLabelFontWeight: variables.typography.fontWeightBold,
157
157
  // a11y button badge
158
- canvasBadgeBackgroundColor: variables.colors.textInfo
158
+ canvasBadgeBackgroundColor: variables.colors.contrasts.blue4570
159
159
  };
160
160
  const css = `
161
161
  .${classNames.root} {
package/es/rcs/api.d.ts CHANGED
@@ -63,7 +63,10 @@ declare class RceApiSource {
63
63
  bookmark: any;
64
64
  files: any;
65
65
  }>;
66
- fetchMedia(props: any): Promise<any>;
66
+ fetchMedia(props: any): Promise<{
67
+ bookmark: any;
68
+ files: any;
69
+ }>;
67
70
  fetchFiles(uri: any): Promise<{
68
71
  bookmark: any;
69
72
  files: any;
package/es/rcs/api.js CHANGED
@@ -21,7 +21,6 @@ import { saveClosedCaptions, saveClosedCaptionsForAttachment, CONSTANTS } from '
21
21
  import { downloadToWrap, fixupFileUrl } from '../common/fileUrl';
22
22
  import alertHandler from '../rce/alertHandler';
23
23
  import buildError from './buildError';
24
- import RCEGlobals from '../rce/RCEGlobals';
25
24
  import { parseUrlPath } from '../util/url-util';
26
25
  export function headerFor(jwt) {
27
26
  return {
@@ -164,18 +163,15 @@ class RceApiSource {
164
163
  fetchMedia(props) {
165
164
  const media = props.media[props.contextType];
166
165
  const uri = media.bookmark || this.uriFor('media', props);
167
- if (RCEGlobals.getFeatures()?.media_links_use_attachment_id) {
168
- return this.apiFetch(uri, headerFor(this.jwt)).then(({
166
+ return this.apiFetch(uri, headerFor(this.jwt)).then(({
167
+ bookmark,
168
+ files
169
+ }) => {
170
+ return {
169
171
  bookmark,
170
- files
171
- }) => {
172
- return {
173
- bookmark,
174
- files: files.map(f => fixupFileUrl(props.contextType, props.contextId, f, this.canvasOrigin))
175
- };
176
- });
177
- }
178
- return this.apiFetch(uri, headerFor(this.jwt));
172
+ files: files.map(f => fixupFileUrl(props.contextType, props.contextId, f, this.canvasOrigin))
173
+ };
174
+ });
179
175
  }
180
176
  fetchFiles(uri) {
181
177
  return this.fetchPage(uri).then(({
@@ -219,7 +215,7 @@ class RceApiSource {
219
215
  title,
220
216
  attachment_id
221
217
  }) {
222
- const uri = RCEGlobals.getFeatures()?.media_links_use_attachment_id && attachment_id ? `${this.baseUri('media_attachments', apiProps.host)}/${attachment_id}?user_entered_title=${encodeURIComponent(title)}` : `${this.baseUri('media_objects', apiProps.host)}/${media_object_id}?user_entered_title=${encodeURIComponent(title)}`;
218
+ const uri = attachment_id ? `${this.baseUri('media_attachments', apiProps.host)}/${attachment_id}?user_entered_title=${encodeURIComponent(title)}` : `${this.baseUri('media_objects', apiProps.host)}/${media_object_id}?user_entered_title=${encodeURIComponent(title)}`;
223
219
  return this.apiPost(uri, headerFor(this.jwt), null, 'PUT');
224
220
  }
225
221
 
@@ -52,6 +52,12 @@ const locale = {
52
52
  "additional_considerations_f3801683": {
53
53
  "message": "الاعتبارات الإضافية"
54
54
  },
55
+ "address_applied_64269b0b": {
56
+ "message": "تم تطبيق العنوان"
57
+ },
58
+ "address_removed_fcb496e0": {
59
+ "message": "تمت إزالة العنوان"
60
+ },
55
61
  "adjacent_links_with_the_same_url_should_be_a_singl_7a1f7f6c": {
56
62
  "message": "يجب أن تكون الروابط المتجاورة بنفس عنوان URL رابطًا فرديًا."
57
63
  },
@@ -208,6 +214,12 @@ const locale = {
208
214
  "blue_daf8fea9": {
209
215
  "message": "أزرق"
210
216
  },
217
+ "bold_applied_42d547b7": {
218
+ "message": "تم تطبيق الخط الغامق"
219
+ },
220
+ "bold_removed_da474a5c": {
221
+ "message": "تمت إزالة الخط الغامق"
222
+ },
211
223
  "border_5b08b06d": {
212
224
  "message": "الحد"
213
225
  },
@@ -574,6 +586,12 @@ const locale = {
574
586
  "display_text_link_opens_in_a_new_tab_75e9afc9": {
575
587
  "message": "عرض ارتباط النص (يفتح في علامة تبويب جديدة)"
576
588
  },
589
+ "div_applied_49ad83fc": {
590
+ "message": "تم تطبيق Div"
591
+ },
592
+ "div_removed_d13f8e17": {
593
+ "message": "تمت إزالة Div"
594
+ },
577
595
  "division_sign_72190870": {
578
596
  "message": "علامة القسمة"
579
597
  },
@@ -931,6 +949,12 @@ const locale = {
931
949
  "heading_4_b2e74be7": {
932
950
  "message": "العنوان 4"
933
951
  },
952
+ "heading_h_applied_eccd294d": {
953
+ "message": "تم تطبيق العنوان { h }"
954
+ },
955
+ "heading_h_removed_745f24a6": {
956
+ "message": "تمت إزالة العنوان { h }"
957
+ },
934
958
  "heading_levels_should_not_be_skipped_3947c0e0": {
935
959
  "message": "يجب ألا يتم تجاوز مستويات العنوان."
936
960
  },
@@ -1117,6 +1141,12 @@ const locale = {
1117
1141
  "issue_num_total_f94536cf": {
1118
1142
  "message": "مشكلة { num }/{ total }"
1119
1143
  },
1144
+ "italic_applied_8f59a684": {
1145
+ "message": "تم تطبيق الخط المائل"
1146
+ },
1147
+ "italic_removed_17cbab6f": {
1148
+ "message": "تمت إزالة الخط المائل"
1149
+ },
1120
1150
  "kappa_2f14c816": {
1121
1151
  "message": "Kappa"
1122
1152
  },
@@ -1576,6 +1606,12 @@ const locale = {
1576
1606
  "paragraph_5e5ad8eb": {
1577
1607
  "message": "الفقرة"
1578
1608
  },
1609
+ "paragraph_applied_959b3fe5": {
1610
+ "message": "تم تطبيق الفقرة"
1611
+ },
1612
+ "paragraph_removed_d09320e": {
1613
+ "message": "تمت إزالة الفقرة"
1614
+ },
1579
1615
  "paragraph_starting_with_start_a59923f8": {
1580
1616
  "message": "فقرة تبدأ بـ { start }"
1581
1617
  },
@@ -2308,6 +2344,12 @@ const locale = {
2308
2344
  "unable_to_determine_resource_selection_url_7867e060": {
2309
2345
  "message": "يتعذر تحديد عنوان URL تحديد الموارد"
2310
2346
  },
2347
+ "underline_applied_ae01ec97": {
2348
+ "message": "تم تطبيق التسطير"
2349
+ },
2350
+ "underline_removed_3693e17c": {
2351
+ "message": "تمت إزالة التسطير"
2352
+ },
2311
2353
  "union_e6b57a53": {
2312
2354
  "message": "Union"
2313
2355
  },
@@ -52,6 +52,12 @@ const locale = {
52
52
  "additional_considerations_f3801683": {
53
53
  "message": "Consideracions addicionals"
54
54
  },
55
+ "address_applied_64269b0b": {
56
+ "message": "S’ha aplicat l’adreça"
57
+ },
58
+ "address_removed_fcb496e0": {
59
+ "message": "S’ha suprimit l''adreça"
60
+ },
55
61
  "adjacent_links_with_the_same_url_should_be_a_singl_7a1f7f6c": {
56
62
  "message": "Els enllaços adjacents amb el mateix URL han de constituir un sol enllaç."
57
63
  },
@@ -208,6 +214,12 @@ const locale = {
208
214
  "blue_daf8fea9": {
209
215
  "message": "Blau"
210
216
  },
217
+ "bold_applied_42d547b7": {
218
+ "message": "S’ha aplicat el format de negreta"
219
+ },
220
+ "bold_removed_da474a5c": {
221
+ "message": "S’ha suprimit el format de negreta"
222
+ },
211
223
  "border_5b08b06d": {
212
224
  "message": "Vora"
213
225
  },
@@ -574,6 +586,12 @@ const locale = {
574
586
  "display_text_link_opens_in_a_new_tab_75e9afc9": {
575
587
  "message": "Mostra l''enllaç al text (s''obre en una pestanya nova)"
576
588
  },
589
+ "div_applied_49ad83fc": {
590
+ "message": "S’ha aplicat la divisió"
591
+ },
592
+ "div_removed_d13f8e17": {
593
+ "message": "S’ha suprimit la divisió"
594
+ },
577
595
  "division_sign_72190870": {
578
596
  "message": "Signe de la divisió"
579
597
  },
@@ -931,6 +949,12 @@ const locale = {
931
949
  "heading_4_b2e74be7": {
932
950
  "message": "Capçalera 4"
933
951
  },
952
+ "heading_h_applied_eccd294d": {
953
+ "message": "S’ha aplicat el titular { h }"
954
+ },
955
+ "heading_h_removed_745f24a6": {
956
+ "message": "S’ha suprimit el titular { h }"
957
+ },
934
958
  "heading_levels_should_not_be_skipped_3947c0e0": {
935
959
  "message": "No s’han d’ometre els nivells de les capçaleres"
936
960
  },
@@ -1117,6 +1141,12 @@ const locale = {
1117
1141
  "issue_num_total_f94536cf": {
1118
1142
  "message": "Problema { num } de { total }"
1119
1143
  },
1144
+ "italic_applied_8f59a684": {
1145
+ "message": "S’ha aplicat el format de cursiva"
1146
+ },
1147
+ "italic_removed_17cbab6f": {
1148
+ "message": "S’ha suprimit el format de cursiva"
1149
+ },
1120
1150
  "kappa_2f14c816": {
1121
1151
  "message": "Kappa"
1122
1152
  },
@@ -1576,6 +1606,12 @@ const locale = {
1576
1606
  "paragraph_5e5ad8eb": {
1577
1607
  "message": "Paràgraf"
1578
1608
  },
1609
+ "paragraph_applied_959b3fe5": {
1610
+ "message": "S’ha aplicat el paràgraf"
1611
+ },
1612
+ "paragraph_removed_d09320e": {
1613
+ "message": "S’ha suprimit el paràgraf"
1614
+ },
1579
1615
  "paragraph_starting_with_start_a59923f8": {
1580
1616
  "message": "El paràgraf comença per { start }"
1581
1617
  },
@@ -2308,6 +2344,12 @@ const locale = {
2308
2344
  "unable_to_determine_resource_selection_url_7867e060": {
2309
2345
  "message": "No s’ha pogut determinar l’URL de selecció de recursos"
2310
2346
  },
2347
+ "underline_applied_ae01ec97": {
2348
+ "message": "S’ha aplicat el format de subratllat"
2349
+ },
2350
+ "underline_removed_3693e17c": {
2351
+ "message": "S’ha suprimit el format de subratllat"
2352
+ },
2311
2353
  "union_e6b57a53": {
2312
2354
  "message": "Unió"
2313
2355
  },
@@ -52,6 +52,12 @@ const locale = {
52
52
  "additional_considerations_f3801683": {
53
53
  "message": "Ystyriaethau ychwanegol"
54
54
  },
55
+ "address_applied_64269b0b": {
56
+ "message": "Cyfeiriad wedi’i osod"
57
+ },
58
+ "address_removed_fcb496e0": {
59
+ "message": "Cyfeiriad wedi’i ddileu"
60
+ },
55
61
  "adjacent_links_with_the_same_url_should_be_a_singl_7a1f7f6c": {
56
62
  "message": "Dylai dolenni cyfagos â’r un URL fod yn un ddolen."
57
63
  },
@@ -208,6 +214,12 @@ const locale = {
208
214
  "blue_daf8fea9": {
209
215
  "message": "Glas"
210
216
  },
217
+ "bold_applied_42d547b7": {
218
+ "message": "Fformat trwm wedi’i osod"
219
+ },
220
+ "bold_removed_da474a5c": {
221
+ "message": "Fformat trwm wedi’i ddileu"
222
+ },
211
223
  "border_5b08b06d": {
212
224
  "message": "Bordor"
213
225
  },
@@ -574,6 +586,12 @@ const locale = {
574
586
  "display_text_link_opens_in_a_new_tab_75e9afc9": {
575
587
  "message": "Dangos Dolen Testun (Yn agor mewn tab newydd)"
576
588
  },
589
+ "div_applied_49ad83fc": {
590
+ "message": "Rhaniad wedi’i osod"
591
+ },
592
+ "div_removed_d13f8e17": {
593
+ "message": "Rhaniad wed’i ddileu"
594
+ },
577
595
  "division_sign_72190870": {
578
596
  "message": "Arwydd Rhannu"
579
597
  },
@@ -931,6 +949,12 @@ const locale = {
931
949
  "heading_4_b2e74be7": {
932
950
  "message": "Pennawd 4"
933
951
  },
952
+ "heading_h_applied_eccd294d": {
953
+ "message": "Pennawd { h } wedi’i osod"
954
+ },
955
+ "heading_h_removed_745f24a6": {
956
+ "message": "Pennawd { h } wedi’i ddileu"
957
+ },
934
958
  "heading_levels_should_not_be_skipped_3947c0e0": {
935
959
  "message": "Ni ddylid anwybyddu lefelau penawdau."
936
960
  },
@@ -1117,6 +1141,12 @@ const locale = {
1117
1141
  "issue_num_total_f94536cf": {
1118
1142
  "message": "Problem { num }/{ total }"
1119
1143
  },
1144
+ "italic_applied_8f59a684": {
1145
+ "message": "Fformat italig wedi’i osod"
1146
+ },
1147
+ "italic_removed_17cbab6f": {
1148
+ "message": "Fformat italig wedi’i ddileu"
1149
+ },
1120
1150
  "kappa_2f14c816": {
1121
1151
  "message": "Kappa"
1122
1152
  },
@@ -1576,6 +1606,12 @@ const locale = {
1576
1606
  "paragraph_5e5ad8eb": {
1577
1607
  "message": "Paragraff"
1578
1608
  },
1609
+ "paragraph_applied_959b3fe5": {
1610
+ "message": "Paragraff wedi’i osod"
1611
+ },
1612
+ "paragraph_removed_d09320e": {
1613
+ "message": "Paragraff wedi’i ddileu"
1614
+ },
1579
1615
  "paragraph_starting_with_start_a59923f8": {
1580
1616
  "message": "Paragraff yn dechrau gyda { start }"
1581
1617
  },
@@ -2308,6 +2344,12 @@ const locale = {
2308
2344
  "unable_to_determine_resource_selection_url_7867e060": {
2309
2345
  "message": "Does dim modd pennu url dewis adnodd"
2310
2346
  },
2347
+ "underline_applied_ae01ec97": {
2348
+ "message": "Tanlinell wedi’i gosod"
2349
+ },
2350
+ "underline_removed_3693e17c": {
2351
+ "message": "Tanlinell wedi’i dileu"
2352
+ },
2311
2353
  "union_e6b57a53": {
2312
2354
  "message": "Uniad"
2313
2355
  },