123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Draw.io Viewer</title>
- <style type="text/css">
- html, body {
- height:100%;
- overflow:hidden;
- }
- body {
- background-color:#ffffff;
- background-image:url(/images/drawlogo-gray.svg);
- background-repeat:no-repeat;
- background-position:center top;
- background-size: 64px;
- font-family:Arial,sans-serif;
- width:100%;
- margin:0;
- }
- </style>
- </head>
- <body>
- <script type="text/javascript">
- // Parses URL parameters
- function getUrlParam(param)
- {
- var result = (new RegExp(param + '=([^&]*)')).exec(window.location.search);
-
- if (result != null && result.length > 0)
- {
- return decodeURIComponent(result[1].replace(/\+/g, '%20'))
- }
-
- return null;
- };
- // Sets global environment variables
- RESOURCE_BASE = '/resources/dia';
- STENCIL_PATH = '/stencils';
- SHAPES_PATH = '/shapes';
- // Overrides browser language with Confluence user language
- var lang = getUrlParam('loc');
- var lightbox = getUrlParam('lightbox') == '1';
- if (lightbox)
- {
- document.body.style.backgroundImage = 'url(/images/drawlogo-text-bottom.svg)';
- document.body.style.backgroundPosition = 'center 30%';
- document.body.style.backgroundSize = '128px';
- }
- // Language is in the Connect URL
- if (lang != null)
- {
- var dash = lang.indexOf('-');
-
- if (dash >= 0)
- {
- mxLanguage = lang.substring(0, dash);
- }
- }
- </script>
- <script type="text/javascript" src="/js/viewer.min.js"></script>
- <script type="text/javascript">
- (function()
- {
- // Enables dynamic loading of shapes and stencils (same domain)
- mxStencilRegistry.dynamicLoading = true;
- // Loads the Atlassian API
- var script = document.createElement('script');
- var baseUrl = getUrlParam('xdm_e') + getUrlParam('cp');
- // Loads the attachment and renders the diagram
- var diagramWidth = parseFloat(getUrlParam('width'));
- var diagramHeight = parseFloat(getUrlParam('height'));
- var diagramName = getUrlParam('diagramName');
-
- //ceoId and owningPageId are IDs of the page that potentially hold the attachment
- //they will differ when page history is shown, ceoId will be historical version ID,
- //owningPageId will be the ID of the current version that holds the attachment
- //ceoId is used as fallback in case owningPageId is not set(should be very rare)
- var ceoId = getUrlParam('ceoId');
- var owningPageId = getUrlParam('owningPageId');
- var revision = null;
-
- var tbStyle = getUrlParam('tbstyle') || 'top';
- var links = getUrlParam('links') || 'auto';
- var enableLightbox = getUrlParam('lbox') != '0';
- var simpleViewer = false; // unused
- var tbHeight = (tbStyle == 'top' && !simpleViewer) ? GraphViewer.prototype.toolbarHeight : 0;
- var zoom = parseFloat(getUrlParam('zoom') || 1);
- var border = (simpleViewer) ? 0 : 8;
-
- if (!lightbox)
- {
- document.body.style.backgroundImage = 'url(/images/aui-wait.gif)';
- document.body.style.backgroundPosition = 'left top';
- document.body.style.backgroundSize = 'auto auto';
- }
-
- function main()
- {
- // Sets initial placeholder size to allow for scrollbars in fit to page width
- AP.resize('100%', (lightbox) ? '100%' : (diagramHeight * zoom + tbHeight + 2 * border));
-
- function showError(msg)
- {
- document.body.style.backgroundImage = 'none';
- document.body.style.padding = '4px';
- mxUtils.write(document.body, msg);
- AP.resize('100%', 24);
- };
-
- AP.require(['request', 'dialog', 'messages', 'navigator'], function(request, dialog, messages, navigator)
- {
- // Uses pageId from current page as page in macro may be outdated after export
- navigator.getLocation(function (data)
- {
- var candidateId = (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId;
- if (data != null && data.target != null && data.context != null)
- {
- candidateId = data.context.contentId;
- }
-
- // Loads the given XML into the viewer
- function showDiagram(id, backupId, name, revision, page, links, retryParams)
- {
- id = id.toString();
-
- retryParams = retryParams || {}; //so we can use it without NPE check
-
- if (id != null && id.length > 0 && name != null && name.length > 0)
- {
- // Option currently not available in the UI
- if (simpleViewer)
- {
- document.body.style.backgroundImage = 'none';
- var img = document.createElement('img');
- img.style.cssText = 'max-width:100%;';
- img.setAttribute('src', baseUrl + '/download/attachments/' + id + '/'
- + encodeURIComponent(name) + ".png?api=v2"
- + (revision != null ? "&version=" + revision : ""));
-
- if (zoom != 1)
- {
- img.style.width = Math.round(diagramWidth * zoom) + 'px';
- }
-
- document.body.appendChild(img);
- }
- else
- {
- var serverName = document.referrer;
- var timeout = 25000;
- var index1 = serverName.indexOf('//');
-
- if (index1 > 0)
- {
- var index2 = serverName.indexOf('/', index1 + 2);
-
- if (index2 > index1)
- {
- serverName = serverName.substring(index1 + 2, index2);
- }
- }
-
- var acceptResponse = true;
-
- var timeoutThread = window.setTimeout(function()
- {
- acceptResponse = false;
-
- if (lightbox)
- {
- var message = messages.error('The connection has timed out', 'The server at ' +
- serverName + ' is taking too long to respond.');
-
- messages.onClose(message, function()
- {
- dialog.close();
- });
- }
- else
- {
- showError('The connection has timed out: The server at ' +
- serverName + ' is taking too long to respond.');
- }
- }, timeout);
-
- request(
- {
- url: '/download/attachments/' + id + '/' + encodeURIComponent(name) +
- ((revision != null && revision.length > 0) ? '?version=' + revision : ''),
- success: function(xml)
- {
- window.clearTimeout(timeoutThread);
-
- if (acceptResponse)
- {
- document.body.style.backgroundImage = 'none';
-
- if (lightbox)
- {
- var config = {highlight: '#3572b0', nav: true, lightbox: false};
-
- if (links != 'auto')
- {
- config.target = links;
- }
-
- var viewer = new GraphViewer(null, null, config);
- viewer.currentPage = parseInt(page || 0);
- viewer.lightboxChrome = false;
- viewer.xml = xml;
-
- // Enables layers via flag to avoid toolbar
- viewer.layersEnabled = true;
-
- var ui = viewer.showLocalLightbox();
-
- // Destroy lightbox with ui instance
- var destroy = ui.destroy;
- ui.destroy = function()
- {
- dialog.close();
- destroy.apply(this, arguments);
- };
- }
- else
- {
- // LATER: Fix horizontal alignment ignored with 100% width of iframe
- // LATER: Fix page scrolling on touch device if trigger event on diagram
- // LATER: Hide toolbar after second container click for iOS
- // LATER: Disable responsive resize while lightbox shows
- var container = document.createElement('div');
- container.style.cssText = 'position:absolute;box-sizing:border-box;' +
- 'max-width:100%;margin-bottom:' + tbHeight +'px;border:1px solid transparent;';
- document.body.appendChild(container);
- var doc = mxUtils.parseXml(xml);
-
- var config = {highlight: '#3572b0', 'toolbar-position': tbStyle,
- nav: true, border: 2, zoom: zoom};
-
- if (tbStyle == 'top')
- {
- config.title = name;
- }
-
- if (links != 'auto')
- {
- config.target = links;
- }
-
- if (!enableLightbox)
- {
- config.lightbox = false;
- }
-
- if (tbStyle != 'hidden')
- {
- config.toolbar = 'pages zoom layers';
- config.border = border;
-
- if (enableLightbox)
- {
- config.toolbar += ' lightbox';
- }
- }
- else
- {
- // Workaround for invalid width if no toolbar is present
- var updateContainerWidth = GraphViewer.prototype.updateContainerWidth;
-
- GraphViewer.prototype.updateContainerWidth = function(container, width)
- {
- width += 3;
- updateContainerWidth.apply(this, arguments);
- };
- }
-
- var viewer = new GraphViewer(container, doc.documentElement, config);
-
- // Handles resize of iframe after zoom
- var graphDoResizeContainer = viewer.graph.doResizeContainer;
-
- function updateHeight(height)
- {
- AP.resize('100%', (tbHeight == 0) ? Math.ceil(height) : container.offsetHeight + tbHeight);
- };
-
- viewer.graph.doResizeContainer = function(width, height)
- {
- graphDoResizeContainer.apply(this, arguments);
- updateHeight(height);
- };
-
- // Updates the size of the iframe in responsive cases
- viewer.updateContainerHeight = function(container, height)
- {
- updateHeight(height);
- };
-
- updateHeight();
-
- viewer.showLightbox = function()
- {
- dialog.create(
- {
- header: name,
- key: 'lightbox',
- size: 'fullscreen',
- customData: {id: id, name: name, revision: revision, page: viewer.currentPage, links: links},
- chrome: true
- });
- };
- }
- if (retryParams.saveIt)
- {
- //Since attachment wasn't found in this page, it is better to save it to this page
- //First load AC dynamically. Since AC is not needed in the viewer except for this case
- var head = document.getElementsByTagName('head')[0];
- var script = document.createElement('script');
- script.setAttribute('data-options', 'resize:false;margin:false');
-
- // Main
- script.onload = function()
- {
- //save diagram
- AC.saveDiagram(retryParams.pageId, name, btoa(unescape(encodeURIComponent(xml))),
- function()
- {
- //nothing!
- },
- function()
- {
- //nothing!
- }, false, 'text/plain', 'Diagram imported by Draw.io');
-
- //TODO save preview png
- //This requires an editor to do the png export, may be a canvas can be used with supported browsers
- };
- script.src = 'ac.js';
- head.appendChild(script);
- }
- }
- },
- error: function (err)
- {
- window.clearTimeout(timeoutThread);
-
- if (err.status == 404)
- {
- //Copied pages are reset to revision 1, in addition, copy&paste pages saves diagrams imported from another page
- //So, try revision 1 first
- if (revision > 1)
- {
- showDiagram(id, backupId, name, null, page, links, {revision: revision});
- }
- else if (backupId != null)
- {
- //Since attachment wasn't found in this page, it is better to save it to this page
- showDiagram(backupId, null, name, revision || retryParams.revision, page, links, {saveIt: true, pageId: id});
- }
- }
- else if (acceptResponse)
- {
- document.body.style.backgroundImage = 'none';
- showError('Error: ' + err.status);
- }
- }
- });
- }
- }
- else
- {
- showError('Error: Invalid descriptor');
- }
- };
-
- if (lightbox)
- {
- // Gets the paramters from the customData object in lightbox mode
- // LATER: Add XML to custom data (does not seem to work)
- showDiagram(dialog.customData.id, dialog.customData.id, dialog.customData.name, dialog.customData.revision, dialog.customData.page, dialog.customData.links);
- }
- else
- {
- var myPageId = (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId;
- showDiagram(candidateId, (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId, diagramName, revision, null, links);
- }
- });
- });
- };
-
- mxResources.loadDefaultBundle = false;
- var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
- mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage);
- // Prefetches asynchronous requests so that below code runs synchronous
- // Loading the correct bundle (one file) via the fallback system in mxResources. The stylesheet
- // is compiled into JS in the build process and is only needed for local development.
- var bundleLoaded = false;
- var scriptLoaded = false;
- var validSize = document.documentElement.offsetWidth > 0;
- function mainBarrier()
- {
- if (validSize && bundleLoaded && scriptLoaded)
- {
- main();
- }
- };
- // Disables delayed rendering since the container is created on the fly
- GraphViewer.prototype.checkVisibleState = false;
-
- // Workaround for collapsed panel is to delay main until size is not 0
- if (!validSize)
- {
- var listener = function()
- {
- if (document.documentElement.offsetWidth > 0)
- {
- window.removeEventListener('resize', listener);
- validSize = true;
- mainBarrier();
- }
- };
-
- window.addEventListener('resize', listener);
- }
-
- mxUtils.getAll([bundle], function(xhr)
- {
- // Adds bundle text to resources
- mxResources.parse(xhr[0].getText());
- bundleLoaded = true;
- mainBarrier();
- });
- script.onload = function()
- {
- // Workaround for Google Chrome triggering
- // no resize event if height is set to 0
- if (mxClient.IS_GC && !validSize)
- {
- AP.resize('100%', 1);
- }
-
- scriptLoaded = true;
- mainBarrier();
- };
- script.src = baseUrl + '/atlassian-connect/all.js';
- script.setAttribute('data-options', 'sizeToParent:true;');
- document.getElementsByTagName('head')[0].appendChild(script);
- })();
- </script>
- </body>
- </html>
|