|
1 | | -jQuery( document ).ready( function() { |
2 | | - if( JSINFO['iseditor'] ) { |
3 | | - jQuery( 'img, object' ).filter( '.media, .medialeft, .mediacenter, .mediaright' ).add( 'iframe.svgpureinsert' ).each( function() { |
4 | | - var current = jQuery( this ); |
5 | | - var src = this.nodeName == 'OBJECT' ? current.attr( 'data' ) : current.attr( 'src' ); |
6 | | - var extension = src.split( '.' ).pop().toLowerCase(); |
7 | | - if( extension == 'svg' ) { |
8 | | - var editlink = '<br><button class="drawio-btn btn btn-default btn-xs" style="clear:both" data-id="' + src.split('media=')[1].split('&')[0] + '">Editieren</button>'; |
9 | | - if( current.parent()[0].nodeName == 'A' ) { |
10 | | - current.parent().after( editlink ); |
| 1 | +jQuery(function () { |
| 2 | + /* DOKUWIKI:include script/helpers.js */ |
| 3 | + /* DOKUWIKI:include script/service.js */ |
| 4 | + /* DOKUWIKI:include script/elements.js */ |
| 5 | + |
| 6 | + // add diagram edit button to all SVGs included in wiki pages |
| 7 | + const $images = jQuery('img').filter('.media, .medialeft, .mediacenter, .mediaright'); |
| 8 | + |
| 9 | + // collect image IDs with file extension |
| 10 | + const imageIds = $images.map(function (key, image) { |
| 11 | + return extractIdFromMediaUrl(image.src); |
| 12 | + }).toArray(); |
| 13 | + |
| 14 | + let ajaxData = {}; |
| 15 | + ajaxData['call'] = 'plugin_diagrams'; |
| 16 | + ajaxData['images'] = imageIds; |
| 17 | + |
| 18 | + // callback to attach buttons to editable diagrams |
| 19 | + const attachButtons = function (result) { |
| 20 | + const diagrams = JSON.parse(result); |
| 21 | + $images.each(function () { |
| 22 | + const id = extractIdFromMediaUrl(this.src); |
| 23 | + const $current = jQuery(this); |
| 24 | + if (diagrams.includes(id)) { |
| 25 | + let $editButton = editDiagramButton(id); |
| 26 | + if ($current.parent()[0].nodeName === 'A') { |
| 27 | + $current.parent().after("<br>", $editButton); |
11 | 28 | } else { |
12 | | - current.after( editlink ); |
| 29 | + $current.after("<br>", $editButton); |
13 | 30 | } |
14 | 31 | } |
15 | | - } ); |
16 | | - } |
| 32 | + }); |
| 33 | + }; |
17 | 34 |
|
18 | | - jQuery( 'button.drawio-btn' ).on( 'click', function() { |
19 | | - var drawio_url = 'https://embed.diagrams.net/?embed=1&proto=json&spin=1'; |
| 35 | + // query backend about permissions and SVG properties before attaching edit buttons |
| 36 | + jQuery.get( |
| 37 | + DOKU_BASE + 'lib/exe/ajax.php', |
| 38 | + ajaxData, |
| 39 | + attachButtons |
| 40 | + ); |
20 | 41 |
|
21 | | - if( !jQuery( '#drawio-frame' )[0] ) { |
22 | | - var fullId = jQuery( this ).data( 'id' ); |
23 | | - var id = fullId; |
24 | | - var ns = ''; |
25 | | - var ext = id.split( '.' ).pop().toLowerCase(); |
26 | | - var idParts = id.split( ':' ); |
27 | | - if( idParts.length > 1 ) { |
28 | | - ns = idParts[0]; |
29 | | - id = idParts.slice( 1 ).join( ':' ); |
30 | | - } |
31 | | - 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>' ); |
32 | | - var onmessage = function( e ) { |
33 | | - var msg = JSON.parse( e.originalEvent.data ); |
34 | | - var drawio = jQuery( '#drawio-frame' )[0].contentWindow; |
35 | | - if( msg.event == 'init' ) { |
36 | | - jQuery.get( DOKU_BASE + 'lib/exe/fetch.php?media=' + fullId, function( data ) { |
37 | | - drawio.postMessage( JSON.stringify( {action: 'load', xml: data} ), '*' ); |
38 | | - }, 'text' ); |
39 | | - } else if( msg.event == 'save' ) { |
40 | | - drawio.postMessage( JSON.stringify( {action: 'export', format: 'xmlsvg', spin: 'Speichern' } ), '*' ); |
41 | | - } else if( msg.event == 'export' ) { |
42 | | - if( msg.format != 'svg' ) { |
43 | | - alert( 'Nicht unterstützt!' ); |
44 | | - } else { |
45 | | - var datastr = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + |
46 | | - decodeURIComponent( atob( msg.data.split( ',' )[1] ).split( '' ).map( function( c ) { |
47 | | - return '%' + ( '00' + c.charCodeAt( 0 ).toString( 16 ) ).slice( -2 ); |
48 | | - } ).join( '' ) ); |
49 | | - jQuery.post( DOKU_BASE + 'lib/exe/ajax.php?call=mediaupload&ow=true&ns=' + ns + '&qqfile=' + id + '§ok=' + JSINFO['sectok'], datastr ) |
50 | | - .done( function() { |
51 | | - jQuery( window ).off( 'message', onmessage ); |
52 | | - jQuery( '#drawio-frame' ).remove(); |
53 | | - setTimeout( function() { |
54 | | - location.reload(); |
55 | | - }, 200 ); |
56 | | - } ).fail( function() { |
57 | | - alert( 'Fehler beim Speichern' ); |
58 | | - } ); |
59 | | - } |
60 | | - } else if( msg.event == 'exit' ) { |
61 | | - jQuery( window ).off( 'message', onmessage ); |
62 | | - jQuery( '#drawio-frame' ).remove(); |
| 42 | + /** |
| 43 | + * Media manager |
| 44 | + * FIXME this should be moved to a separate file |
| 45 | + */ |
| 46 | + |
| 47 | + /* are we in media manager context? */ |
| 48 | + const $mm_page = jQuery('#mediamanager__page'); |
| 49 | + const $mm_popup = jQuery('#media__manager'); |
| 50 | + const isMMPage = $mm_page.length > 0; |
| 51 | + const isMMPopup = $mm_popup.length > 0; |
| 52 | + if (!isMMPage && !isMMPopup) return; |
| 53 | + |
| 54 | + /* in the namespace tree add a link to create a new diagram */ |
| 55 | + const $mm_tree = jQuery("#media__tree"); |
| 56 | + const $createLink = jQuery('<a href="#">' + LANG.plugins.diagrams.createLink + '</a>') |
| 57 | + .on('click', function (e) { |
| 58 | + e.preventDefault(); |
| 59 | + e.stopPropagation(); |
| 60 | + newDiagramForm().dialog({ |
| 61 | + title: LANG.plugins.diagrams.createLink, |
| 62 | + width: 600, |
| 63 | + appendTo: '.dokuwiki', |
| 64 | + modal: true, |
| 65 | + open: function () { |
| 66 | + const ns = isMMPage ? jQuery('.panelHeader h3 strong').text() : jQuery('#media__ns').text(); |
| 67 | + jQuery('#diagrams__current-ns').text(ns); |
| 68 | + }, |
| 69 | + close: function () { |
| 70 | + // do not reuse the dialog |
| 71 | + // https://stackoverflow.com/a/2864783 |
| 72 | + jQuery(this).dialog('destroy').remove(); |
63 | 73 | } |
64 | | - }; |
65 | | - jQuery( window ).on( 'message', onmessage ); |
66 | | - jQuery( '#drawio-frame' ).attr( 'src', drawio_url ); |
67 | | - } |
68 | | - } ); |
| 74 | + }); |
| 75 | + }); |
| 76 | + $mm_tree.prepend($createLink); |
69 | 77 |
|
70 | | - jQuery( 'a#drawio-newfile-create' ).on( 'click', function( e ) { |
71 | | - e.preventDefault(); |
72 | | - var ns = NS; |
73 | | - var id = prompt( 'Name des neuen Diagramms' ); |
74 | | - if( !/^[\w][\w\.\-]*$/.test( id ) ) { |
75 | | - alert( 'Dateiname enthält ungültige Zeichen' ); |
76 | | - return; |
77 | | - } |
78 | | - id += '.svg'; |
79 | | - var datastr = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + |
80 | | - '<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>'; |
81 | | - jQuery.post( DOKU_BASE + 'lib/exe/ajax.php?call=mediaupload&ns=' + ns + '&qqfile=' + id + '§ok=' + JSINFO['sectok'], datastr ) |
82 | | - .done( function( response ) { |
83 | | - if( response.error ) { |
84 | | - alert( 'Fehler beim Speichern: ' + response.error ); |
85 | | - } else { |
86 | | - alert( 'Diagramm ' + response.id + ' angelegt' ); |
| 78 | + // attach edit button to detail view of SVG files |
| 79 | + if (!isMMPage) return; |
| 80 | + $mm_page.on('click', '.panel.filelist .panelContent a', function (e) { |
| 81 | + |
| 82 | + // observe div.file for mutations |
| 83 | + const $df = jQuery('div.file'); |
| 84 | + const targetNode = $df[0]; |
| 85 | + |
| 86 | + // observe the target node descendants |
| 87 | + const config = {childList: true, subtree: true}; |
| 88 | + |
| 89 | + // add edit diagram button to file actions |
| 90 | + const addEditButton = function (mutationsList, observer) { |
| 91 | + for (let mutation of mutationsList) { |
| 92 | + // div.file has been filled with new content (detail view) |
| 93 | + if (mutation.type === 'childList') { |
| 94 | + const $svgLink = jQuery('a.mf_svg'); |
| 95 | + // only add buttons to SVG files |
| 96 | + if ($svgLink.length !== 0) { |
| 97 | + const $actionsList = jQuery('ul.actions'); |
| 98 | + // disconnect now so we don't observe the mutation we are about to trigger |
| 99 | + observer.disconnect(); |
| 100 | + // FIXME why do they multiply when non-svg link is clicked before?!!! |
| 101 | + if ($actionsList.find('button.diagrams-btn').length === 0) { |
| 102 | + $actionsList.append(editDiagramButton($svgLink.html())); |
| 103 | + } |
| 104 | + } |
87 | 105 | } |
88 | | - } ).fail( function() { |
89 | | - alert( 'Fehler beim Speichern' ); |
90 | | - } ); |
91 | | - } ); |
92 | | -} ); |
| 106 | + } |
| 107 | + }; |
| 108 | + |
| 109 | + const observer = new MutationObserver(addEditButton); |
| 110 | + observer.observe(targetNode, config); |
| 111 | + }); |
| 112 | +}); |
0 commit comments