Découvrez les nouveautés de cette version : Fonctionnalités, améliorations et évolutions vous attendent ! 👉 Cliquez ici pour en savoir plus

Modifications pour le document DiagramEditSheet

Modifié par Admin le 19/03/2025 - 19:24

Depuis la version 9.1
modifié par Admin
sur 19/03/2025 - 19:24
Commentaire de modification : Install extension [com.xwiki.diagram:application-diagram/1.22.1]
À la version 7.1
modifié par Admin
sur 08/11/2024 - 07:52
Commentaire de modification : Install extension [com.xwiki.diagram:application-diagram/1.21]

Résumé

Détails

XWiki.JavaScriptExtension[1]
Code
... ... @@ -105,19 +105,18 @@
105 105   var attachmentReference = new XWiki.AttachmentReference(fileName, documentReference);
106 106   var uploadMethod = (diagramConfig.isTemporaryUploadSupported) ? xutils.temporaryUploadAttachment : xutils.uploadAttachment;
107 107   var uploadAttachment = $.proxy(uploadMethod, null, blob, attachmentReference);
108 - return uploadAttachment();
108 + // Avoid creating too many versions of the attachment. Upload the attachment even if we failed to delete it first.
109 + return xutils.deleteAttachment(attachmentReference).then(uploadAttachment, uploadAttachment);
109 109   };
110 110  
111 111   var imageCache = {};
112 - var saveFileAsPNGImageAttachment = function(file, index, originalPage) {
113 + var saveFileAsPNGImageAttachment = function(file) {
113 113   var deferred = $.Deferred();
114 - let page = file.ui.pages[index];
115 - file.ui.selectPage(page, true, null);
116 - file.getUi().exportToCanvas(/* callback */ function (canvas) {
115 + file.getUi().exportToCanvas(/* callback */ function(canvas) {
117 117   if (canvas) {
118 118   try {
119 - canvas.toBlob(function (blob) {
120 - pipeDeferred(saveBlobAsImageAttachment(blob, `${getXWikiAttachmentName(index)}.png`, file.documentReference), deferred);
118 + canvas.toBlob(function(blob) {
119 + pipeDeferred(saveBlobAsImageAttachment(blob, 'diagram.png', file.documentReference), deferred);
121 121   });
122 122   } catch(err) {
123 123   deferred.reject();
... ... @@ -130,17 +130,13 @@
130 130   $jsontool.serialize($services.localization.render('diagram.editor.saveAsImageAttachmentError')), 'error');
131 131   deferred.reject();
132 132   }, /* limitHeight */ null, /* ignoreSelection */ true, /* scale */ diagramConfig.pdfImageExportZoom);
133 - file.ui.selectPage(originalPage, true, null);
134 134   return deferred.promise();
135 135   };
136 136  
137 - var saveFileAsSVGImageAttachment = function(file, index, originalPage) {
138 - var deferred = $.Deferred()
139 - let page = file.ui.pages[index];
140 - file.ui.selectPage(page, true, null);
135 + var saveFileAsSVGImageAttachment = function(file) {
136 + var deferred = $.Deferred();
141 141   var svgRoot = file.ui.editor.graph.getSvg(/* background: */ '#ffffff', /* scale: */ null, /* border: */ null,
142 142   /* nocrop: */ true, /* crisp: */ null, /* ignoreSelection: */ true);
143 - file.ui.selectPage(originalPage, true, null);
144 144   // Embed the images because the PDF exporter might not be able to access them.
145 145   file.ui.convertImages(svgRoot, function() {
146 146   var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' +
... ... @@ -147,62 +147,28 @@
147 147   '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
148 148   mxUtils.getXml(svgRoot);
149 149   var blob = new Blob([svg], {type: 'image/svg+xml'});
150 - pipeDeferred(saveBlobAsImageAttachment(blob, `${getXWikiAttachmentName(index)}.svg`, file.documentReference),
151 - deferred);
145 + pipeDeferred(saveBlobAsImageAttachment(blob, 'diagram.svg', file.documentReference), deferred);
152 152   }, imageCache);
153 153   return deferred.promise();
154 154   };
155 155  
156 - var saveFileAsImageAttachments = function(file, index, originalPage) {
150 + var saveFileAsImageAttachments = function(file) {
157 157   // This is a workaround for https://github.com/jgraph/drawio/issues/490
158 158   // Stop editing for getting the latest content from diagram
159 159   file.ui.editor.graph.stopEditing(false);
160 160   // We upload the PNG image even if the SVG upload has failed.
161 - var pngUpload = $.proxy(saveFileAsPNGImageAttachment, null, file, index, originalPage);
162 - return saveFileAsSVGImageAttachment(file, index, originalPage).then(pngUpload, pngUpload);
155 + var pngUpload = $.proxy(saveFileAsPNGImageAttachment, null, file);
156 + return saveFileAsSVGImageAttachment(file).then(pngUpload, pngUpload);
163 163   };
164 164  
165 - var getXWikiAttachmentName = function (index) {
166 - if (index == 0)
167 - {
168 - // If is the first page we keep the old naming strategy -> diagram.png / diagram.svg
169 - return "diagram";
170 - }
171 - return `diagram${index+1}`;
172 - };
173 -
174 - var deleteAllDiagrams = function() {
175 - let baseUrl = `/xwiki/rest/diagram/${xm.documentReference.toString()}`;
176 - let queryString = $.param({"form_token": xm.form_token});
177 - return $.post(`${baseUrl}?${queryString}`);
178 - };
179 -
180 180   var saveFilesAsImageAttachments = function() {
181 - var uploadDeferredList = []
182 -
183 - forEachOpenedFile(function (file) {
184 - var uploadDeferred = $.Deferred().resolve();
185 - // Get the current page so we know where to return after saving.
186 - let originalPage = file.ui.currentPage;
187 -
188 - file.ui.pages.forEach(function (page, index) {
189 - // We do the next upload even if the previous uploads have failed.
190 - var nextUpload = $.proxy(saveFileAsImageAttachments, null, file, index,originalPage);
191 - uploadDeferred = uploadDeferred.then(nextUpload, nextUpload);
192 - uploadDeferredList.push(uploadDeferred.promise());
193 - });
160 + var uploadDeferred = $.Deferred().resolve();
161 + forEachOpenedFile(function(file) {
162 + // We do the next upload even if the previous uploads have failed.
163 + var nextUpload = $.proxy(saveFileAsImageAttachments, null, file);
164 + uploadDeferred = uploadDeferred.then(nextUpload, nextUpload);
194 194   });
195 - // Wait for all deferreds to complete.
196 - return $.when.apply($, uploadDeferredList).then(
197 - function () {
198 - // Resolve the overall promise if all succeeded.
199 - return { status: 'success' };
200 - },
201 - function () {
202 - // Reject the overall promise if any failed.
203 - return $.Deferred().reject({ status: 'fail' });
204 - }
205 - ).promise();
166 + return uploadDeferred.promise();
206 206   };
207 207  
208 208   var uploadInProgress = false;
... ... @@ -214,13 +214,10 @@
214 214   event.stopPropagation();
215 215   var saveButton = $(event.target);
216 216   saveButton.prop('disabled', true);
217 - deleteAllDiagrams()
218 - .then(saveFilesAsImageAttachments)
219 - .catch(function(e) {
178 + saveFilesAsImageAttachments().fail(function(e) {
220 220   new XWiki.widgets.Notification(
221 221   $jsontool.serialize($services.localization.render('diagram.editor.saveAsImageAttachmentError')), 'error');
222 - })
223 - .always(function() {
181 + }).always(function() {
224 224   saveButton.prop('disabled', false).click();
225 225   });
226 226   } else {
Parser le contenu
... ... @@ -1,1 +1,1 @@
1 -Non
1 +Oui
XWiki.JavaScriptExtension[2]
Code
... ... @@ -18,29 +18,6 @@
18 18   a.nodeName.toLowerCase() != b.toLowerCase() ? !1 : null == c || a.getAttribute(c) == d;
19 19   };
20 20  
21 -/**
22 - * TODO: When upgrading, make sure to check if this method has changed.
23 - * This method was copied directly from draw.io, and the only change made was the call to this.showDialog.
24 - * Both the width and height were modified to fit better within the XWiki UI.
25 - */
26 -EditorUi.prototype.showBackgroundImageDialog = function (apply, img, color, showColor) {
27 - apply = (apply != null) ? apply : mxUtils.bind(this, function (image, failed, color, shadowVisible) {
28 - if (!failed) {
29 - var change = new ChangePageSetup(this, (showColor) ? color : null, image);
30 - change.ignoreColor = !showColor;
31 - if (shadowVisible != null && showColor) {
32 - change.shadowVisible = shadowVisible;
33 - }
34 - this.editor.graph.model.execute(change);
35 - }
36 - });
37 -
38 - var dlg = new BackgroundImageDialog(this, apply, img, color, showColor);
39 - this.showDialog(dlg.container, 420, (showColor) ? 260 : 240, true, true);
40 - dlg.init();
41 -};
42 -
43 -
44 44   EditorUi.prototype.showLinkDialog = function(value, selectLabel, callback, showNewWindowOption, linkTarget) {
45 45   var resourceReference = diagramLinkHandler.getResourceReferenceFromCustomLink(value);
46 46   // We append the modal to the body element in order to fix Issue #108: "Inserting a link in full screen mode is not
... ... @@ -65,32 +65,6 @@
65 65   // Do nothing.
66 66   }
67 67  
68 - // Override the Graph.updateSvgLinks method to ensure that the links are preserved in the final SVG.
69 - // We need to directly modify the original method because drawio does not provide a parameter to override the default
70 - // behavior or a smaller method that only performs the replacement.
71 - Graph.prototype.updateSvgLinks = function (node, target, removeCustom) {
72 - var links = node.getElementsByTagName('a');
73 - for (var i = 0; i < links.length; i++) {
74 - if (links[i].getAttribute('target') == null) {
75 - var href = links[i].getAttribute('href');
76 - if (href == null) {
77 - href = links[i].getAttribute('xlink:href');
78 - }
79 -
80 - if (href != null) {
81 - if (target != null && /^https?:\/\//.test(href)) {
82 - // If the href starts with http or https, set the target attribute.
83 - links[i].setAttribute('target', target);
84 - } else if (this.isCustomLink(href)) {
85 - // Handle custom links
86 - let absoluteLink = $('<a/>').attr('href', diagramLinkHandler.getURLFromCustomLink(href)).prop('href');
87 - links[i].setAttribute('href', absoluteLink);
88 - }
89 - }
90 - }
91 - }
92 - };
93 -
94 94   // Overwrite Graph.getSvg in order to replace XWiki custom links with absolute URLs.
95 95   // Also fix the text fallback for viewers with no support for foreignObjects.
96 96   var originalGraphGetSVG = Graph.prototype.getSvg;
... ... @@ -150,6 +150,318 @@
150 150   return converter;
151 151   };
152 152  
104 + // Copied from the drawio version 24.5.4 to include a fix for importing a file in an empty diagram. This method should
105 + // be removed once we upgrade to a drawio version >= 24.4.0. Being a big method, the structure was altered just to
106 + // make it shorter.
107 + var importFilesNew = function(files, x, y, maxSize, fn, resultFn, filterFn, barrierFn,
108 + resizeDialog, maxBytes, resampleThreshold, ignoreEmbeddedXml, evt) {
109 + maxSize = (maxSize != null) ? maxSize : this.maxImageSize;
110 + maxBytes = (maxBytes != null) ? maxBytes : this.maxImageBytes;
111 + var crop = x != null && y != null;
112 + var resizeImages = true;
113 + x = (x != null) ? x : 0;
114 + y = (y != null) ? y : 0;
115 + // Checks if large images are imported
116 + var largeImages = false;
117 + if (!mxClient.IS_CHROMEAPP && files != null) {
118 + var thresh = resampleThreshold || this.resampleThreshold;
119 + for (var i = 0; i < files.length; i++) {
120 + if (files[i].type.substring(0, 9) !== 'image/svg' &&
121 + files[i].type.substring(0, 6) === 'image/' &&
122 + files[i].size > thresh) {
123 + largeImages = true;
124 + break;
125 + }
126 + }
127 + }
128 + var doImportFiles = mxUtils.bind(this, function() {
129 + var graph = this.editor.graph;
130 + var gs = graph.gridSize;
131 + fn = (fn != null) ? fn : mxUtils.bind(this, function(data, mimeType, x, y, w, h, filename, done, file) {
132 + try {
133 + if (data != null && data.substring(0, 10) == '<mxlibrary') {
134 + this.spinner.stop();
135 + this.loadLibrary(new LocalLibrary(this, data, filename));
136 + this.showSidebar();
137 + return null;
138 + }
139 + else {
140 + // Drop on empty file ignores drop location
141 + if (this.isCompatibleString(data) && files.length == 1 && evt != null &&
142 + evt.type == 'drop' && this.isBlankFile() && !this.canUndo()) {
143 + crop = false;
144 + x = 0;
145 + y = 0;
146 + }
147 + return this.importFile(data, mimeType, x, y, w, h, filename,
148 + done, file, crop, ignoreEmbeddedXml, evt);
149 + }
150 + }
151 + catch (e) {
152 + this.handleError(e);
153 + return null;
154 + }
155 + });
156 + resultFn = (resultFn != null) ? resultFn : mxUtils.bind(this, function(cells) {
157 + graph.setSelectionCells(cells);
158 + });
159 + if (this.spinner.spin(document.body, mxResources.get('loading'))) {
160 + var count = files.length;
161 + var remain = count;
162 + var queue = [];
163 + // Barrier waits for all files to be loaded asynchronously
164 + var barrier = mxUtils.bind(this, function(index, fnc) {
165 + queue[index] = fnc;
166 + if (--remain == 0) {
167 + this.spinner.stop();
168 + if (barrierFn != null) {
169 + barrierFn(queue);
170 + }
171 + else {
172 + var cells = [];
173 + graph.getModel().beginUpdate();
174 + try {
175 + for (var j = 0; j < queue.length; j++) {
176 + var tmp = queue[j]();
177 + if (tmp != null) {
178 + cells = cells.concat(tmp);
179 + }
180 + }
181 + }
182 + finally {
183 + graph.getModel().endUpdate();
184 + }
185 + }
186 + resultFn(cells);
187 + }
188 + });
189 + for (var i = 0; i < count; i++) {
190 + (mxUtils.bind(this, function(index) {
191 + var file = files[index];
192 + if (file != null) {
193 + var reader = new FileReader();
194 + reader.onload = mxUtils.bind(this, function(e) {
195 + if (filterFn == null || filterFn(file)) {
196 + try {
197 + if (file.type.substring(0, 6) == 'image/') {
198 + if (file.type.substring(0, 9) == 'image/svg') {
199 + // Checks if SVG contains content attribute
200 + var data = Graph.clipSvgDataUri(e.target.result);
201 + var comma = data.indexOf(',');
202 + var svgText = decodeURIComponent(escape(atob(data.substring(comma + 1))));
203 + var root = mxUtils.parseXml(svgText);
204 + var svgs = root.getElementsByTagName('svg');
205 + if (svgs.length > 0) {
206 + var svgRoot = svgs[0];
207 + var cont = (ignoreEmbeddedXml) ? null : svgRoot.getAttribute('content');
208 + if (cont != null && cont.charAt(0) != '<' && cont.charAt(0) != '%') {
209 + cont = unescape((window.atob) ? atob(cont) : Base64.decode(cont, true));
210 + }
211 + if (cont != null && cont.charAt(0) == '%') {
212 + cont = decodeURIComponent(cont);
213 + }
214 + if (cont != null && (cont.substring(0, 8) === '<mxfile ' ||
215 + cont.substring(0, 14) === '<mxGraphModel ')) {
216 + barrier(index, mxUtils.bind(this, function() {
217 + return fn(cont, 'text/xml', x + index * gs, y + index * gs, 0, 0, file.name);
218 + }));
219 + }
220 + else {
221 + // SVG needs special handling to add viewbox if missing and
222 + // find initial size from SVG attributes (only for IE11)
223 + barrier(index, mxUtils.bind(this, function() {
224 + try {
225 + // Parses SVG and find width and height
226 + if (root != null) {
227 + var svgs = root.getElementsByTagName('svg');
228 + if (svgs.length > 0) {
229 + var svgRoot = svgs[0];
230 + var w = svgRoot.getAttribute('width');
231 + var h = svgRoot.getAttribute('height');
232 + if (w != null && w.charAt(w.length - 1) != '%') {
233 + w = parseFloat(w);
234 + }
235 + else {
236 + w = NaN;
237 + }
238 + if (h != null && h.charAt(h.length - 1) != '%') {
239 + h = parseFloat(h);
240 + }
241 + else {
242 + h = NaN;
243 + }
244 + // Check if viewBox attribute already exists
245 + var vb = svgRoot.getAttribute('viewBox');
246 + if (vb == null || vb.length == 0) {
247 + svgRoot.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
248 + }
249 + // Uses width and height from viewbox for
250 + // missing width and height attributes
251 + else if (isNaN(w) || isNaN(h)) {
252 + var tokens = vb.split(' ');
253 + if (tokens.length > 3) {
254 + w = parseFloat(tokens[2]);
255 + h = parseFloat(tokens[3]);
256 + }
257 + }
258 + data = Editor.createSvgDataUri(mxUtils.getXml(svgRoot));
259 + var s = Math.min(1, Math.min(maxSize / Math.max(1, w)), maxSize / Math.max(1, h));
260 + var cells = fn(data, file.type, x + index * gs, y + index * gs, Math.max(
261 + 1, Math.round(w * s)), Math.max(1, Math.round(h * s)), file.name);
262 + // Hack to fix width and height asynchronously
263 + if (cells != null && (isNaN(w) || isNaN(h))) {
264 + var img = new Image();
265 + img.onload = mxUtils.bind(this, function() {
266 + w = Math.max(1, img.width);
267 + h = Math.max(1, img.height);
268 + cells[0].geometry.width = w;
269 + cells[0].geometry.height = h;
270 + svgRoot.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
271 + data = Editor.createSvgDataUri(mxUtils.getXml(svgRoot));
272 + var semi = data.indexOf(';');
273 + if (semi > 0) {
274 + data = data.substring(0, semi) + data.substring(data.indexOf(',', semi + 1));
275 + }
276 + graph.setCellStyles('image', data, [cells[0]]);
277 + });
278 + img.src = Editor.createSvgDataUri(mxUtils.getXml(svgRoot));
279 + }
280 + return cells;
281 + }
282 + }
283 + }
284 + catch (e) {
285 + // ignores any SVG parsing errors
286 + }
287 + return null;
288 + }));
289 + }
290 + }
291 + else {
292 + barrier(index, mxUtils.bind(this, function() {
293 + return null;
294 + }));
295 + }
296 + }
297 + else {
298 + // Checks if PNG+XML is available to bypass code below
299 + var containsModel = false;
300 + if (file.type == 'image/png') {
301 + var xml = (ignoreEmbeddedXml) ? null : this.extractGraphModelFromPng(e.target.result);
302 + if (xml != null && xml.length > 0) {
303 + var img = new Image();
304 + img.src = e.target.result;
305 + barrier(index, mxUtils.bind(this, function() {
306 + return fn(xml, 'text/xml', x + index * gs, y + index * gs,
307 + img.width, img.height, file.name);
308 + }));
309 + containsModel = true;
310 + }
311 + }
312 + // Additional asynchronous step for finding image size
313 + if (!containsModel) {
314 + // Cannot load local files in Chrome App
315 + if (mxClient.IS_CHROMEAPP) {
316 + this.spinner.stop();
317 + this.showError(mxResources.get('error'), mxResources.get('dragAndDropNotSupported'),
318 + mxResources.get('cancel'), mxUtils.bind(this, function()
319 + {
320 + // Hides the dialog
321 + }), null, mxResources.get('ok'), mxUtils.bind(this, function()
322 + {
323 + // Redirects to import function
324 + this.actions.get('import').funct();
325 + })
326 + );
327 + }
328 + else {
329 + this.loadImage(e.target.result, mxUtils.bind(this, function(img) {
330 + this.resizeImage(img, e.target.result, mxUtils.bind(this, function(data2, w2, h2) {
331 + barrier(index, mxUtils.bind(this, function() {
332 + // Refuses to insert images above a certain size as they kill the app
333 + if (data2 != null && data2.length < maxBytes) {
334 + var s = (!resizeImages || !this.isResampleImageSize(
335 + file.size, resampleThreshold)) ? 1 :
336 + Math.min(1, Math.min(maxSize / w2, maxSize / h2));
337 + return fn(data2, file.type, x + index * gs, y + index * gs,
338 + Math.round(w2 * s), Math.round(h2 * s), file.name);
339 + }
340 + else {
341 + this.handleError({message: mxResources.get('imageTooBig')});
342 + return null;
343 + }
344 + }));
345 + }), resizeImages, maxSize, resampleThreshold, file.size);
346 + }), mxUtils.bind(this, function() {
347 + this.handleError({message: mxResources.get('invalidOrMissingFile')});
348 + }));
349 + }
350 + }
351 + }
352 + }
353 + else {
354 + var data = e.target.result;
355 + fn(data, file.type, x + index * gs, y + index * gs, 240, 160, file.name, function(cells) {
356 + barrier(index, function() {
357 + return cells;
358 + });
359 + }, file);
360 + }
361 + }
362 + catch (e) {
363 + // Ignores file parsing error
364 + barrier(index, mxUtils.bind(this, function() {
365 + return null;
366 + }));
367 + if (window.console != null) {
368 + console.error(e, file);
369 + }
370 + }
371 + }
372 + else {
373 + // Ignores file and decrements counter
374 + barrier(index, mxUtils.bind(this, function()
375 + {
376 + return null;
377 + }));
378 + }
379 + });
380 + // Handles special cases
381 + if (/(\.v(dx|sdx?))($|\?)/i.test(file.name) || /(\.vs(x|sx?))($|\?)/i.test(file.name)) {
382 + fn(null, file.type, x + index * gs, y + index * gs, 240, 160, file.name, function(cells) {
383 + barrier(index, function() {
384 + return cells;
385 + });
386 + }, file);
387 + }
388 + else if (file.type.substring(0, 5) == 'image' || file.type == 'application/pdf') {
389 + reader.readAsDataURL(file);
390 + }
391 + else {
392 + reader.readAsText(file);
393 + }
394 + }
395 + }))(i);
396 + }
397 + }
398 + });
399 + if (largeImages) {
400 + // Workaround for lost files array in async code
401 + var tmp = [];
402 + for (var i = 0; i < files.length; i++) {
403 + tmp.push(files[i]);
404 + }
405 + files = tmp;
406 + this.confirmImageResize(function(doResize) {
407 + resizeImages = doResize;
408 + doImportFiles();
409 + }, resizeDialog);
410 + }
411 + else {
412 + doImportFiles();
413 + }
414 + };
415 +
153 153   // Override for uploading the image as attachment instead of encode it to Base64.
154 154   var originalImportFiles = EditorUi.prototype.importFiles;
155 155   EditorUi.prototype.importFiles = function(files, x, y, maxSize, fn, resultFn, filterFn, barrierFn, resizeDialog,
... ... @@ -179,7 +179,7 @@
179 179   }
180 180   };
181 181   }
182 - originalImportFiles.apply(this, importFilesArgs);
445 + importFilesNew.apply(this, importFilesArgs);
183 183   };
184 184  
185 185   // Add support for inserting images by specifying the XWiki attachment reference.
... ... @@ -313,15 +313,6 @@
313 313   };
314 314  });
315 315  
316 -define('diagramMenuTranslations', {
317 - prefix: 'diagram.editor.menu.',
318 - keys: [
319 - // File menu.
320 - 'print.label',
321 - 'print.title'
322 - ]
323 -});
324 -
325 325  /**
326 326   * Integrates draw.io diagram editor in XWiki.
327 327   */
... ... @@ -331,12 +331,11 @@
331 331   'diagram-utils',
332 332   'diagram-url-io',
333 333   'diagram-config',
334 - 'xwiki-l10n!diagramMenuTranslations',
335 335   'diagram-graph-xml-filter',
336 336   'diagram-link-editor',
337 337   'diagram-image-editor',
338 338   'diagram-external-services'
339 -], function($, diagramStore, diagramUtils, diagramUrlIO, diagramConfig, l10n) {
592 +], function($, diagramStore, diagramUtils, diagramUrlIO, diagramConfig) {
340 340  
341 341   // These variables are used to decide if an image should be uploaded at original resolution or
342 342   // should be declined for being too big.
... ... @@ -368,7 +368,6 @@
368 368  
369 369   var fixEditorUI = function(editorUI) {
370 370   cleanMenu(editorUI);
371 - renameMenu(editorUI);
372 372   fixKeyboardShortcutsAction(editorUI);
373 373   fixEditorButtons($(editorUI.container));
374 374   removeThemeButton();
... ... @@ -394,7 +394,8 @@
394 394   //
395 395   // Change the service name in order to disable notifications.
396 396   //
397 - EditorUi.prototype.getServiceName = function() {
649 + EditorUi.prototype.getServiceName = function()
650 + {
398 398   return 'xwiki.com';
399 399   };
400 400  
... ... @@ -407,31 +407,11 @@
407 407   var originalAddSubmenu = Menus.prototype.addSubmenu;
408 408   Menus.prototype.addSubmenu = function(name, menu, parent, label) {
409 409   var subMenu = this.get(name);
410 - if (subMenu && subMenu.isEnabled() !== false) {
411 - return originalAddSubmenu.apply(this, arguments);
663 + if (subMenu && subMenu.visible !== false) {
664 + originalAddSubmenu.apply(this, arguments);
412 412   }
413 413   };
414 414  
415 -
416 - /*
417 - * Map with all the menu items that we want to have a title.
418 - */
419 - const titleMap = new Map([
420 - ['print', l10n['print.title']]
421 - ]);
422 -
423 - /*
424 - * Update the title of the menu items.
425 - */
426 - var originalAddMenuItem = Menus.prototype.addMenuItem;
427 - Menus.prototype.addMenuItem = function(menu, key, parent, trigger, sprite, label) {
428 - let item = originalAddMenuItem.apply(this, arguments);
429 - if (item != null && titleMap.has(key)) {
430 - item.title = titleMap.get(key);
431 - }
432 - return item;
433 - };
434 -
435 435   // Remove the language picker because the diagram editor is configured to use the XWiki language.
436 436   var originalCreateMenubar = Menus.prototype.createMenubar;
437 437   Menus.prototype.createMenubar = function(container) {
... ... @@ -451,24 +451,6 @@
451 451   };
452 452  
453 453   //
454 - // Rename menu options to fit our needs.
455 - //
456 - var renameMenu = function(editorUI) {
457 - const menuItems = [
458 - // File menu
459 - ['print', l10n['print.label']]
460 - ];
461 -
462 - // Iterate over the array of tuples
463 - menuItems.forEach(function([menuKey, newLabel]) {
464 - var action = editorUI.actions.actions[menuKey];
465 - if (action) {
466 - action.label = newLabel;
467 - }
468 - });
469 - };
470 -
471 - //
472 472   // Clean the editor menu by removing the features that are not needed.
473 473   //
474 474   var cleanMenu = function(editorUI) {
... ... @@ -481,7 +481,7 @@
481 481   // Help menu
482 482   'downloadDesktop', 'useOffline',
483 483   // ExportAs
484 - 'exportHtml', 'exportPdf'
699 + 'exportHtml'
485 485   ].forEach(function(actionName) {
486 486   var action = editorUI.actions.actions[actionName];
487 487   if (action) {