1<?php
2
3use dokuwiki\plugin\diagrams\parser\DiagramsNode;
4use dokuwiki\plugin\prosemirror\parser\ImageNode;
5use dokuwiki\plugin\prosemirror\schema\Node;
6
7/**
8 * DokuWiki Plugin diagrams (Action Component)
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Anna Dabrowska <dabrowska@cosmocode.de>
12 */
13class action_plugin_diagrams_prosemirror extends \dokuwiki\Extension\ActionPlugin
14{
15
16    /** @inheritDoc */
17    public function register(Doku_Event_Handler $controller)
18    {
19        $controller->register_hook('PROSEMIRROR_RENDER_PLUGIN', 'BEFORE', $this, 'handleRender');
20        $controller->register_hook('PROSEMIRROR_PARSE_UNKNOWN', 'BEFORE', $this, 'handleNode');
21    }
22
23    /**
24     * Event handler for PROSEMIRROR_RENDER_PLUGIN
25     * Renders DokuWiki's instructions into JSON as required by schema
26     *
27     * @param Doku_Event $event Event object
28     * @return void
29     */
30    public function handleRender(Doku_Event $event) {
31        /*
32          $eventData = [
33            'name' => $name,
34            'data' => $data,
35            'state' => $state,
36            'match' => $match,
37            'renderer' => $this,
38        ];*/
39
40        $eventData = $event->data;
41        $imageData = $eventData['data'];
42
43        //check for our data
44        if (
45            $eventData['name'] !== 'diagrams_mediafile' &&
46            $eventData['name'] !== 'diagrams_embed'
47        ) return;
48
49        $event->preventDefault();
50
51        if($eventData['name'] === 'diagrams_mediafile') {
52            $url = $imageData['url'];
53        } else {
54            // we use a data uri that will be loaded in an img tag
55            // this should provide the same amount of security as our CSP but can be interactively
56            // changed during the edit session
57            $url = 'data:image/svg+xml;base64,' . base64_encode($imageData['svg']);
58        }
59
60        $node = new Node('diagrams');
61        $node->attr('type', $eventData['name'] === 'diagrams_mediafile' ? 'mediafile' : 'embed');
62        $node->attr('id', $imageData['src'] ?? ''); // only for mediafile
63        $node->attr('url', $url);
64        $node->attr('title', $imageData['title'] ?? '');
65        $node->attr('width', $imageData['width']);
66        $node->attr('height', $imageData['height']);
67        $node->attr('align', $imageData['align']);
68
69        $event->data['renderer']->addToNodestack($node);
70    }
71
72    /**
73     * Event handler for PROSEMIRROR_PARSE_UNKNOWN
74     * Translate the JSON from Prosemirror back to DokuWiki's syntax
75     *
76     * @param Doku_Event $event
77     * @return void
78     */
79    public function handleNode(Doku_Event $event)
80    {
81        /*
82          $eventData = [
83            'node' => $node,
84            'parent' => $parent,
85            'previous' => $previous,
86            'newNode' => null,
87        ];*/
88
89        // check for our node type
90        if ($event->data['node']['type'] !== 'diagrams') return;
91
92        $event->preventDefault();
93
94        if($event->data['node']['attrs']['type'] === 'mediafile') {
95            $node = new ImageNode($event->data['node'], $event->data['parent']);
96        } else {
97            $node = new DiagramsNode($event->data['node'], $event->data['parent']);
98        }
99
100        $event->data['newNode'] = $node;
101    }
102}
103