Änderungen von Dokument DiagramEditSheet
Zuletzt geändert von Daniel Herrmann am 2026/02/04 20:25
Von Version
2.1
bearbeitet von Daniel Herrmann
am 2026/02/04 20:25
am 2026/02/04 20:25
Änderungskommentar:
Install extension [com.xwiki.diagram:application-diagram/1.22.11]
Auf Version 1.1
bearbeitet von Mike Schneider
am 2025/12/30 10:37
am 2025/12/30 10:37
Änderungskommentar:
Install extension [org.xwiki.contrib:application-diagram/1.3]
Zusammenfassung
Details
- Seiteneigenschaften
-
- Dokument-Autor
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. dherrman1 +XWiki.mschneide - Inhalt
-
... ... @@ -1,34 +32,3 @@ 1 -{{include reference="Diagram.ResourceSelector.WebHome" /}} 2 - 3 -{{velocity output="false"}} 4 -#macro (diagramLinkModal) 5 - <div class="modal" id="diagramLinkModal" tabindex="-1" role="dialog" 6 - aria-labelledby="diagramLinkModal-label" data-backdrop="static" data-keyboard="false"> 7 - <div class="modal-dialog modal-lg" role="document"> 8 - <div class="modal-content"> 9 - <div class="modal-header"> 10 - <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 11 - <span aria-hidden="true">×</span> 12 - </button> 13 - <div class="modal-title" id="diagramLinkModal-label"> 14 - Link 15 - </div> 16 - </div> 17 - <div class="modal-body xform"> 18 - #resourceSelector() 19 - </div> 20 - <div class="modal-footer"> 21 - <button type="button" class="btn btn-default" data-dismiss="modal"> 22 - $escapetool.xml($services.localization.render('cancel')) 23 - </button> 24 - <button type="button" class="btn btn-primary"></button> 25 - </div> 26 - </div> 27 - </div> 28 - </div> 29 -#end 30 -{{/velocity}} 31 - 32 32 {{velocity}} 33 33 {{html clean="false"}} 34 34 #if ($doc.getObject('Diagram.DiagramClass')) ... ... @@ -35,28 +35,13 @@ 35 35 ## Disable the keyboard shortcuts because they prevent the user from typing text inside the diagram (the diagram 36 36 ## editor doesn't use standard text fields for entering the labels for the various shapes the diagram is made of) 37 37 #set ($keyboardShortcutsEnabled = false) 38 - #set ($discard = $xwiki.ssx.use('Diagram.DiagramSheet')) 7 + #set ($discard = $xwiki.ssx.use('Diagram.DiagramEditSheet')) 39 39 #set ($discard = $xwiki.jsx.use('Diagram.DiagramEditSheet')) 40 - ## Issue #219: Cannot modify diagram title in diagram editor 41 - <div class="row xform"> 42 - <div class="col-xs-12"> 43 - <dl> 44 - <dt> 45 - <label for="xwikidoctitleinput"> 46 - $escapetool.xml($services.localization.render('core.editors.content.titleField.label')) 47 - </label> 48 - </dt> 49 - <dd> 50 - <input id="xwikidoctitleinput" type="text" name="title" value="$escapetool.xml($tdoc.title)"> 51 - </dd> 52 - </dl> 53 - </div> 54 - </div> 55 - 56 - <div class="diagram-editor loading" data-diagram-config="$escapetool.xml($jsontool.serialize($diagramConfig))"> 9 + <div class="diagram-editor loading"> 57 57 <input class="diagram-content" type="hidden" name="content" value="$escapetool.xml($tdoc.content)" /> 11 + <input class="diagram-svg" type="hidden" name="Diagram.DiagramClass_0_svg" 12 + value="$!escapetool.xml($doc.getValue('svg'))" /> 58 58 </div> 59 - #diagramLinkModal() 60 60 #end 61 61 {{/html}} 62 62 {{/velocity}}
- XWiki.JavaScriptExtension[1]
-
- Code
-
... ... @@ -1,29 +1,19 @@ 1 1 /** 2 2 * Adds support for editing diagrams stored in XWiki pages. 3 3 */ 4 -define('diagramEditTranslations', { 5 - prefix: 'diagram.editor.', 6 - keys: [ 7 - 'saveAsImageAttachmentError' 8 - ] 9 -}); 10 - 11 -define('diagram-store', ['jquery', 'xwiki-meta', 'xwiki-utils', 'diagram-utils', 'diagram-config', 12 - 'xwiki-l10n!diagramEditTranslations', 'draw.io', 13 - 'xwiki-events-bridge'], function($, xm, xutils, diagramUtils, diagramConfig, l10n) { 4 +define('diagramStore', ['jquery', 'draw.io', 'xwiki-events-bridge'], function($) { 14 14 var files = []; 15 15 window._xfiles = files; 16 - var createFile = function(ui, input, title , documentReference) {17 - var file = new XWikiFile(ui, input, title , documentReference);7 + var createFile = function(ui, input, title) { 8 + var file = new XWikiFile(ui, input, title); 18 18 files.push(file); 19 19 return file; 20 20 }; 21 21 22 - var XWikiFile = function(ui, input, title, documentReference) { 13 + var XWikiFile = function(ui, input, title) { 14 + DrawioFile.call(this, ui); 23 23 this.input = input; 24 - DrawioFile.call(this, ui, input.val()); 25 25 this.title = title; 26 - this.documentReference = documentReference; 27 27 }; 28 28 29 29 mxUtils.extend(XWikiFile, DrawioFile); ... ... @@ -41,40 +41,13 @@ 41 41 setData: function(data) { 42 42 this.input.val(data); 43 43 }, 44 - isCompressed: function() { 45 - return false; 34 + updateFileData: function() { 35 + // We overwrite the base implementation because we don't want to support files that contain multiple diagrams. 36 + this.setData(mxUtils.getPrettyXml(this.ui.editor.getGraphXml())); 46 46 }, 47 - // TODO: When upgrading the drawio version, ensure that this method is copied from the drawio code and the 48 - // `resolveReferences` parameter of the getFileData is set to `true` to prevent incorrect formatting of links to 49 - // wiki pages in the diagram content. https://github.com/xwikisas/application-diagram/issues/295 50 - createData: function() { 51 - var actualPages = this.ui.pages; 52 - 53 - if (this.isRealtime()) { 54 - // Uses ownPages for getting file data below 55 - this.ui.pages = this.ownPages; 56 - 57 - // Updates view state in own current page 58 - if (this.ui.currentPage != null) { 59 - var ownPage = this.ui.getPageById( 60 - this.ui.currentPage.getId(), 61 - this.ownPages); 62 - 63 - if (ownPage != null) { 64 - ownPage.viewState = this.ui.editor.graph.getViewState(); 65 - ownPage.needsUpdate = true; 66 - } 67 - } 68 - } 69 - 70 - var result = this.ui.getFileData(null, null, null, null, null, null, null, null, this, 71 - !this.isCompressed(), true); 72 - this.ui.pages = actualPages; 73 - return result; 74 - }, 75 75 open: function() { 76 76 var graphXML = this.getData() || '<mxGraphModel/>'; 77 - this.ui.set FileData(graphXML);40 + this.ui.editor.setGraphXml(mxUtils.parseXml(graphXML).documentElement); 78 78 this.changeListener = mxUtils.bind(this, function(sender, eventObject) { 79 79 this.setModified(true); 80 80 }); ... ... @@ -92,9 +92,6 @@ 92 92 93 93 var updateFormFields = function(event) { 94 94 forEachOpenedFile(function(file) { 95 - // This is a workaround for https://github.com/jgraph/drawio/issues/490 96 - // Stop editing for getting the latest content from diagram 97 - file.ui.editor.graph.stopEditing(false); 98 98 file.updateFileData(); 99 99 }); 100 100 }; ... ... @@ -105,143 +105,19 @@ 105 105 }); 106 106 }; 107 107 108 - var pipeDeferred = function(left, right) { 109 - left.done($.proxy(right, 'resolve')).fail($.proxy(right, 'reject')); 110 - }; 68 + // We need to update the form fields before the form is validated (for Preview, Save and Save & Continue). 69 + $(document).on('xwiki:actions:beforePreview xwiki:actions:beforeSave', updateFormFields); 111 111 112 - var saveBlobAsImageAttachment = function(blob, fileName, documentReference) { 113 - var attachmentReference = new XWiki.AttachmentReference(fileName, documentReference); 114 - var uploadMethod = (diagramConfig.isTemporaryUploadSupported) ? xutils.temporaryUploadAttachment : xutils.uploadAttachment; 115 - var uploadAttachment = $.proxy(uploadMethod, null, blob, attachmentReference); 116 - return uploadAttachment(); 117 - }; 118 - 119 - var imageCache = {}; 120 - var saveFileAsPNGImageAttachment = function(file, index, originalPage) { 121 - var deferred = $.Deferred(); 122 - let page = file.ui.pages[index]; 123 - file.ui.selectPage(page, true, null); 124 - file.getUi().exportToCanvas(/* callback */ function (canvas) { 125 - if (canvas) { 126 - try { 127 - canvas.toBlob(function (blob) { 128 - pipeDeferred(saveBlobAsImageAttachment(blob, `${getXWikiAttachmentName(index)}.png`, file.documentReference), deferred); 129 - }); 130 - } catch(err) { 131 - deferred.reject(); 132 - } 133 - } else { 134 - deferred.reject(); 71 + $(document).on('xwiki:actions:beforeSave', function() { 72 + forEachOpenedFile(function(file) { 73 + var svgInput = file.input.next('.diagram-svg'); 74 + if (svgInput.length > 0) { 75 + var svgRoot = file.getUi().editor.graph.getSvg('#ffffff', true, false, false, null, true); 76 + svgInput.val(mxUtils.getXml(svgRoot)); 135 135 } 136 - }, /* width */ null, /* imageCache */ imageCache, /* background */ null, /* error */ function(e) { 137 - new XWiki.widgets.Notification( 138 - l10n['saveAsImageAttachmentError'], 'error'); 139 - deferred.reject(); 140 - }, /* limitHeight */ null, /* ignoreSelection */ true, /* scale */ diagramConfig.pdfImageExportZoom); 141 - file.ui.selectPage(originalPage, true, null); 142 - return deferred.promise(); 143 - }; 144 - 145 - var saveFileAsSVGImageAttachment = function(file, index, originalPage) { 146 - var deferred = $.Deferred() 147 - let page = file.ui.pages[index]; 148 - file.ui.selectPage(page, true, null); 149 - var svgRoot = file.ui.editor.graph.getSvg(/* background: */ '#ffffff', /* scale: */ null, /* border: */ null, 150 - /* nocrop: */ true, /* crisp: */ null, /* ignoreSelection: */ true); 151 - file.ui.selectPage(originalPage, true, null); 152 - // Embed the images because the PDF exporter might not be able to access them. 153 - file.ui.convertImages(svgRoot, function() { 154 - var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + 155 - '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + 156 - mxUtils.getXml(svgRoot); 157 - var blob = new Blob([svg], {type: 'image/svg+xml'}); 158 - pipeDeferred(saveBlobAsImageAttachment(blob, `${getXWikiAttachmentName(index)}.svg`, file.documentReference), 159 - deferred); 160 - }, imageCache); 161 - return deferred.promise(); 162 - }; 163 - 164 - var saveFileAsImageAttachments = function(file, index, originalPage) { 165 - // This is a workaround for https://github.com/jgraph/drawio/issues/490 166 - // Stop editing for getting the latest content from diagram 167 - file.ui.editor.graph.stopEditing(false); 168 - // We upload the PNG image even if the SVG upload has failed. 169 - var pngUpload = $.proxy(saveFileAsPNGImageAttachment, null, file, index, originalPage); 170 - return saveFileAsSVGImageAttachment(file, index, originalPage).then(pngUpload, pngUpload); 171 - }; 172 - 173 - var getXWikiAttachmentName = function (index) { 174 - if (index == 0) 175 - { 176 - // If is the first page we keep the old naming strategy -> diagram.png / diagram.svg 177 - return "diagram"; 178 - } 179 - return `diagram${index+1}`; 180 - }; 181 - 182 - var deleteAllDiagrams = function() { 183 - let baseUrl = `${XWiki.contextPath}/rest/diagram/deleteDiagramAttachments`; 184 - let queryString = $.param({ 185 - "form_token": xm.form_token, 186 - "documentReference": encodeURIComponent(xm.documentReference.toString()) 187 187 }); 188 - return $.post(`${baseUrl}?${queryString}`); 189 - }; 190 - 191 - var saveFilesAsImageAttachments = function() { 192 - var uploadDeferredList = [] 193 - 194 - forEachOpenedFile(function (file) { 195 - var uploadDeferred = $.Deferred().resolve(); 196 - // Get the current page so we know where to return after saving. 197 - let originalPage = file.ui.currentPage; 198 - 199 - file.ui.pages.forEach(function (page, index) { 200 - // We do the next upload even if the previous uploads have failed. 201 - var nextUpload = $.proxy(saveFileAsImageAttachments, null, file, index,originalPage); 202 - uploadDeferred = uploadDeferred.then(nextUpload, nextUpload); 203 - uploadDeferredList.push(uploadDeferred.promise()); 204 - }); 205 - }); 206 - // Wait for all deferreds to complete. 207 - return $.when.apply($, uploadDeferredList).then( 208 - function () { 209 - // Resolve the overall promise if all succeeded. 210 - return { status: 'success' }; 211 - }, 212 - function () { 213 - // Reject the overall promise if any failed. 214 - return $.Deferred().reject({ status: 'fail' }); 215 - } 216 - ).promise(); 217 - }; 218 - 219 - var uploadInProgress = false; 220 - // Attach the diagram SVG to the diagram page in order to use it for viewing the diagram and for exporting the diagram 221 - // to PDF. For this we need to stop the default save until the upload action is completed and trigger it after. 222 - $(document).on('xwiki:actions:beforeSave', function(event, data) { 223 - if (!uploadInProgress) { 224 - uploadInProgress = true; 225 - event.stopPropagation(); 226 - var saveButton = $(event.target); 227 - saveButton.prop('disabled', true); 228 - deleteAllDiagrams() 229 - .then(saveFilesAsImageAttachments) 230 - .catch(function(e) { 231 - new XWiki.widgets.Notification( 232 - l10n['saveAsImageAttachmentError'], 'error'); 233 - }) 234 - .always(function() { 235 - saveButton.prop('disabled', false).click(); 236 - }); 237 - } else { 238 - uploadInProgress = false; 239 - } 240 240 }); 241 241 242 - // We need to update the form fields before the form is validated (for Preview, Save and Save & Continue). 243 - $(document).on('xwiki:actions:beforePreview xwiki:actions:beforeSave', updateFormFields); 244 - 245 245 var submitInProgress = false; 246 246 // Disable the leave confirmation when the form action buttons are used. 247 247 $(document).on('xwiki:actions:cancel xwiki:actions:preview xwiki:actions:save xwiki:document:saved', - Inhalt parsen
-
... ... @@ -1,1 +1,1 @@ 1 - Nein1 +Ja
- XWiki.JavaScriptExtension[2]
-
- Code
-
... ... @@ -1,384 +1,20 @@ 1 -/** 2 - * Overrides the link dialog in order to support creating links to wiki pages. 3 - */ 4 -define('diagram-link-editor', [ 5 - 'jquery', 6 - 'diagram-link-handler', 7 - 'draw.io', 8 - 'resourceSelector' 9 -], function($, diagramLinkHandler) { 10 - /** 11 - * Override in order to change the Element type check from a.constructor !== Element, which was failing due to a 12 - * collision with the PrototypeJS's own implementation of the standard Element. 13 - * See http://api.prototypejs.org/dom/Element/new/index.html. This code is taken from the minified version of 14 - * mxClient.js and should be removed after PrototypeJS is no longer loaded. 15 - */ 16 - mxUtils.isNode = function(a, b, c, d) { 17 - return null == a || a.nodeType !== Node.ELEMENT_NODE || null != b && 18 - a.nodeName.toLowerCase() != b.toLowerCase() ? !1 : null == c || a.getAttribute(c) == d; 19 - }; 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 - EditorUi.prototype.showLinkDialog = function(value, selectLabel, callback, showNewWindowOption, linkTarget) { 45 - var resourceReference = diagramLinkHandler.getResourceReferenceFromCustomLink(value); 46 - // We append the modal to the body element in order to fix Issue #108: "Inserting a link in full screen mode is not 47 - // possible". 48 - $('#diagramLinkModal').appendTo('body').selectResource(resourceReference, { 49 - selectLabel: selectLabel 50 - }).done(function(resourceReference) { 51 - callback(diagramLinkHandler.getCustomLinkFromResourceReference(resourceReference), null, linkTarget); 52 - }); 53 - }; 54 - 55 - // For some cases, to consider wrapping or overflow, w might be altered and we need to keep the initial value as 56 - // it was from bounds.width of the base mxText node. 57 - var originalText = mxSvgCanvas2D.prototype.text; 58 - mxSvgCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir) { 59 - this.state.initialWidth = w; 60 - return originalText.apply(this, arguments); 61 - }; 62 - 63 - // Don't add warning when the viewer doesn't support SVG 1.1, since we create a fallback for foreignObjects. 64 - Graph.prototype.addForeignObjectWarning = function(canvas, root) { 65 - // Do nothing. 66 - } 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 - // Overwrite Graph.getSvg in order to replace XWiki custom links with absolute URLs. 95 - // Also fix the text fallback for viewers with no support for foreignObjects. 96 - var originalGraphGetSVG = Graph.prototype.getSvg; 97 - Graph.prototype.getSvg = function(background, scale, border, nocrop, crisp, ignoreSelection, showText, imgExport, 98 - linkTarget, hasShadow, incExtFonts, keepTheme, exportType, cells) { 99 - imgExport = imgExport || this.createSvgImageExport(); 100 - var originalGetLinkForCellState = imgExport.getLinkForCellState; 101 - imgExport.getLinkForCellState = function() { 102 - var result = originalGetLinkForCellState.apply(this, arguments); 103 - if (diagramLinkHandler.isXWikiCustomLink(result)) { 104 - result = diagramLinkHandler.getURLFromCustomLink(result); 105 - // Use the absolute URL because this SVG is used for PDF export which needs to be portable. 106 - result = $('<a/>').attr('href', result).prop('href'); 107 - } 108 - return result; 109 - } 110 - var originalDrawState = imgExport.drawState; 111 - imgExport.drawState = function(state, canvas) { 112 - var originalCreateAlternateContent = canvas.createAlternateContent; 113 - canvas.createAlternateContent = function(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, 114 - rotation) { 115 - if (format === 'html') { 116 - // Keep only the text content. 117 - str = $('<div/>').html(str).text() || this.foAltText; 118 - } 119 - return originalCreateAlternateContent.call(this, fo, x, y, w, h, str, align, valign, wrap, format, overflow, 120 - clip, rotation); 121 - }; 122 - return originalDrawState.apply(this, arguments); 123 - }; 124 - try { 125 - return originalGraphGetSVG.call(this, background, scale, border, nocrop, crisp, ignoreSelection, showText, 126 - imgExport, linkTarget, hasShadow, incExtFonts, keepTheme, exportType, cells); 127 - } finally { 128 - imgExport.getLinkForCellState = originalGetLinkForCellState; 129 - imgExport.drawState = originalDrawState; 130 - } 131 - }; 132 -}); 133 - 134 -/** 135 - * Adds support for using XWiki image attachments in diagrams. 136 - */ 137 -define('diagram-image-editor', ['xwiki-utils', 'diagram-link-handler', 'draw.io'], function(xutils, diagramLinkHandler) { 138 - // Fix the base URL used when exporting the diagram as image. 139 - var originalCreateImageUrlConverter = EditorUi.prototype.createImageUrlConverter; 140 - EditorUi.prototype.createImageUrlConverter = function() { 141 - var converter = originalCreateImageUrlConverter.call(this); 142 - converter.convert = function(src) { 143 - // Use baseDomain instead of baseUrl to detect external URLs. 144 - if (src && (src.substr(0, 7) === 'http://' || src.substr(0, 8) === 'https://') && 145 - src.substr(0, converter.baseDomain.length) !== converter.baseDomain) { 146 - src = PROXY_URL + '?url=' + encodeURIComponent(src); 147 - } 148 - return src; 149 - }; 150 - return converter; 151 - }; 152 - 153 - // Override for uploading the image as attachment instead of encode it to Base64. 154 - var originalImportFiles = EditorUi.prototype.importFiles; 155 - EditorUi.prototype.importFiles = function(files, x, y, maxSize, fn, resultFn, filterFn, barrierFn, resizeDialog, 156 - maxBytes, resampleThreshold, ignoreEmbeddedXml, evt) { 157 - let importFilesArgs = arguments; 158 - if (fn) { 159 - let editorUi = this; 160 - importFilesArgs = Array.prototype.slice.call(arguments); 161 - // This is the call back function responsible to insert the image. 162 - importFilesArgs[4] = function(data, mimeType, x, y, w, h, filename) { 163 - if (data.substring(0, 5) == 'data:') { 164 - let fnArgs = Array.prototype.slice.call(arguments); 165 - let fileBase64Data = data.substring(data.indexOf(',') + 1); 166 - xutils.uploadAttachment(editorUi.base64ToBlob(fileBase64Data, mimeType), filename).done(function() { 167 - // Include the attachment reference in the URL using the fragment identifier in order to be able to use it 168 - // when saving the diagram (we want to save the attachment reference not the attachment URL). 169 - let resourceReference = { 170 - type: 'attach', 171 - reference: XWiki.Model.serialize(new XWiki.AttachmentReference(filename)) 172 - }; 173 - let customLink = diagramLinkHandler.getCustomLinkFromResourceReference(resourceReference); 174 - fnArgs[0] = xutils.getAttachmentURL(filename) + '#' + encodeURIComponent(customLink); 175 - fn.apply(this, fnArgs); 176 - }); 177 - } else { 178 - fn.apply(this, arguments); 179 - } 180 - }; 181 - } 182 - originalImportFiles.apply(this, importFilesArgs); 183 - }; 184 - 185 - // Add support for inserting images by specifying the XWiki attachment reference. 186 - var originalShowImageDialog = EditorUi.prototype.showImageDialog; 187 - EditorUi.prototype.showImageDialog = function(title, value, fn, ignoreExisting, convertDataUri, withCrop, 188 - initClipPath) { 189 - var showImageDialogArgs = Array.prototype.slice.call(arguments); 190 - var customLink = diagramLinkHandler.getCustomLinkFromURL(value); 191 - if (customLink) { 192 - // Edit the XWiki custom link instead of the actual URL. 193 - showImageDialogArgs[1] = customLink; 194 - } 195 - if (typeof fn === 'function') { 196 - showImageDialogArgs[2] = function(newValue, width, height) { 197 - var fnArgs = Array.prototype.slice.call(arguments); 198 - if (diagramLinkHandler.isXWikiCustomLink(newValue)) { 199 - // Save the actual URL, but keep the custom link as fragment identifier. 200 - fnArgs[0] = diagramLinkHandler.getURLFromCustomLink(newValue) + '#' + encodeURIComponent(newValue); 201 - } 202 - fn.apply(this, fnArgs); 203 - }; 204 - } 205 - originalShowImageDialog.apply(this, showImageDialogArgs); 206 - }; 207 - 208 - // This function is used by the image dialog to preload the images before inserting them. We have to overwrite it in 209 - // order to make it use the actual URL for XWiki image attachments. 210 - var originalLoadImage = EditorUi.prototype.loadImage; 211 - EditorUi.prototype.loadImage = function(uri, onload, onerror) { 212 - var loadImageArgs = Array.prototype.slice.call(arguments); 213 - if (diagramLinkHandler.isXWikiCustomLink(uri)) { 214 - loadImageArgs[0] = diagramLinkHandler.getURLFromCustomLink(uri); 215 - } 216 - originalLoadImage.apply(this, loadImageArgs); 217 - }; 218 -}); 219 - 220 -/** 221 - * Customizes the diagram export as URL and the diagram import from URL. 222 - */ 223 -define('diagram-url-io', ['diagram-utils', 'draw.io'], function(diagramUtils) { 224 - var urlParam = function(parameter, url) { 225 - var results = new RegExp('[\?&]' + parameter + '=([^&#]*)').exec(url); 226 - if (results === null) { 227 - return null; 228 - } 229 - return decodeURIComponent(results[1]); 230 - }; 231 - 232 - var getParameterValueFromURL = function(parameter, url) { 233 - if (typeof URLSearchParams === 'function') { 234 - return new URL(url, window.location.href).searchParams.get(parameter); 235 - } 236 - // IE will get here since it's not supporting URLSearchParams. 237 - return urlParam(parameter, url); 238 - }; 239 - 240 - // Custom diagram import from URL. 241 - var loadUrl = function(url) { 242 - var diagramXML = null; 243 - let exportedUrl = getParameterValueFromURL('url', url); 244 - if (exportedUrl) { 245 - diagramXML = diagramUtils.getDiagramXMLFromURL(exportedUrl); 246 - } 247 - return diagramXML; 248 - }; 249 - 250 - // Custom diagram export as URL (using the current host). 251 - var originalCreateLink = EditorUi.prototype.createLink; 252 - EditorUi.prototype.createLink = function(linkTarget, linkColor, allPages, lightbox, editLink, layers, url, ignoreFile, 253 - params, useOpenParameter) { 254 - let rawURL = originalCreateLink.apply(this, arguments); 255 - // Do not include '#' because it's automatically added by getURL function below. 256 - let documentFragmentIndex = rawURL.indexOf('#'); 257 - let documentFragment = rawURL.substring(documentFragmentIndex + 1); 258 - if (documentFragment.substring(0, 1) == 'R') { 259 - let queryString = ''; 260 - let queryStringIndex = rawURL.indexOf('?'); 261 - if (queryStringIndex > -1) { 262 - queryString = rawURL.substring (queryStringIndex + 1, documentFragmentIndex); 263 - } 264 - // Append source parameter to the query 265 - queryString += '&source=url'; 266 - return window.location.protocol + '//' + window.location.host + 267 - new XWiki.Document('DiagramViewSheet', 'Diagram').getURL('view', queryString, documentFragment); 268 - } 269 - return rawURL; 270 - } 271 - 272 - return { 273 - loadUrl: loadUrl 274 - }; 275 -}); 276 - 277 -/** 278 - * In case external services are disabled, stop the features that require it (online shape search, help section 279 - * external links) and show an info dialog. 280 - */ 281 -define('diagram-external-services', ['jquery', 'diagram-config', 'draw.io'], function($, diagramConfig) { 282 - var showDisabledServicesDialog = function(editorUi) { 283 - var errorMessage = $('<div></div') 284 - .html($jsontool.serialize($services.localization.render('diagram.editor.disabledExternalServices'))); 285 - 286 - errorMessage.addClass('externalServicesDialog'); 287 - var dlg = new CustomDialog(/*editorUi*/ editorUi, /*content*/ errorMessage[0], /*okFn*/ null, /*cancelFn*/ null, 288 - /*okButtonText*/ mxResources.get('ok'), /*helpLink*/ null, /*buttonsContent*/ null, 289 - /*hideCancel*/ true); 290 - editorUi.showDialog(dlg.container, 250, 75, true, true); 291 - }; 292 - 293 - var originalIsOfflineApp = EditorUi.prototype.isOfflineApp; 294 - EditorUi.prototype.isOfflineApp = function() { 295 - return diagramConfig.disableExternalServices || originalIsOfflineApp(); 296 - }; 297 -}); 298 - 299 -define('diagramMenuTranslations', { 300 - prefix: 'diagram.editor.menu.', 301 - keys: [ 302 - // File menu. 303 - 'print.label', 304 - 'print.title' 305 - ] 306 -}); 307 - 308 -/** 309 - * Integrates draw.io diagram editor in XWiki. 310 - */ 311 -define('diagram-editor', [ 312 - 'jquery', 313 - 'diagram-store', 314 - 'diagram-utils', 315 - 'diagram-url-io', 316 - 'diagram-config', 317 - 'xwiki-l10n!diagramMenuTranslations', 318 - 'diagram-graph-xml-filter', 319 - 'diagram-link-editor', 320 - 'diagram-image-editor', 321 - 'diagram-external-services' 322 -], function($, diagramStore, diagramUtils, diagramUrlIO, diagramConfig, l10n) { 323 - var diagramEditorKeyboardShortcutsPath = "$services.webjars.url('org.xwiki.contrib:draw.io', 'shortcuts.svg')"; 324 - // These variables are used to decide if an image should be uploaded at original resolution or 325 - // should be declined for being too big. 326 - // Default values: 327 - // EditorUi.prototype.maxImageSize = 520; 328 - // EditorUi.prototype.maxImageBytes = 1000000; 329 - 1 +define('diagramEditor', ['jquery', 'diagramStore'], function($, diagramStore) { 330 330 // 331 331 // Diagram Editor Constructor. 332 332 // 333 333 var createDiagramEditor = function(options) { 334 334 options = options || {}; 335 - // This is needed since we do not use drafts and it would create the file to soon, leading to the file being opened 336 - // in a new window. 337 - EditorUi.enableDrafts = false; 338 - var editor = new Editor(/* chromeless: */ uiTheme === 'min', options.themes, /* model: */ null, /* graph: */ null, 339 - /* editable: */ true); 340 - var editorUI = new App(editor, options.container); 341 - // This is usefull for debugging the diagram editor from the JavaScript console. 342 - $(editorUI.container).data('diagramEditor', editorUI).trigger('diagramEditorCreated', editorUI); 343 - // Fix the editor UI before loading the diagram because layout changes can influence the way the shapes are drawn. 344 - fixEditorUI(editorUI); 345 - fixLoadUrl(editorUI); 346 - var file = diagramStore.createFile(editorUI, options.input, options.fileName, options.documentReference); 347 - // The first letter of the file name is used to determine the storage type. Let's use 'X' for XWiki storage. 348 - editorUI.loadFile('X' + options.fileName, true, file); 7 + var editorUI = new App(new Editor(false, options.themes), options.container); 8 + var file = diagramStore.createFile(editorUI, options.input, options.fileName); 9 + editorUI.loadFile(options.fileName, true, file); 349 349 return editorUI; 350 350 }; 351 351 352 - var fixEditorUI = function(editorUI) { 353 - cleanMenu(editorUI); 354 - renameMenu(editorUI); 355 - fixKeyboardShortcutsAction(editorUI); 356 - fixEditorButtons($(editorUI.container)); 357 - removeThemeButton(); 358 - // These are not present on mobile. 359 - if (editorUI.menubar != null) { 360 - removeCompactModeToggle(editorUI); 361 - fixFullScreenToggle(editorUI); 362 - } 363 - }; 364 - 365 - var fixLoadUrl = function(editorUI) { 366 - // Custom diagram import from URL. 367 - var originalLoadUrl = editorUI.editor.loadUrl; 368 - editorUI.editor.loadUrl = function(url, success, error, forceBinary, retry, dataUriPrefix, noBinary, headers) { 369 - var diagramXML = diagramUrlIO.loadUrl(url); 370 - if (diagramXML != null) { 371 - return success(diagramXML); 372 - } 373 - return originalLoadUrl.apply(this, arguments); 374 - }; 375 - }; 376 - 377 377 // 378 - // Change theservice name inorder todisablenotifications.14 + // Disable the tabbed UI (setting urlParams['pages'] to '0' is not enough..) 379 379 // 380 - EditorUi.prototype. getServiceName = function() {381 - return'xwiki.com';16 + EditorUi.prototype.initPages = function() { 17 + // Do nothing. 382 382 }; 383 383 384 384 // Don't change the document title. ... ... @@ -388,70 +388,24 @@ 388 388 // Add support for disabling an entire sub-menu. 389 389 // 390 390 var originalAddSubmenu = Menus.prototype.addSubmenu; 391 - Menus.prototype.addSubmenu = function(name, menu, parent , label) {27 + Menus.prototype.addSubmenu = function(name, menu, parent) { 392 392 var subMenu = this.get(name); 393 - if (subMenu && subMenu.is Enabled()!== false) {394 - returnoriginalAddSubmenu.apply(this, arguments);29 + if (subMenu && subMenu.visible !== false) { 30 + originalAddSubmenu.apply(this, arguments); 395 395 } 396 396 }; 397 397 398 - 399 - /* 400 - * Map with all the menu items that we want to have a title. 401 - */ 402 - const titleMap = new Map([ 403 - ['print', l10n['print.title']] 404 - ]); 405 - 406 - /* 407 - * Update the title of the menu items. 408 - */ 409 - var originalAddMenuItem = Menus.prototype.addMenuItem; 410 - Menus.prototype.addMenuItem = function(menu, key, parent, trigger, sprite, label) { 411 - let item = originalAddMenuItem.apply(this, arguments); 412 - if (item != null && titleMap.has(key)) { 413 - item.title = titleMap.get(key); 414 - } 415 - return item; 416 - }; 417 - 418 - // Remove the language picker because the diagram editor is configured to use the XWiki language. 419 - var originalCreateMenubar = Menus.prototype.createMenubar; 420 - Menus.prototype.createMenubar = function(container) { 421 - delete this.menus['language']; 422 - return originalCreateMenubar.apply(this, arguments); 423 - } 424 - 425 425 // 426 - // Addsupportfor notdisplaying 'browser'optionfrom 'Importfrom' sub-menu35 + // Hide the editor footer. 427 427 // 428 - var originalAddItem = mxPopupMenu.prototype.addItem; 429 - mxPopupMenu.prototype.addItem = function(title, image, funct, parent, iconCls, enabled, active) { 430 - if (title === (mxResources.get('browser') + '...') && parent && parent.innerText === 'Import from') { 431 - return null; 432 - } 433 - return originalAddItem.apply(this, arguments); 37 + var hideFooter = function(editorUI) { 38 + // We call this just in case the footer is visible. 39 + editorUI.hideFooter(); 40 + // Make sure the diagram editor doesn't leave space for the footer. 41 + editorUI.footerHeight = 0; 434 434 }; 435 435 436 436 // 437 - // Rename menu options to fit our needs. 438 - // 439 - var renameMenu = function(editorUI) { 440 - const menuItems = [ 441 - // File menu 442 - ['print', l10n['print.label']] 443 - ]; 444 - 445 - // Iterate over the array of tuples 446 - menuItems.forEach(function([menuKey, newLabel]) { 447 - var action = editorUI.actions.actions[menuKey]; 448 - if (action) { 449 - action.label = newLabel; 450 - } 451 - }); 452 - }; 453 - 454 - // 455 455 // Clean the editor menu by removing the features that are not needed. 456 456 // 457 457 var cleanMenu = function(editorUI) { ... ... @@ -458,13 +458,11 @@ 458 458 // Disable and hide some of the menu entries. 459 459 [ 460 460 // File menu 461 - ' synchronize', 'new', 'open', 'save', 'saveAs', 'rename', 'makeCopy', 'close',51 + 'new', 'open', 'save', 'saveAs', 'rename', 'makeCopy', 'close', 462 462 // Extras menu 463 463 'autosave', 'showStartScreen', 'plugins', 'offline', 'chromeApp', 464 - // Help menu 465 - 'downloadDesktop', 'useOffline', 466 - // ExportAs 467 - 'exportHtml', 'exportPdf' 54 + // Help menu (Graph Editor) 55 + 'help' 468 468 ].forEach(function(actionName) { 469 469 var action = editorUI.actions.actions[actionName]; 470 470 if (action) { ... ... @@ -486,26 +486,51 @@ 486 486 }); 487 487 }; 488 488 489 - // 490 - // Fix the side bar tool tip: the tool tip position is computed as if the editor takes the full screen. 491 - // 492 - var originalGetTooltipOffset = Sidebar.prototype.getTooltipOffset; 493 - Sidebar.prototype.getTooltipOffset = function(elt, bounds) { 494 - var fullScreenCoordinates = originalGetTooltipOffset.apply(this, arguments); 495 - // Adjust the tool tip coordinates with the editor offset. 496 - var offset = $(this.editorUi.container).offsetParent().offset(); 497 - return new mxPoint(fullScreenCoordinates.x + offset.left, fullScreenCoordinates.y + offset.top); 77 + // Fix the base URL used when exporting the diagram as image. 78 + var oldCreateImageUrlConverter = EditorUi.prototype.createImageUrlConverter; 79 + EditorUi.prototype.createImageUrlConverter = function() { 80 + var converter = oldCreateImageUrlConverter.call(this); 81 + converter.convert = function(src) { 82 + // Use baseDomain instead of baseUrl to detect external URLs. 83 + if (src && (src.substr(0, 7) === 'http://' || src.substr(0, 8) === 'https://') && 84 + src.substr(0, converter.baseDomain.length) !== converter.baseDomain) { 85 + src = PROXY_URL + '?url=' + encodeURIComponent(src); 86 + } 87 + return src; 88 + }; 89 + return converter; 498 498 }; 499 499 500 500 // 501 - // ConsiderthebasePathfortheshapesadded intheleftpanel.93 + // Fix the side bar tool tip: the tool tip position is computed as if the editor takes the full screen. 502 502 // 503 - var oldCreateVertexTemplateEntry = Sidebar.prototype.createVertexTemplateEntry; 504 - Sidebar.prototype.createVertexTemplateEntry = function(style, width, height, value, title, showLabel, showTitle, 505 - allowCellsInserted, showTooltip, clickFn, thumbWidth, thumbHeight) { 506 - style = style.replace(/(image=)(img\/lib)/g, '$1' + diagramConfig.drawIOBasePath + '$2'); 507 - return oldCreateVertexTemplateEntry.call(this, style, width, height, value, title, showLabel, showTitle, 508 - allowCellsInserted, showTooltip, clickFn, thumbWidth, thumbHeight); 95 + var oldShowTooltip = Sidebar.prototype.showTooltip; 96 + Sidebar.prototype.showTooltip = function(elt) { 97 + if (this.enableTooltips && this.showTooltips && this.currentElt != elt) { 98 + // The next usage of mxUtils.bind() is to bind the (private) show function to the side bar object. 99 + // We need to overwrite the show function. 100 + var oldBind = mxUtils.bind; 101 + mxUtils.bind = function(object, method) { 102 + // Restore the original function. 103 + mxUtils.bind = oldBind; 104 + return oldBind(object, function() { 105 + var result = method.apply(this, arguments); 106 + // Adjust the tool tip coordinates because they are computed as if the editor takes the full screen. 107 + // Thus we need to add the editor offset. 108 + var offset = $(this.container).parent().offsetParent().offset(); 109 + $(this.tooltip).css({ 110 + left: (offset.left + parseInt(this.tooltip.style.left)) + 'px', 111 + top: (offset.top + parseInt(this.tooltip.style.top)) + 'px' 112 + }); 113 + $(this.tooltipImage).css({ 114 + left: (offset.left + parseInt(this.tooltipImage.style.left)) + 'px', 115 + top: (offset.top + parseInt(this.tooltipImage.style.top)) + 'px' 116 + }); 117 + return result; 118 + }); 119 + }; 120 + } 121 + oldShowTooltip.apply(this, arguments); 509 509 }; 510 510 511 511 // ... ... @@ -514,12 +514,12 @@ 514 514 var fixKeyboardShortcutsAction = function(editorUI) { 515 515 var keyboardShortcutsAction = editorUI.actions.get('keyboardShortcuts'); 516 516 if (keyboardShortcutsAction) { 517 - var o riginalFunct = keyboardShortcutsAction.funct;130 + var oldFunct = keyboardShortcutsAction.funct; 518 518 keyboardShortcutsAction.funct = function() { 519 519 if (mxClient.IS_SVG) { 520 - window.open(diagramEditor KeyboardShortcutsPath);133 + window.open(diagramEditorBasePath + 'shortcuts.svg'); 521 521 } else { 522 - o riginalFunct.apply(this, arguments);135 + oldFunct.apply(this, arguments); 523 523 } 524 524 }; 525 525 } ... ... @@ -530,7 +530,7 @@ 530 530 // 531 531 var removeCompactModeToggle = function(editorUI) { 532 532 if (typeof editorUI.toggleCompactMode === 'function') { 533 - editorUI.toggleCompactMode( /* visible: */ false);146 + editorUI.toggleCompactMode(true); 534 534 var buttons = $(editorUI.container).find('.geToolbarContainer > a.geButton'); 535 535 buttons.last().remove(); 536 536 buttons.css('right', function(index, value) { ... ... @@ -540,11 +540,6 @@ 540 540 }; 541 541 542 542 var fullScreen = new XWiki.widgets.FullScreen(); 543 - // We only call the init in versions that have the function defined so we don't get an error in the console. 544 - // The 'if' should be removed after upgrading the app to a parent >= 17.10.2. 545 - if (typeof fullScreen.initDom === 'function') { 546 - fullScreen.initDom(); 547 - } 548 548 var fixFullScreenToggle = function(editorUI) { 549 549 mxEvent.removeAllListeners(editorUI.fullscreenElement); 550 550 editorUI.container._x_fullScreenActivator = editorUI.fullscreenElement; ... ... @@ -554,7 +554,7 @@ 554 554 if (isFullScreen) { 555 555 // Exit full screen mode. 556 556 fullScreen.closeFullScreen(); 557 - editorUI. refresh();165 + editorUI.toggleCompactMode(true); 558 558 } else { 559 559 // Enter full screen mode. 560 560 fullScreen.makeFullScreen(editorUI.container); ... ... @@ -561,78 +561,54 @@ 561 561 // The previous line hides the 'fullScreenActivator' and shows the 'Exit Full Screen' button. We want to use the 562 562 // 'fullScreenActivator' for exiting the full screen mode. The 'Exit Full Screen' button is hidden from CSS. 563 563 $(editorUI.fullscreenElement).show(); 564 - editorUI. refresh();172 + editorUI.toggleCompactMode(); 565 565 } 566 566 }); 567 567 }; 568 568 569 569 // 570 - // Add the type of the buttons manually to stop the default submit. The preventDefault used in editDiagram is not 571 - // working for these since in draw.io code is called stopPropagation. 572 - // 573 - var fixEditorButtons = function(editor) { 574 - editor.find('button:not([type])').each(function() { 575 - $(this).attr('type', 'button'); 576 - }); 577 - }; 578 - 579 - var removeThemeButton = function() { 580 - $('.geAdaptiveAsset[title="Theme"]').remove(); 581 - }; 582 - 583 - // mxRuler adds the ruler to the document body instead of adding it to the editor container. 584 - var originalMxDualRuler = mxDualRuler; 585 - mxDualRuler = function(editorUI, unit) { 586 - originalMxDualRuler.apply(this, arguments); 587 - $([this.hRuler.container, this.vRuler.container]).appendTo(editorUI.container); 588 - }; 589 - mxDualRuler.prototype = Object.create(originalMxDualRuler.prototype); 590 - mxDualRuler.prototype.constructor = mxDualRuler; 591 - 592 - var themes = {}; 593 - var getDiagramEditorConfig = function(container) { 594 - var input = $(container).children('input.diagram-content'); 595 - var documentReference = input.data('reference') || ''; 596 - if (typeof documentReference === 'string') { 597 - documentReference = XWiki.Model.resolve(documentReference, XWiki.EntityType.DOCUMENT, 598 - XWiki.currentDocument.documentReference); 599 - } 600 - var fileName = input.data('title') || $('#document-title').text(); 601 - if (!fileName) { 602 - fileName = documentReference.name == 'WebHome' ? documentReference.parent.name : documentReference.name; 603 - } 604 - return { 605 - container: container, 606 - themes: themes, 607 - fileName: fileName, 608 - input: input, 609 - documentReference: documentReference 610 - }; 611 - }; 612 - 613 - // 614 614 // jQuery plugin 615 615 // 180 + var themes = {}; 616 616 $.fn.editDiagram = function(options) { 617 617 return this.on('click', 'button', function(event) { 618 618 // Make sure the buttons from the editor UI don't submit the edit form. 619 619 event.preventDefault(); 620 - }).on('keydown keyup keypress', '.geContentEditable', function(event) { 621 - // Make sure the keyboard events triggered from the nested editable sections are not propagated as they may 622 - // trigger shortcut keys (the nested editable sections need to behave like input fields). 623 - // See issue #15: If you install XWebIDE Application you can't use "W" letter in the diagram text. 624 - event.stopPropagation(); 625 625 }).each(function() { 626 - // We need this CSS class on the body element in order to have proper styling for the UI elements (menus, dialogs, 627 - // tooltips) that are added directly under the body element. 628 - $(document.body).addClass('geEditor'); 629 - createDiagramEditor($.extend(getDiagramEditorConfig(this), options)); 186 + var editorUI = createDiagramEditor($.extend({ 187 + container: this, 188 + themes: themes, 189 + fileName: $('#document-title').text() || XWiki.currentPage, 190 + input: $(this).children('input.diagram-content') 191 + }, options)); 630 630 $(this).removeClass('loading'); 193 + hideFooter(editorUI); 194 + cleanMenu(editorUI); 195 + fixKeyboardShortcutsAction(editorUI); 196 + removeCompactModeToggle(editorUI); 197 + fixFullScreenToggle(editorUI); 631 631 }); 632 632 }; 633 633 634 - return diagramUtils.loadTranslationAndTheme().done(function(theme) { 635 - // Configure the default editor theme. 636 - themes[Graph.prototype.defaultThemeName] = theme; 201 + // 202 + // Load the translation files. 203 + // 204 + var diagramEditorDeferred = $.Deferred(); 205 + mxResources.loadDefaultBundle = false; 206 + var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) || 207 + mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage); 208 + mxUtils.getAll([bundle, STYLE_PATH + '/default.xml'], function(response) { 209 + // Adds bundle text to resources. 210 + mxResources.parse(response[0].getText()); 211 + 212 + // Configures the default editor theme. 213 + themes[Graph.prototype.defaultThemeName] = response[1].getDocumentElement(); 214 + 215 + diagramEditorDeferred.resolve(); 216 + }, function() { 217 + // Failed to load resources. 218 + diagramEditorDeferred.reject(); 637 637 }); 220 + 221 + return diagramEditorDeferred.promise(); 638 638 });
- XWiki.JavaScriptExtension[3]
-
- Code
-
... ... @@ -1,37 +1,5 @@ 1 -/*! 2 -## Make sure that the version loaded with RequireJS is not a cached one. 3 -#set ($version = $services.extension.installed.getInstalledExtension('com.xwiki.diagram:application-diagram', 4 - "wiki:$xcontext.database").version.value) 5 -#set ($params = $escapetool.url({ 6 - 'minify': $!services.debug.minify, 7 - 'appVersion': $version 8 -})) 9 -#[[*/ 10 -// Start JavaScript-only code. 11 -(function(params) { 12 - "use strict"; 13 - 14 -require.config({ 15 - paths: { 16 - 'diagram-setup': new XWiki.Document('DiagramSheet', 'Diagram').getURL('jsx', params) 17 - }, 18 - map: { 19 - 'diagram-utils': { 20 - 'mxgraph-common': 'mxgraph-editor' 21 - }, 22 - 'diagram-link-handler': { 23 - 'draw.io.common': 'draw.io' 24 - } 25 - } 26 -}); 27 - 28 -require(['diagram-setup'], function() { 29 - require(['jquery', 'diagram-editor'], function($, diagramEditorPromise) { 30 - diagramEditorPromise.done(function() { 31 - $('.diagram-editor').editDiagram(); 32 - }); 1 +require(['jquery', 'diagramEditor'], function($, diagramEditorPromise) { 2 + diagramEditorPromise.done(function() { 3 + $('.diagram-editor').editDiagram(); 33 33 }); 34 34 }); 35 - 36 -// End JavaScript-only code. 37 -}).apply(']]#', $jsontool.serialize([$params]));
- XWiki.JavaScriptExtension[0]
-
- Pufferstrategie
-
... ... @@ -1,0 +1,1 @@ 1 +long - Code
-
... ... @@ -1,0 +1,84 @@ 1 +// mxGraph Client Configuration 2 +var mxBasePath = "$services.webjars.url('org.xwiki.contrib:mxgraph-client', '')"; 3 +var mxLanguage = '$xcontext.locale'; 4 + 5 +var mxGraphEditorBasePath = "$services.webjars.url('org.xwiki.contrib:mxgraph-editor', '')"; 6 + 7 +// Diagram Editor Configuration 8 +var diagramEditorBasePath = "$services.webjars.url('org.xwiki.contrib:draw.io', '')"; 9 +var RESOURCES_PATH = diagramEditorBasePath + 'resources'; 10 +// Comment out the following line when using the basic mxGraph Editor. 11 +var RESOURCE_BASE = RESOURCES_PATH + '/dia'; 12 +var STENCIL_PATH = diagramEditorBasePath + 'stencils'; 13 +var IMAGE_PATH = diagramEditorBasePath + 'images'; 14 +var STYLE_PATH = CSS_PATH = diagramEditorBasePath + 'styles'; 15 + 16 +var SHAPES_PATH = diagramEditorBasePath + 'shapes'; 17 +var GRAPH_IMAGE_PATH = diagramEditorBasePath + 'img'; 18 +var TEMPLATE_PATH = diagramEditorBasePath + 'templates'; 19 + 20 +var isLocalStorage = true; 21 + 22 +var urlParams = (function(params) { 23 + var pairs = window.location.search.substr(1).split('&'); 24 + pairs.forEach(function(pair) { 25 + var parts = pair.split('=', 2); 26 + if (parts.length === 2) { 27 + params[parts[0]] = decodeURIComponent(parts[1].replace(/\+/g, " ")); 28 + } 29 + }); 30 + return params; 31 +})({ 32 + // Don't show the splash screen. 33 + 'splash': '0', 34 + // Disable the tabbed UI. 35 + 'pages': '0', 36 + // Disable the GitHub integration. 37 + 'gh': '0', 38 + // Disable the Dropbox integration. 39 + 'db': '0', 40 + // Disable the Google Drive integration. 41 + 'gapi': '0', 42 + // Disable Google Analytics. 43 + 'analytics': '0', 44 + // Disable the One Drive integration. 45 + 'od': '0' 46 +}); 47 + 48 +// Disabling the integration with these external services is not enough because the draw.io code has hard-coded references. 49 +var DriveFile = DropboxFile = GitHubFile = OneDriveFile = false; 50 + 51 +require.config({ 52 + paths: { 53 + 'mxgraph-init': diagramEditorBasePath + 'js/draw.io.init.min', 54 + 'mxgraph-client': mxBasePath + 'mxClient.min', 55 + 'jscolor': mxGraphEditorBasePath + 'jscolor/jscolor.min', 56 + 'sanitizer': mxGraphEditorBasePath + 'sanitizer/sanitizer.min', 57 + 'mxgraph-editor': mxGraphEditorBasePath + 'mxGraphEditor.min', 58 + 'base64': diagramEditorBasePath + 'js/deflate/base64.min', 59 + 'pako': diagramEditorBasePath + 'js/deflate/pako.min', 60 + 'spin': diagramEditorBasePath + 'js/spin/spin.min', 61 + 'draw.io': diagramEditorBasePath + 'js/draw.io.min', 62 + }, 63 + shim: { 64 + 'mxgraph-client': { 65 + deps: ['mxgraph-init'] 66 + }, 67 + 'mxgraph-editor': { 68 + deps: ['mxgraph-client', 'jscolor', 'sanitizer'] 69 + }, 70 + 'draw.io': { 71 + deps: ['mxgraph-editor', 'base64', 'pako-global', 'spin-global'] 72 + } 73 + } 74 +}) 75 + 76 +define('pako-global', ['pako'], function(pako) { 77 + // draw.io expects a global variable. 78 + window.pako = pako; 79 +}); 80 + 81 +define('spin-global', ['spin'], function(spin) { 82 + // draw.io expects a global variable. 83 + window.Spinner = spin; 84 +}); - Name
-
... ... @@ -1,0 +1,1 @@ 1 +Configuration - Inhalt parsen
-
... ... @@ -1,0 +1,1 @@ 1 +Ja - Benutze diese Erweiterung
-
... ... @@ -1,0 +1,1 @@ 1 +onDemand
- XWiki.StyleSheetExtension[0]
-
- Pufferstrategie
-
... ... @@ -1,0 +1,1 @@ 1 +long - Code
-
... ... @@ -1,0 +1,87 @@ 1 +/* The diagram editor styles should be loaded after the skin and before our overwrites. */ 2 +@import url("$services.webjars.url('org.xwiki.contrib:mxgraph-editor', 'styles/grapheditor.css')"); 3 + 4 +.diagram-editor { 5 + height: 600px; 6 + min-height: 20px; 7 + position: relative; 8 +} 9 + 10 +.diagram-editor input[type="checkbox"], .diagram-editor input[type="radio"], 11 +.mxPopupMenu input[type="checkbox"], .mxPopupMenu input[type="radio"], 12 +.mxWindow input[type="checkbox"], .mxWindow input[type="radio"], 13 +.geDialog input[type="checkbox"], .geDialog input[type="radio"] { 14 + vertical-align: text-bottom; 15 +} 16 + 17 +.fullScreenWrapper .buttons > .buttonwrapper:first-child { 18 + /* Hide the "Exit Full Screen" button. We have a tool bar entry for this. */ 19 + display: none !important; 20 +} 21 + 22 +/** 23 + * Overwrite XWiki skin styles 24 + */ 25 +.diagram-editor *, 26 +.mxPopupMenu *, 27 +.mxWindow *, 28 +.geDialog, 29 +.geDialog * { 30 + box-sizing: content-box; 31 +} 32 + 33 +.mxPopupMenu, 34 +.mxWindow, 35 +.geDialog { 36 + /* We need the same font size as on draw.io because the dialog height is hard-coded. */ 37 + font-size: 10pt; 38 +} 39 + 40 +.diagram-editor button, .diagram-editor select, 41 +.mxPopupMenu button, .mxPopupMenu select, 42 +.mxWindow button, .mxWindow select, 43 +.geDialog button, .geDialog select { 44 + box-sizing: border-box; 45 +} 46 + 47 +.diagram-editor input[type="text"], 48 +.mxPopupMenu input[type="text"], 49 +.mxWindow input[type="text"], 50 +.geDialog input[type="text"] { 51 + font-size: inherit; 52 + height: auto; 53 + padding: 1px; 54 +} 55 + 56 +.diagram-editor img, 57 +.mxPopupMenu img, 58 +.mxWindow img, 59 +.geDialog img { 60 + vertical-align: baseline; 61 +} 62 + 63 +.diagram-editor hr, 64 +.mxPopupMenu hr, 65 +.mxWindow hr, 66 +.geDialog hr { 67 + margin: 0; 68 +} 69 + 70 +.mxPopupMenu table, 71 +.mxWindow table, 72 +.geDialog table { 73 + margin-bottom: 0; 74 + width: auto; 75 +} 76 + 77 +.diagram-editor table > tbody > tr > td, 78 +.mxPopupMenu table > tbody > tr > td, 79 +.mxWindow table > tbody > tr > td, 80 +.geDialog table > tbody > tr > td { 81 + border-top: 0 none; 82 +} 83 + 84 +.geDialog table > tbody > tr > td { 85 + padding: 0; 86 + vertical-align: baseline; 87 +} - Content Type
-
... ... @@ -1,0 +1,1 @@ 1 +CSS - Inhalt parsen
-
... ... @@ -1,0 +1,1 @@ 1 +Ja - Benutze diese Erweiterung
-
... ... @@ -1,0 +1,1 @@ 1 +onDemand