1jQuery( document ).ready( function() { 2 3 const serviceUrl = 'https://embed.diagrams.net/?embed=1&proto=json&spin=1'; 4 const doctypeXML = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'; 5 6 // check if name/id of new diagram is valid 7 function validId(id) { 8 return id.length > 0 && /^[\w][\w\.\-]*$/.test( id ) 9 } 10 11 // return URL to fetch existing diagram from DW 12 function getLocalDiagramUrl(ns, id) { 13 return DOKU_BASE + 'lib/exe/ajax.php?call=mediaupload&ow=true&ns=' + ns + '&qqfile=' + id + '§ok=' + JSINFO['sectok']; 14 } 15 16 // split full id into ns and id parts 17 function splitFullId(fullId) { 18 let id = fullId; 19 let ns = ''; 20 const idParts = id.split(':'); 21 if (idParts.length > 1) { 22 ns = idParts[0]; 23 id = idParts.slice(1).join(':'); 24 } 25 return {ns: ns, id: id}; 26 } 27 28 /** 29 * Launch diagram editor's iframe 30 * 31 * @param fullId 32 */ 33 const launchEditor = function(fullId) { 34 if (!jQuery('#drawio-frame')[0]) { 35 36 jQuery('body').append('<iframe id="drawio-frame" style="border: 0;position: fixed; top: 0; left: 0; right:0; bottom: 0; width:100%; height:100%; z-index: 9999;"></iframe>'); 37 38 jQuery(window).on('message', {fullId: fullId}, handleServiceMessages); 39 jQuery('#drawio-frame').attr('src', serviceUrl); 40 } 41 }; 42 43 /** 44 * Handle messages from diagramming service 45 * 46 * @param e 47 */ 48 const handleServiceMessages = function( e ) { 49 // get diagram info passed to the function 50 const fullId = e.data.fullId; 51 const {ns, id} = splitFullId(fullId); 52 53 const msg = JSON.parse( e.originalEvent.data ); 54 const drawio = jQuery( '#drawio-frame' )[0].contentWindow; 55 if( msg.event === 'init' ) { 56 // try loading existing diagram file 57 jQuery.get(DOKU_BASE + 'lib/exe/fetch.php?media=' + fullId, function (data) { 58 drawio.postMessage(JSON.stringify({action: 'load', xml: data}), '*'); 59 }, 'text') 60 .fail(function () { // catch 404, file does not exist yet locally 61 drawio.postMessage(JSON.stringify({action: 'load', xml: ''}), '*'); 62 }); 63 } else if ( msg.event === 'save' ) { 64 drawio.postMessage( 65 JSON.stringify( {action: 'export', format: 'xmlsvg', spin: 'Speichern' } ), 66 '*' 67 ); 68 } else if ( msg.event === 'export' ) { 69 if ( msg.format !== 'svg' ) { 70 alert( 'Nicht unterstützt!' ); 71 } else { 72 const datastr = doctypeXML + '\n' + 73 decodeURIComponent( atob( msg.data.split( ',' )[1] ).split( '' ).map( function( c ) { 74 return '%' + ( '00' + c.charCodeAt( 0 ).toString( 16 ) ).slice( -2 ); 75 } ).join( '' ) ); 76 jQuery.post( getLocalDiagramUrl(ns, id), datastr ) 77 .done( function() { 78 jQuery( window ).off( 'message', handleServiceMessages ); 79 jQuery( '#drawio-frame' ).remove(); 80 setTimeout( function() { 81 location.reload(); 82 }, 200 ); 83 } ).fail( function() { 84 alert( 'Fehler beim Speichern' ); 85 } ); 86 } 87 } else if( msg.event === 'exit' ) { 88 jQuery( window ).off( 'message', handleServiceMessages ); 89 jQuery( '#drawio-frame' ).remove(); 90 } 91 }; 92 93 // add diagram edit button to all SVGs included in wiki pages 94 if( JSINFO['iseditor'] ) { 95 jQuery( 'img, object' ).filter( '.media, .medialeft, .mediacenter, .mediaright' ).add( 'iframe.svgpureinsert' ).each( function() { 96 const current = jQuery( this ); 97 const src = this.nodeName === 'OBJECT' ? current.attr( 'data' ) : current.attr( 'src' ); 98 const extension = src.split( '.' ).pop().toLowerCase(); 99 if( extension === 'svg' ) { 100 const editlink = '<br><button class="drawio-btn btn btn-default btn-xs" style="clear:both" data-id="' + src.split('media=')[1].split('&')[0] + '">Editieren</button>'; 101 if( current.parent()[0].nodeName === 'A' ) { 102 current.parent().after( editlink ); 103 } else { 104 current.after( editlink ); 105 } 106 } 107 } ); 108 } 109 110 // attach diagram editing function to the button rendered on pages 111 jQuery( 'button.drawio-btn' ).on( 'click', function () { 112 const fullId = jQuery( this ).data( 'id' ); 113 launchEditor(fullId); 114 }); 115 116 // create a new diagram, triggered by click on page tools item 117 jQuery( 'a#drawio-newfile-create' ).on( 'click', function( e ) { 118 e.preventDefault(); 119 const ns = NS; 120 let id = prompt( 'Name des neuen Diagramms' ); 121 if( !validId(id) ) { 122 alert( 'Dateiname ist leer oder enthält ungültige Zeichen' ); 123 return; 124 } 125 id += '.svg'; 126 const datastr = doctypeXML + 127 '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1px" height="1px" version="1.1" content="<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" version="7.9.5" editor="www.draw.io"><diagram id="8c846276-93cf-00fc-3101-d1fabb6ae99a" name="Seite-1">dZHBEoIgEIafhrtCNXY2q0snD51JEJjQdRBH6+nTwIyxuLB8/7+7sCCSVsPJ0EZegHGNcMQGRA4I43iDd+M2kYcjSbJ3QBjFvGkBuXpyDyNPO8V4GxgtgLaqCWEBdc0LGzBqDPShrQQddm2o4CuQF1Sv6VUxK/0rttHCz1wJOXeOI6/caHEXBrra90OYlO/l5IrOtby/lZRB/4VIhkhqAKyLqiHleprtPDaXd/yjfu5teG1/JIzBUns8BB9Ishc=</diagram></mxfile>" style="background-color: rgb(255, 255, 255);"><defs/><g transform="translate(0.5,0.5)"/></svg>'; 128 jQuery.post( getLocalDiagramUrl(ns, id), datastr ) 129 .done( function( response ) { 130 if( response.error ) { 131 alert( 'Fehler beim Speichern: ' + response.error ); 132 } else { 133 alert( 'Diagramm ' + response.id + ' angelegt' ); 134 } 135 } ).fail( function() { 136 alert( 'Fehler beim Speichern' ); 137 } ); 138 } ); 139 140 /** 141 * Launch the editor and create a new diagram 142 * 143 * @param event 144 */ 145 function createDiagram(event) { 146 event.preventDefault(); 147 148 let href; 149 // FIXME does this really work? 150 // get namespace selected in ns tree 151 $selectedNSLink = jQuery('.idx_dir.selected'); 152 if ($selectedNSLink && $selectedNSLink.length > 0) { 153 href = $selectedNSLink.attr('href'); 154 } else { 155 // FIXME url rewriting? 156 href = location.href; 157 } 158 const ns = extractNs(href); 159 const id = jQuery('#drawio__create-filename').val(); 160 161 if (!validId(id)) { 162 alert('name is empty or contains invalid characters!'); 163 return; 164 } 165 166 const fullIdArray = [ns, id]; 167 launchEditor(fullIdArray.join(':') + '.svg'); 168 } 169 170 // extract ns param from URL 171 function extractNs(url) { 172 urlParam = function(name) { 173 var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(url); 174 return results[1] || ''; 175 }; 176 return decodeURIComponent(urlParam('ns')); 177 } 178 179 // returns a diagram creation form as jQuery object 180 function newDiagramForm() { 181 currentNs = extractNs(location.href); 182 $drawioCreateForm = jQuery( 183 '<form>' + 184 '<p>Create draw.io diagram in current namespace <strong><span id="drawio__current-ns">' + 185 currentNs + 186 '</strong></span></p>' + 187 '<input type="text" name="drawio-create-filename" id="drawio__create-filename" />' + 188 '<button id="drawio__create">Create</button>' + 189 '</form>' 190 ); 191 192 jQuery( $drawioCreateForm ).on( 'submit', createDiagram ); 193 194 return $drawioCreateForm; 195 } 196 197 /** 198 * Full-page media manager 199 */ 200 const $mm_page = jQuery('#mediamanager__page'); 201 if (!$mm_page.length) return; 202 203 const $mm_tree = jQuery("#media__tree"); 204 $mm_tree.prepend(newDiagramForm()); 205 206 $mm_tree.find('a.idx_dir').each(function (e) { 207 const $this = jQuery( this ); 208 $this.on('click', function (e) { 209 e.preventDefault(); 210 ns = extractNs(e.target); 211 const $nsSpan = jQuery('#drawio__current-ns'); 212 $nsSpan.text(ns); 213 }); 214 }); 215 216 // TODO pop-up media manager 217} ); 218