/** * @provides javelin-behavior-diagram-extension */ JX.behavior('diagram-extension', function(config) { var phorge_extension = {}; function createIframe() { var iframe = document.createElement('iframe'); var iframeInitializedEvent = new CustomEvent('initReceived'); iframe.setAttribute('title', 'diagrams.net editor'); iframe.setAttribute('frameborder', '0'); iframe.style.width = '100%'; iframe.style.height = 'calc(100vh - 91px)'; iframe.style.marginTop = '30px'; iframe.style.marginBottom = '-16px'; var receive = function (evt) { if (evt.data.length > 0) { var msg = JSON.parse(evt.data); if (msg.event == 'init') { if (phorge_extension.diagramBase64) { var diagramName = document.querySelector('.diagramName'); diagramName.style.display = 'inline-block'; diagramName.querySelector('a').innerText = phorge_extension.diagramName; if (phorge_extension.diagramVersion != '') { diagramName.querySelector('.version').innerText = '(#' + phorge_extension.diagramVersion + ')'; } } iframe.contentWindow.postMessage(JSON.stringify({ action: 'load', autosave: 1, xmlpng: 'data:image/png;base64,' + phorge_extension.diagramBase64 }), '*'); } else if (msg.event == 'load') { // enable Mathematical Typesettings by default iframe.contentWindow.sb.editorUi.setMathEnabled(true); setupButtonsInMenuToolbar(); } else if (msg.event == 'export') { saveFlowchart(name, msg.data, iframe); } else if (msg.event == 'save') { iframe.contentWindow.postMessage(JSON.stringify({ action: 'export', format: 'xmlpng', xml: msg.xml, spin: 'Updating page' }), '*'); } } }; window.addEventListener('message', receive); iframe.setAttribute('src', phorge_extension.editor); document.querySelector('#mainScreen').appendChild(iframe); iframe.contentWindow.addEventListener('DOMContentLoaded', addToolbarResourcesToIframe); iframe.dispatchEvent(iframeInitializedEvent); iframe.contentWindow.RESOURCES_PATH = document.baseURI + 'iframe/resources'; iframe.contentWindow.STENCIL_PATH = document.baseURI + 'iframe/stencils'; iframe.contentWindow.IMAGE_PATH = document.baseURI + 'iframe/images'; iframe.contentWindow.STYLE_PATH = document.baseURI + 'iframe/styles'; iframe.contentWindow.CSS_PATH = document.baseURI + 'iframe/styles'; } function addToolbarResourcesToIframe() { var head = this.document.getElementsByTagName('head')[0]; var script = this.document.createElement('script'); script.src = config.toolbarJs; head.appendChild(script); var styles = this.document.createElement('link'); styles.setAttribute('type', 'text/css'); styles.setAttribute('rel', 'stylesheet'); styles.setAttribute('href', config.toolbarCss); head.appendChild(styles); } function init(diagramName, diagramPHID, diagramVersion, diagramBase64) { var baseURI = document.baseURI; if (diagramName != '' && diagramBase64 != '') { baseURI = baseURI.substr(0, baseURI.length - diagramName.length - 1); if (diagramVersion != '') { baseURI = baseURI.substr(0, baseURI.length - diagramVersion.length - 1); } } phorge_extension.baseURI = baseURI; phorge_extension.csrf = document.querySelector('input[name="__csrf__"]')?.value; phorge_extension.editor = baseURI + '/iframe/?embed=1&spin=0&proto=json&noExitBtn=1'; phorge_extension.name = null; phorge_extension.editor += '&lang=en'; phorge_extension.editor += '&ui=min'; phorge_extension.diagramPHID = diagramPHID; phorge_extension.diagramName = diagramName; phorge_extension.diagramVersion = diagramVersion; phorge_extension.diagramBase64 = diagramBase64; createIframe(); } function saveFlowchart(name, flowchartData, iframe) { var diagramID = document.querySelector('.diagramName a').innerText.replace(/^DIAG/, ''); var csrf = document.querySelector('input[name="__csrf__"]')?.value; var data = new URLSearchParams(); data.append('data', flowchartData); data.append('diagramID', diagramID); data.append('__csrf__', csrf); data.append('__form__', '1'); data.append('__ajax__', 'true'); var xmlhttp = new XMLHttpRequest(); xmlhttp.overrideMimeType('application/json'); xmlhttp.open('POST', 'save/', true); xmlhttp.onload = function () { if (xmlhttp.readyState == 4) { var errorMessage = null; try { var result = JSON.parse(xmlhttp.responseText); if (result.Status != 'OK') { errorMessage = result.Error; } else { // make sure we don't show messagebox about redirection in browser iframe.parentNode.removeChild(iframe); if (!phorge_extension.diagramVersion || !phorge_extension.diagramVersion.trim()) { if (!phorge_extension.diagramName || !phorge_extension.diagramName.trim()) { // load new diagram window.location = window.location + '/DIAG' + result.DiagramID; } else { // reload actual page (so versioned diagrams info is also updated) window.location.reload(); } } else { // cut off version id from url var url = document.baseURI .substring(0, document.baseURI .length - phorge_extension.diagramVersion .length - 1 ); // redirect to latest version of diagram window.location = url; } } } catch (exc) { errorMessage = exc.message; } } }; xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;'); xmlhttp.send(data); } function setupButtonsInMenuToolbar() { var iframe = document.querySelector('iframe'); var btnSave = Array.prototype.slice.call( iframe.contentDocument .querySelector('.geMenubarContainer') .querySelectorAll('button'), 0 ).reverse()[0]; // identify Exit Button btnSave.classList.add('btnSave'); // change layout settings of area where btnSave belongs to so // that the dropdown menu is not hidden under the drawing area btnSave.parentNode.style.position = 'fixed'; // create extra controls var subscribeUnsubscribe = setupSubscriptionButtonInMenuToolbar(iframe, btnSave); var dropdown = setupVersionDropDownInMenuToolbar(iframe, subscribeUnsubscribe); // initialize toolbuttons for (var tb in phorge_extension.toolbtn) { if (phorge_extension.toolbtn.hasOwnProperty(tb)) { phorge_extension.toolbtn[tb].instance.initialize(); } } } function setupVersionDropDownInMenuToolbar(iframe, btnLeft) { // generate 'Select Version' button // create the dropdown element const dropdown = document.createElement('div'); dropdown.classList.add('toolbtn-version-dropdown'); // create the dropdown toggle button const toggle = document.createElement('button'); toggle.classList.add('toolbtn-version-dropdown-toggle'); toggle.textContent = 'Select Version'; toggle.title = 'View previous versions'; dropdown.appendChild(toggle); const iframeContent = document.querySelector('iframe').contentDocument; const menubarContainer = iframeContent.querySelector('.geMenubarContainer'); // create the dropdown menu const menu = document.createElement('div'); menu.classList.add('toolbtn-version-dropdown-menu'); menubarContainer.parentNode.insertBefore(menu, menubarContainer.nextSibling); // create the version list const versionList = document.createElement('ul'); versionList.classList.add('toolbtn-version-list'); menu.appendChild(versionList); // create the prev and next buttons const prevBtn = document.createElement('button'); prevBtn.classList.add('toolbtn-version-prev-btn'); prevBtn.textContent = '<'; const nextBtn = document.createElement('button'); nextBtn.classList.add('toolbtn-version-next-btn'); nextBtn.textContent = '>'; menu.appendChild(prevBtn); menu.appendChild(nextBtn); // place dropdown next to button on the left btnLeft.parentNode.insertBefore(dropdown, btnLeft.nextSibling); return dropdown; } function setupSubscriptionButtonInMenuToolbar(iframe, btnLeft) { // generate 'Subscribe/Unsubscribe' button // create grouping div element const div = document.createElement('div'); div.classList.add('toolbtn-diagram-subscription'); // create subscribe button const btnSubscribe = document.createElement('button'); btnSubscribe.classList.add('subscribe'); btnSubscribe.classList.add('eye'); btnSubscribe.title = 'Subscribe'; div.appendChild(btnSubscribe); // create unsubscribe button const btnUnsubscribe = document.createElement('button'); btnUnsubscribe.classList.add('unsubscribe'); btnUnsubscribe.classList.add('eye'); btnUnsubscribe.title = 'Unsubscribe'; div.appendChild(btnUnsubscribe); // place grouping next to button on the left btnLeft.parentNode.insertBefore(div, btnLeft.nextSibling); return div; } if (config.initParams) { init.apply(undefined, config.initParams); } window.__diagram = phorge_extension; });