xref: /plugin/diagrams/script.js (revision 5b540ddbbc6385991c7c4a2a00a6a337741ea967)
1jQuery( function() {
2    /* DOKUWIKI:include script/helpers.js */
3    /* DOKUWIKI:include script/service.js */
4
5    /**
6     * Launch diagram editor's iframe
7     */
8    const launchEditor = function(event) {
9        const fullId = event.data.fullId;
10        if (!jQuery('#drawio-frame')[0]) {
11            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>');
12            jQuery(window).on('message', {fullId: fullId}, handleServiceMessages);
13            jQuery('#drawio-frame').attr('src', serviceUrl);
14        }
15    };
16
17    // add diagram edit button to all SVGs included in wiki pages
18    if( JSINFO['iseditor'] ) {
19        jQuery( 'img, object' ).filter( '.media, .medialeft, .mediacenter, .mediaright' ).add( 'iframe.svgpureinsert' ).each( function() {
20            const current = jQuery( this );
21            const src = this.nodeName === 'OBJECT' ? current.attr( 'data' ) : current.attr( 'src' );
22            const extension = src.split( '.' ).pop().toLowerCase();
23            if( extension === 'svg' ) {
24                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>';
25                if( current.parent()[0].nodeName === 'A' ) {
26                    current.parent().after( editlink );
27                } else {
28                    current.after( editlink );
29                }
30            }
31        } );
32    }
33
34    // attach diagram editing function to the button rendered on pages
35    jQuery( 'button.drawio-btn' ).on( 'click', function () {
36        const fullId = jQuery( this ).data( 'id' );
37        launchEditor({data: {fullId: fullId}});
38    });
39
40    /**
41     * Launch the editor and create a new diagram
42     *
43     * @param event
44     */
45    function createDiagram(event) {
46        event.preventDefault();
47
48        let href;
49        // get namespace selected in ns tree
50        const $selectedNSLink = jQuery('.idx_dir.selected');
51        if ($selectedNSLink && $selectedNSLink.length > 0) {
52            href = $selectedNSLink.attr('href');
53        } else {
54            // FIXME url rewriting?
55            href = location.href;
56        }
57        const ns = extractNs(href);
58        const id = jQuery('#drawio__create-filename').val();
59
60        if (!validId(id)) {
61            alert('name is empty or contains invalid characters!');
62            return;
63        }
64
65        const fullIdArray = [ns, id];
66        launchEditor({data:{fullId: fullIdArray.join(':') + '.svg'}});
67    }
68
69    /**
70     * returns a diagram creation form as jQuery object
71     *
72     * @returns {jQuery|HTMLElement}
73     */
74    function newDiagramForm() {
75        const currentNs = extractNs(location.href);
76        const $createForm = jQuery(
77            '<form>' +
78            '<p>Create draw.io diagram in current namespace <strong><span id="drawio__current-ns">' +
79            currentNs +
80            '</strong></span></p>' +
81            '<input type="text" name="drawio-create-filename" id="drawio__create-filename" />' +
82            '<button id="drawio__create">Create</button>' +
83            '</form>'
84        );
85
86        jQuery( $createForm ).on( 'submit', createDiagram );
87
88        return $createForm;
89    }
90
91    /**
92     * Full-page media manager
93     */
94    const $mm_page = jQuery('#mediamanager__page');
95    if (!$mm_page.length) return;
96
97    const $mm_tree = jQuery("#media__tree");
98    $mm_tree.prepend(newDiagramForm());
99
100    // update diagram NS when clicking in media tree
101    $mm_tree.find('a.idx_dir').each(function (e) {
102        const $this = jQuery( this );
103        $this.on('click', function (e) {
104            e.preventDefault();
105
106            const $nsSpan = jQuery('#drawio__current-ns');
107            $nsSpan.text(extractNs(e.target));
108        });
109    });
110
111    /**
112     * Returns an edit button with attached click handler that launches the editor
113     *
114     * @param fullId
115     * @returns {jQuery|HTMLElement}
116     */
117    function editDiagramButton(fullId) {
118        const $editButton = jQuery(
119            '<button type="submit" class="drawio-btn" data-id="' +
120            fullId +
121            '">Edit diagram</button>'
122        );
123        jQuery( $editButton ).on( 'click', {fullId: fullId}, launchEditor );
124
125        return $editButton;
126    }
127
128
129
130    // attach edit button to detail view of SVG files
131    $mm_page.on('click', '.panel.filelist .panelContent a', function (e) {
132
133        // observe div.file for mutations
134        const $df = jQuery('div.file');
135        const targetNode = $df[0];
136
137        // observe the target node descendants
138        const config = { childList: true, subtree: true };
139
140        // add edit diagram  button to file actions
141        const addEditButton = function(mutationsList, observer) {
142            for(let mutation of mutationsList) {
143                // div.file has been filled with new content (detail view)
144                if (mutation.type === 'childList') {
145                    const $svgLink = jQuery('a.mf_svg');
146                    // only add buttons to SVG files
147                    if ($svgLink.length !== 0) {
148                        const $actionsList = jQuery('ul.actions');
149                        // disconnect now so we don't observe the mutation we are about to trigger
150                        observer.disconnect();
151                        // FIXME WTF why do they multiply when non-svg link is clicked before?!!!
152                        if ($actionsList.find('button.drawio-btn').length === 0) {
153                            $actionsList.append(editDiagramButton($svgLink.html()));
154                        }
155                    }
156                }
157            }
158        };
159
160        const observer = new MutationObserver(addEditButton);
161        observer.observe(targetNode, config);
162    });
163
164    // TODO pop-up media manager
165} );
166