| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247 |
- var mxIsElectron = navigator.userAgent != null &&
- navigator.userAgent.toLowerCase().indexOf(' electron/') > -1 &&
- navigator.userAgent.indexOf(' draw.io/') > -1;
- var GOOGLE_APPS_MAX_AREA = 25000000;
- var GOOGLE_SHEET_MAX_AREA = 1000000; // The maximum number of pixels is 1 million.
- /**
- * Adds meta tag to the page.
- */
- function mxmeta(content, httpEquiv)
- {
- try
- {
- var s = document.createElement('meta');
-
- s.setAttribute('content', content);
- s.setAttribute('http-equiv', httpEquiv);
- var t = document.getElementsByTagName('meta')[0];
- t.parentNode.insertBefore(s, t);
- }
- catch (e)
- {
- // ignore
- }
- };
- function mxscript(src, onLoad)
- {
- var s = document.createElement('script');
- s.setAttribute('type', 'text/javascript');
- s.setAttribute('src', src);
-
- if (onLoad != null)
- {
- var r = false;
-
- s.onload = s.onreadystatechange = function()
- {
- if (!r && (!this.readyState || this.readyState == 'complete'))
- {
- r = true;
- onLoad();
- }
- };
- }
- var t = document.getElementsByTagName('script')[0];
-
- if (t != null)
- {
- t.parentNode.insertBefore(s, t);
- }
- };
- if (mxIsElectron)
- {
- mxmeta('default-src \'self\'; script-src \'self\'; connect-src \'self\' https://*.draw.io https://*.diagrams.net https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; frame-src \'none\'; style-src \'self\' \'unsafe-inline\' https://fonts.googleapis.com; base-uri \'none\';child-src \'self\';object-src \'none\';', 'Content-Security-Policy');
-
- // We can't use eval in Electron because of CSP, so load all shapes and disable eval
- mxscript('js/stencils.min.js', function()
- {
- mxscript('js/shapes-14-6-5.min.js', function()
- {
- if (window.pendingRequest != null)
- {
- render(window.pendingRequest);
- }
- window.shapesLoaded = true;
- });
- });
-
- // Disables eval for JS (uses shapes-14-6-5.min.js)
- mxStencilRegistry.allowEval = false;
- }
- // TODO Add support for loading math from a local folder
- Editor.initMath((remoteMath? 'https://app.diagrams.net/' : '') + 'math/es5/startup.js');
- // Marks individual font and CSS URLs as preloaded
- var fontPreload = {};
- var cssPreload = {};
- function render(data)
- {
- if (data.csv != null)
- {
- // CSV loads orgChart asynchronously and needs mxscript
- window.mxscript = function (src, onLoad, id)
- {
- var s = document.createElement('script');
- s.setAttribute('type', 'text/javascript');
- s.setAttribute('defer', 'true');
- s.setAttribute('src', src);
- if (id != null)
- {
- s.setAttribute('id', id);
- }
-
- if (onLoad != null)
- {
- var r = false;
-
- s.onload = s.onreadystatechange = function()
- {
- if (!r && (!this.readyState || this.readyState == 'complete'))
- {
- r = true;
- onLoad();
- }
- };
- }
-
- var t = document.getElementsByTagName('script')[0];
-
- if (t != null)
- {
- t.parentNode.insertBefore(s, t);
- }
- };
- var editorUi = new HeadlessEditorUi();
-
- editorUi.importCsv(data.csv, function()
- {
- data.xml = mxUtils.getXml(editorUi.editor.getGraphXml());
- delete data.csv;
- render(data);
- });
- return;
- }
- var autoScale = false;
-
- if (data.scale == 'auto')
- {
- autoScale = true;
- data.scale = 1;
- }
-
- document.body.innerText = '';
- var container = document.createElement('div');
- container.id = 'graph';
- container.style.width = '100%';
- container.style.height = '100%';
- document.body.appendChild(container);
-
- var graph = new Graph(container);
- graph.enableFlowAnimation = true;
-
- data.border = parseInt(data.border) || 0;
- data.w = parseFloat(data.w) || 0;
- data.h = parseFloat(data.h) || 0;
- data.scale = parseFloat(data.scale) || 1;
-
- var extras = null;
-
- try
- {
- extras = JSON.parse(data.extras);
- }
- catch (e)
- {
- try
- {
- extras = JSON.parse(decodeURIComponent(data.extras));
- }
- catch (e)
- {
- // ignore
- }
- }
- var gridColor = null;
- if (extras != null && extras.grid != null)
- {
- graph.gridSize = extras.grid.size;
- graph.view.gridSteps = extras.grid.steps;
- gridColor = extras.grid.color;
- }
-
- if (extras != null && extras.diagramLanguage != null)
- {
- Graph.diagramLanguage = extras.diagramLanguage;
- Graph.translateDiagram = true;
- }
- if (extras != null && extras.globalVars != null && extras.globalVars.filename != null)
- {
- document.title = extras.globalVars.filename + '.pdf';
- }
-
- // Overrides graph bounds to include background images
- var graphGetGraphBounds = graph.getGraphBounds;
- graph.getGraphBounds = function()
- {
- var bounds = graphGetGraphBounds.apply(this, arguments);
- var img = this.backgroundImage;
-
- if (img != null && img.width != null && img.height != null)
- {
- var t = this.view.translate;
- var s = this.view.scale;
- bounds = mxRectangle.fromRectangle(bounds);
- bounds.add(new mxRectangle(
- (t.x + img.x) * s, (t.y + img.y) * s,
- img.width * s, img.height * s));
- }
- return bounds;
- };
-
- //PNG+XML format
- if (data.xml.substring(0, 5) == 'iVBOR' || (extras != null && extras.isPng))
- {
- data.xml = Editor.extractGraphModelFromPng('data:image/png;base64,' + data.xml);
- }
-
- //IE11 sends incorrect xml
- if (data.xml.substring(0, 11) == '<#document>')
- {
- data.xml = data.xml.substring(11, data.xml.length - 12);
- }
-
- // Parses XML
- var doc = mxUtils.parseXml(data.xml);
- var node = Editor.extractGraphModel(doc.documentElement, true);
- if (node == null)
- {
- //Electron pdf export
- try
- {
- electron.sendMessage('render-finished', null);
- }
- catch(e)
- {
- console.log(e);
- }
-
- return graph;
- }
-
- var xmlDoc = node.ownerDocument;
- var origXmlDoc = xmlDoc;
- var diagrams = null;
- var from = 0;
- function getFileXml(uncompressed)
- {
- var xml = mxUtils.getXml(origXmlDoc);
- var editorUi = new HeadlessEditorUi();
- var tmpFile = new LocalFile(editorUi, xml);
- editorUi.setCurrentFile(tmpFile);
- editorUi.setFileData(xml);
- return editorUi.createFileData(editorUi.getXmlFileData(null, null, uncompressed));
- };
- if (mxIsElectron && data.format == 'xml')
- {
- try
- {
- electron.sendMessage('xml-data', getFileXml(data.uncompressed));
- }
- catch(e)
- {
- electron.sendMessage('xml-data-error');
- }
-
- return;
- }
- // Handles mxfile
- if (xmlDoc.documentElement.nodeName == 'mxfile')
- {
- diagrams = xmlDoc.documentElement.getElementsByTagName('diagram');
- }
-
- //Add global variables to graph
- if (extras != null && extras.globalVars != null)
- {
- graph.globalVars = extras.globalVars;
- }
- /**
- * Disables custom links but allows page links.
- */
- function isLinkIgnored(graph, link)
- {
- return link == null || (graph.isCustomLink(link) && !Graph.isPageLink(link));
- };
- /**
- * Disables custom links on shapes.
- */
- var graphGetLinkForCell = graph.getLinkForCell;
-
- graph.getLinkForCell = function(cell)
- {
- var link = graphGetLinkForCell.apply(this, arguments);
- if (isLinkIgnored(this, link))
- {
- link = null;
- }
-
- return link;
- };
-
- /**
- * Disables custom links in labels.
- */
- var cellRendererRedrawLabelShape = graph.cellRenderer.redrawLabelShape;
-
- graph.cellRenderer.redrawLabelShape = function(shape)
- {
- cellRendererRedrawLabelShape.apply(this, arguments);
-
- if (shape.node != null)
- {
- var links = shape.node.getElementsByTagName('a');
- for (var i = 0; i < links.length; i++)
- {
- var href = links[i].getAttribute('href');
-
- if (isLinkIgnored(graph, href))
- {
- links[i].setAttribute('href', '#');
- }
- }
- }
- };
-
- var preview = null;
- var waitCounter = 1;
- var bounds;
- var pageId;
- var expScale;
- // Waits for all images to finish loading
- var cache = new Object();
- var math = false;
-
- // Decrements waitCounter and invokes callback when finished
- function decrementWaitCounter()
- {
- if (--waitCounter < 1)
- {
- //Note: This code targets Chrome as it is the browser used by export server
- //Ensure that all fonts have been loaded, this promise is never rejected
- document.fonts.ready.then(function()
- {
- // Rewrite page links
- Graph.rewritePageLinks(document);
-
- var doneDiv = document.createElement("div");
- var pageCount = diagrams != null? diagrams.length : 1;
- doneDiv.id = 'LoadingComplete';
- doneDiv.style.display = 'none';
- doneDiv.setAttribute('bounds', JSON.stringify(bounds));
- doneDiv.setAttribute('page-id', pageId);
- doneDiv.setAttribute('scale', expScale);
- doneDiv.setAttribute('pageCount', pageCount);
- document.body.appendChild(doneDiv);
- //Electron pdf export
- if (mxIsElectron)
- {
- try
- {
- electron.registerMsgListener('get-svg-data', (arg) =>
- {
- graph.mathEnabled = math; //Enable math such that getSvg works as expected
- // Returns the exported SVG for the given graph (see EditorUi.exportSvg)
- var bg = graph.background;
-
- if (bg == mxConstants.NONE)
- {
- bg = null;
- }
-
- if (data.theme == 'dark')
- {
- // TODO Support enableCssDarkMode?
- graph.shapeForegroundColor = Editor.lightColor;
- graph.shapeBackgroundColor = Editor.darkColor;
- graph.stylesheet = graph.getDefaultStylesheet();
- graph.refresh();
- }
- var linkTarget = null;
- if (data.linkTarget == 'same-win')
- {
- linkTarget = '_top';
- }
- else if (data.linkTarget == 'new-win')
- {
- linkTarget = '_blank';
- }
- var svgRoot = graph.getSvg(bg, expScale, 0, false, null, true, null, null, linkTarget);
-
- if (graph.shadowVisible)
- {
- graph.addSvgShadow(svgRoot);
- }
-
- // TODO addFontCss cannot be used as it requires this
- // Adds CSS
- //Editor.prototype.addFontCss(svgRoot);
-
- if (math)
- {
- Editor.prototype.addMathCss(svgRoot);
- }
-
- function doSend()
- {
- var editable = data.embedXml == '1';
- if (editable)
- {
- svgRoot.setAttribute('content', getFileXml());
- }
- electron.sendMessage('svg-data', Graph.xmlDeclaration + '\n' + ((editable) ? Graph.svgFileComment + '\n' : '') +
- Graph.svgDoctype + '\n' + mxUtils.getXml(svgRoot));
- };
- if (data.embedImages == '1')
- {
- var tmpEditor = new Editor();
- tmpEditor.convertImages(svgRoot, doSend);
- }
- else
- {
- doSend();
- }
- });
-
- //For some reason, Electron 9 doesn't send this object as is without stringifying. Usually when variable is external to function own scope
- electron.sendMessage('render-finished', {bounds: JSON.stringify(bounds), pageCount: pageCount});
- }
- catch(e)
- {
- console.log(e);
- }
- }
- });
- }
- };
-
- function waitForImages(tagName, attributeName)
- {
- var imgs = document.body.getElementsByTagName(tagName);
- waitCounter += imgs.length;
- for (var i = 0; i < imgs.length; i++)
- {
- // No load events for image elements in Phantom using indirection instead
- var src = imgs[i].getAttribute(attributeName);
-
- if (src != null && src.length > 0 && cache[src] == null)
- {
- cache[src] = new Image();
- cache[src].onload = decrementWaitCounter;
- cache[src].onerror = decrementWaitCounter;
- cache[src].src = src;
- }
- else
- {
- decrementWaitCounter();
- }
- }
- };
-
- // Waits for MathJax autoloading and rendering
- var editorOnMathJaxDone = Editor.onMathJaxDone;
-
- Editor.onMathJaxDone = function()
- {
- editorOnMathJaxDone.apply(this, arguments);
- decrementWaitCounter();
- };
- // Adds MathJax rendering task
- function renderMath(elt)
- {
- if (Editor.MathJaxRender != null)
- {
- waitCounter++;
- Editor.MathJaxRender(elt);
- }
- };
- // Waits for the given font
- function waitForFont(url)
- {
- try
- {
- if (url != null && fontPreload[url] == null)
- {
- waitCounter++;
- fontPreload[url] = true;
- mxUtils.get(url, decrementWaitCounter,
- decrementWaitCounter, false, 10000,
- decrementWaitCounter);
- }
- }
- catch (e)
- {
- // ignore font
- }
- };
- // Waits for the fonts in the given CSS
- function waitForFonts(fontCss)
- {
- var parts = fontCss.split('url(');
-
- for (var i = 1; i < parts.length; i++)
- {
- try
- {
- var idx = parts[i].indexOf(')');
- var url = Editor.trimCssUrl(parts[i].substring(0, idx));
- waitForFont(url);
- }
- catch (e)
- {
- // ignore font css
- }
- }
- };
- // Loads and processes the fonts in the given Google Font URL
- function processGoogleFontCss(url)
- {
- try
- {
- if (Graph.isGoogleFontUrl(url) && cssPreload[url] == null)
- {
- cssPreload[url] = true;
- var link = document.createElement('link');
- link.setAttribute('rel', 'preload');
- link.setAttribute('as', 'style');
- link.setAttribute('href', url);
- document.getElementsByTagName('head')[0].appendChild(link);
- // Loads the stylesheet to wait for fonts
- waitCounter++;
- mxUtils.get(url, mxUtils.bind(this, function(req)
- {
- try
- {
- if (req.getStatus() >= 200 && req.getStatus() <= 299)
- {
- waitForFonts(req.getText());
- }
- decrementWaitCounter();
- }
- catch(e)
- {
- decrementWaitCounter();
- }
- }), decrementWaitCounter, false, 10000, decrementWaitCounter);
- }
- }
- catch (e)
- {
- // ignore stylesheet
- }
- };
- // Waits for Google Font CSS imports in the given element
- function waitForGoogleFontImports(elt)
- {
- var style = elt.getElementsByTagName('style');
- for (var i = 0; i < style.length; i++)
- {
- var parts = style[i].innerHTML.split('@import url(');
- for (var i = 1; i < parts.length; i++)
- {
- try
- {
- var idx = parts[i].indexOf(')');
- var url = Editor.trimCssUrl(parts[i].substring(0, idx));
- processGoogleFontCss(url);
- }
- catch (e)
- {
- // ignore import
- }
- }
- }
- };
- // Intercepts loading of Google Fonts CSS
- var origCreateFontElement = Graph.createFontElement;
- Graph.createFontElement = function(name, url)
- {
- var elt = origCreateFontElement.apply(this, arguments);
- try
- {
- if (elt != null && elt.nodeName.toLowerCase() == 'link' &&
- elt.getAttribute('type') == 'text/css' &&
- elt.getAttribute('rel') == 'stylesheet')
- {
- processGoogleFontCss(elt.getAttribute('href'));
- }
- }
- catch (e)
- {
- // ignore stylesheet
- }
- return elt;
- };
- // Adds wait counter for loading fonts
- var origAddFont = Graph.addFont;
-
- Graph.addFont = function(name, url)
- {
- waitCounter++;
- return origAddFont.call(this, name, url, decrementWaitCounter);
- };
-
- /**
- * Renders the given page or all pages.
- */
- function renderPage(currentPageId)
- {
- // Configures math typesetting
- graph.mathEnabled = xmlDoc.documentElement.getAttribute('math') == '1';
- // Sets grid size
- var gs = xmlDoc.documentElement.getAttribute('gridSize');
- if (gs != null)
- {
- graph.gridSize = parseInt(gs);
- }
- else
- {
- graph.gridSize = mxGraph.prototype.gridSize;
- }
- // Configure graph
- graph.foldingEnabled = false;
- graph.setEnabled(false);
-
- // Sets background image
- var bgImg = xmlDoc.documentElement.getAttribute('backgroundImage');
- if (bgImg != null)
- {
- bgImg = JSON.parse(bgImg);
- graph.setBackgroundImage(new mxImage(bgImg.src, bgImg.width,
- bgImg.height, bgImg.x, bgImg.y));
- }
- else
- {
- graph.setBackgroundImage(null);
- }
-
- // Parses XML into graph
- var codec = new mxCodec(xmlDoc);
- var model = graph.getModel();
- codec.decode(xmlDoc.documentElement, model);
- var bg;
-
- if (data.format == 'pdf')
- {
- if (data.bg == 'none' || bg == '')
- {
- bg = null;
- }
- else
- {
- bg = xmlDoc.documentElement.getAttribute('background');
-
- if (bg == 'none' || !bg)
- {
- bg = '#ffffff';
- }
- }
- }
- else
- {
- // Loads background color
- bg = xmlDoc.documentElement.getAttribute('background');
- // Normalizes values for transparent backgrounds
- if (bg == 'none' || bg == '')
- {
- bg = null;
- }
-
- // Checks if export format supports transparent backgrounds
- if (bg == null && data.format != 'gif' && data.format != 'png' && data.format != 'svg')
- {
- bg = '#ffffff';
- }
-
- // Sets background color on page
- if (bg != null)
- {
- document.body.style.backgroundColor = bg;
- }
- }
-
- //handle layers
- if (extras != null && ((extras.layers != null && extras.layers.length > 0) ||
- (extras.layerIds != null && extras.layerIds.length > 0)))
- {
- var childCount = model.getChildCount(model.root);
-
- // Hides all layers
- for (var i = 0; i < childCount; i++)
- {
- model.setVisible(model.getChildAt(model.root, i), false);
- }
- if (extras.layerIds != null)
- {
- for (var i = 0; i < extras.layerIds.length; i++)
- {
- model.setVisible(model.getCell(extras.layerIds[i]), true);
- }
- }
- else
- {
- for (var i = 0; i < extras.layers.length; i++)
- {
- var layer = model.getChildAt(model.root, extras.layers[i]);
-
- if (layer != null)
- {
- model.setVisible(layer, true);
- }
- }
- }
- }
-
- // Sets initial value for PDF page background
- var gb = graph.getGraphBounds();
- graph.pdfPageVisible = false;
-
- // Handles PDF output where the output should match the page format if the page is visible
- if (data.print || data.format == 'pdf')
- {
- var printScale = 1;
-
- var pw = data.pageWidth || xmlDoc.documentElement.getAttribute('pageWidth');
- var ph = data.pageHeight || xmlDoc.documentElement.getAttribute('pageHeight');
- graph.pdfPageVisible = true;
-
- if (pw != null && ph != null)
- {
- graph.pageFormat = new mxRectangle(0, 0, parseFloat(pw), parseFloat(ph));
- }
-
- var ps = data.pageScale || xmlDoc.documentElement.getAttribute('pageScale');
-
- if (ps != null)
- {
- graph.pageScale = ps;
- }
- if (data.fileTitle != null)
- {
- document.title = data.fileTitle;
- }
-
- var pf = graph.pageFormat;
- var temp = data.scale;
- pf.width = Math.ceil(pf.width * graph.pageScale);
- pf.height = Math.ceil(pf.height * graph.pageScale);
- var scale = 1;
- if (data.fit == '1' && data.sheetsAcross != null && data.sheetsDown != null)
- {
- var h = data.sheetsAcross;
- var v = data.sheetsDown;
- if (!isNaN(temp))
- {
- pf.width = Math.ceil(pf.width * temp);
- pf.height = Math.ceil(pf.height * temp);
- }
-
- scale = Math.min((pf.height * v) / (gb.height / graph.view.scale),
- (pf.width * h) / (gb.width / graph.view.scale));
- }
- else
- {
- scale = !isNaN(temp) ? temp : 1;
- }
- // Applies print scale
- data.scale = scale * printScale;
- graph.getPageSize = function()
- {
- return new mxRectangle(0, 0, this.pageFormat.width * this.pageScale,
- this.pageFormat.height * this.pageScale);
- };
-
- graph.getPageLayout = function()
- {
- var size = this.getPageSize();
- var bounds = this.getGraphBounds();
- if (bounds.width == 0 || bounds.height == 0)
- {
- return new mxRectangle(0, 0, 1, 1);
- }
- else
- {
- // Computes untransformed graph bounds
- var x = Math.ceil(bounds.x / this.view.scale - this.view.translate.x);
- var y = Math.ceil(bounds.y / this.view.scale - this.view.translate.y);
- var w = Math.floor(bounds.width / this.view.scale);
- var h = Math.floor(bounds.height / this.view.scale);
-
- var x0 = Math.floor(x / size.width);
- var y0 = Math.floor(y / size.height);
- var w0 = Math.ceil((x + w) / size.width) - x0;
- var h0 = Math.ceil((y + h) / size.height) - y0;
-
- return new mxRectangle(x0, y0, w0, h0);
- }
- };
- // Fits the number of background pages to the graph
- graph.view.getBackgroundPageBounds = function()
- {
- var layout = this.graph.getPageLayout();
- var page = this.graph.getPageSize();
-
- return new mxRectangle(
- this.scale * (this.translate.x + layout.x * page.width),
- this.scale * (this.translate.y + layout.y * page.height),
- this.scale * layout.width * page.width,
- this.scale * layout.height * page.height);
- };
- }
- if (!graph.pdfPageVisible)
- {
- var b = graph.getGraphBounds();
-
- // Floor is needed to keep rendering crisp
- if (data.w > 0 || data.h > 0)
- {
- var s = 1;
-
- if (data.w > 0 && data.h > 0)
- {
- s = Math.min(data.w / b.width, data.h / b.height);
- }
- else if (data.w > 0)
- {
- s = data.w / b.width;
- }
- else
- {
- s = data.h / b.height;
- }
-
- graph.view.scaleAndTranslate(s,
- Math.floor(data.border / s - Math.floor(b.x)),
- Math.floor(data.border / s - Math.floor(b.y)));
- }
- else
- {
- var s = data.scale;
-
- if (autoScale)
- {
- var pageWidth = (extras != null && extras.pageWidth != null) ? extras.pageWidth : 800;
-
- if (b.width < pageWidth & b.height < 1.5 * pageWidth)
- {
- s = 4;
- }
- else if (b.width < 2 * pageWidth & b.height < 3 * pageWidth)
- {
- s = 3;
- }
- else if (b.width < 4 * pageWidth && b.height < 6 * pageWidth)
- {
- s = 2;
- }
-
- if (extras != null && extras.isGoogleSheet != null)
- {
- GOOGLE_APPS_MAX_AREA = GOOGLE_SHEET_MAX_AREA;
- }
-
- //The image cannot exceed 25 MP to be included in Google Apps
- if (b.width * s * b.height * s > GOOGLE_APPS_MAX_AREA)
- {
- //Subtracting 0.01 to prevent any other rounding that can make slightly over 25 MP
- s = Math.sqrt(GOOGLE_APPS_MAX_AREA / (b.width * b.height)) - 0.01;
- }
- }
-
- graph.view.scaleAndTranslate(s,
- Math.floor(data.border - Math.floor(b.x)),
- Math.floor(data.border - Math.floor(b.y)));
- }
- }
- else
- {
- // Disables border for PDF page export
- data.border = 0;
-
- // Moves to first page in page layout
- var layout = graph.getPageLayout();
- var page = graph.getPageSize();
- var dx = layout.x * page.width;
- var dy = layout.y * page.height;
-
- if (dx != 0 || dy != 0)
- {
- graph.view.setTranslate(Math.floor(-dx), Math.floor(-dy));
- }
- }
-
- // Gets the diagram bounds and sets the document size
- bounds = (graph.pdfPageVisible) ? graph.view.getBackgroundPageBounds() : graph.getGraphBounds();
- bounds.width = Math.ceil(bounds.width + data.border) + 1; //The 1 extra pixels to prevent cutting the cells on the edges when crop is enabled
- bounds.height = Math.ceil(bounds.height + data.border) + 1; //The 1 extra pixels to prevent starting a new page. TODO Not working in every case
-
- // Print to pdf fails for 1x1 pages
- if (bounds.width <= 1 && bounds.height <= 1)
- {
- bounds.width = 2;
- bounds.height = 2;
- }
- expScale = graph.view.scale || 1;
-
- // Converts the graph to a vertical sequence of pages for PDF export
- if (graph.pdfPageVisible)
- {
- var pf = graph.pageFormat || mxConstants.PAGE_FORMAT_A4_PORTRAIT;
- var scale = (data.print || data.format == 'pdf') ? data.scale : 1 / graph.pageScale;
- var autoOrigin = ((data.print || data.format == 'pdf') && data.fit == '1') ||
- data.crop == '1' || xmlDoc.documentElement.getAttribute('page') != '1';
- var border = 0;
- // Negative coordinates are cropped or shifted if page visible
- var x0 = 0;
- var y0 = 0;
-
- if (data.crop == '1')
- {
- pf.width = (gb.width + 1.5) * scale;
- pf.height = (gb.height + 1.5) * scale;
- }
- // Starts at first visible page
- if (!autoOrigin)
- {
- var layout = graph.getPageLayout();
- x0 -= layout.x * pf.width;
- y0 -= layout.y * pf.height;
- }
- var anchorId = (currentPageId != null) ? 'page/id,' + currentPageId : null;
-
- if (preview == null)
- {
- preview = new mxPrintPreview(graph, scale, pf, border, x0, y0);
- preview.printBackgroundImage = true;
- preview.autoOrigin = autoOrigin;
- preview.backgroundColor = bg;
- preview.pageMargin = (data.pageMargin != null) ?
- parseInt(data.pageMargin) : ((data.crop == '1') ?
- 0 : preview.pageMargin);
-
- // Replaces background images with SVG subtrees
- var previewDrawBackgroundImage = preview.drawBackgroundImage;
-
- preview.drawBackgroundImage = function(img)
- {
- previewDrawBackgroundImage.apply(this, arguments);
- if (img.node != null)
- {
- EditorUi.embedSvgImages(img.node);
- graph.disableSvgLinks(img.node, function(link)
- {
- link.setAttribute('href', 'javascript:void(0)');
- });
- }
- };
- // Renders the grid and configures math
- var previewAddGraphFragment = preview.addGraphFragment;
- preview.addGraphFragment = function(dx, dy, scale, pageNumber, div, clip)
- {
- previewAddGraphFragment.apply(this, arguments);
- // Disables math rendering in graph
- if (!graph.mathEnabled)
- {
- div.classList.add('geDisableMathJax')
- }
- waitForGoogleFontImports(div);
- };
- // Renders print output into this document and removes the graph container
- preview.gridColor = gridColor;
- preview.gridSize = graph.gridSize;
- preview.gridSteps = graph.view.gridSteps;
- preview.open(null, window, null, null, anchorId, pf);
- }
- else
- {
- preview.gridColor = gridColor;
- preview.gridSize = graph.gridSize;
- preview.gridSteps = graph.view.gridSteps;
- preview.backgroundColor = bg;
- preview.autoOrigin = autoOrigin;
- preview.appendGraph(graph, scale, x0, y0, null, null, anchorId, pf);
- }
- // Adds shadow
- // NOTE: Shadow rasterizes output
- /*if (mxClient.IS_SVG && xmlDoc.documentElement.getAttribute('shadow') == '1')
- {
- var svgs = document.getElementsByTagName('svg');
-
- for (var i = 0; i < svgs.length; i++)
- {
- var svg = svgs[i];
- var filter = graph.addSvgShadow(svg, null, true);
- filter.setAttribute('id', 'shadow-' + i);
- svg.appendChild(filter);
- svg.setAttribute('filter', 'url(#' + 'shadow-' + i + ')');
- }
-
- border = 7;
- }*/
-
- bounds = new mxRectangle(0, 0, pf.width, pf.height);
- }
- else
- {
- var bgImg = graph.backgroundImage;
- if (bgImg != null)
- {
- var t = graph.view.translate;
- var s = graph.view.scale;
- bounds.add(new mxRectangle(
- (t.x + bgImg.x) * s, (t.y + bgImg.y) * s,
- bgImg.width * s, bgImg.height * s));
- if (t.x < 0 || t.y < 0)
- {
- graph.view.setTranslate(
- t.x < 0 ? Math.max(-bgImg.x * s, t.x) : t.x,
- t.y < 0 ? Math.max(-bgImg.y * s, t.y) : t.y);
- bounds.x = 0.5;
- bounds.y = 0.5;
- }
- }
- // Adds shadow
- // NOTE: PDF shadow rasterizes output so it's disabled
- if (data.format != 'pdf' && mxClient.IS_SVG && xmlDoc.documentElement.getAttribute('shadow') == '1')
- {
- graph.addSvgShadow(graph.view.canvas.ownerSVGElement, null, true);
- graph.setShadowVisible(true);
- bounds.width += 7;
- bounds.height += 7;
- }
-
- document.body.style.width = Math.ceil(bounds.x + bounds.width) + 'px';
- document.body.style.height = Math.ceil(bounds.y + bounds.height) + 'px';
- }
- };
-
- if (diagrams != null && diagrams.length > 0)
- {
- var to = diagrams.length - 1;
-
- // Parameters to and all pages should not be sent with formats other than PDF with page view enabled
- if (data.allPages != '1')
- {
- if (data.pageId != null)
- {
- for (var i = 0; i < diagrams.length; i++)
- {
- if (data.pageId == diagrams[i].getAttribute('id'))
- {
- from = i;
- to = i;
- break;
- }
- }
- }
- else
- {
- from = Math.max(0, Math.min(parseInt(data.from) || from, diagrams.length - 1));
- to = parseInt(data.to);
- //If to is not defined, use from (so one page), otherwise, to is restricted to the range from "from" to diagrams.length - 1
- to = isNaN(to)? from : Math.max(from, Math.min(to, diagrams.length - 1));
- }
- }
-
- /**
- * Implements %page% and %pagenumber% placeholders
- */
- var graphGetGlobalVariable = graph.getGlobalVariable;
-
- graph.getGlobalVariable = function(name)
- {
- if (name == 'page')
- {
- return (diagrams == null) ? 'Page-1' :
- (diagrams[from].getAttribute('name') || ('Page-' + (from + 1)));
- }
- else if (name == 'pagenumber')
- {
- return from + 1;
- }
-
- return graphGetGlobalVariable.apply(this, arguments);
- };
- waitCounter += to - from + 1;
-
- for (var i = from; i <= to; i++)
- {
- if (diagrams[i] != null)
- {
- if (pageId == null)
- {
- pageId = diagrams[i].getAttribute('id');
- }
-
- xmlDoc = Editor.parseDiagramNode(diagrams[i]);
-
- if (xmlDoc != null)
- {
- xmlDoc = xmlDoc.ownerDocument;
- }
- graph.getModel().clear();
- from = i;
- renderPage(diagrams[i].getAttribute('id'));
- }
- decrementWaitCounter();
- }
- }
- else
- {
- renderPage();
- }
- if (preview != null)
- {
- preview.addPendingCss(document);
- Graph.rewritePageLinks(document, true);
- }
- if (fallbackFont)
- {
- // Add a fallbackFont font to all labels in case the selected font doesn't support the character
- // Some systems doesn't have a good fallback fomt that supports all languages
- // Use this with a custom font-face in export-fonts.css file
- document.querySelectorAll('foreignObject div').forEach(d => d.style.fontFamily = (d.style.fontFamily || '') + ', ' + fallbackFont);
- }
- if (data.format == 'pdf')
- {
- graph.container.parentNode.removeChild(graph.container);
- }
- // Includes images in SVG and HTML labels
- waitForImages('image', 'xlink:href');
- waitForImages('img', 'src');
- renderMath(document.body);
-
- // Invokes callback
- decrementWaitCounter();
-
- return graph;
- };
- //Electron pdf export
- if (mxIsElectron)
- {
- try
- {
- electron.registerMsgListener('render', (arg) =>
- {
- try
- {
- if (window.shapesLoaded)
- {
- render(arg);
- }
- else
- {
- window.pendingRequest = arg;
- }
- }
- catch(e)
- {
- console.log(e);
- electron.sendMessage('render-finished', null);
- }
- });
- }
- catch(e)
- {
- console.log(e);
- }
- }
|