xref: /plugin/diagrams/action/prosemirror.php (revision c949f2b3d2e6bcf98af329b2afe42b867baa2bf6)
18d8f8b26SAnna Dabrowska<?php
28d8f8b26SAnna Dabrowska
30ec94f66SAndreas Gohruse dokuwiki\plugin\diagrams\parser\DiagramsNode;
40ec94f66SAndreas Gohruse dokuwiki\plugin\prosemirror\parser\ImageNode;
58d8f8b26SAnna Dabrowskause dokuwiki\plugin\prosemirror\schema\Node;
68d8f8b26SAnna Dabrowska
78d8f8b26SAnna Dabrowska/**
88d8f8b26SAnna Dabrowska * DokuWiki Plugin diagrams (Action Component)
98d8f8b26SAnna Dabrowska *
108d8f8b26SAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
118d8f8b26SAnna Dabrowska * @author  Anna Dabrowska <dabrowska@cosmocode.de>
128d8f8b26SAnna Dabrowska */
138d8f8b26SAnna Dabrowskaclass action_plugin_diagrams_prosemirror extends \dokuwiki\Extension\ActionPlugin
148d8f8b26SAnna Dabrowska{
158d8f8b26SAnna Dabrowska
168d8f8b26SAnna Dabrowska    /** @inheritDoc */
178d8f8b26SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
188d8f8b26SAnna Dabrowska    {
198d8f8b26SAnna Dabrowska        $controller->register_hook('PROSEMIRROR_RENDER_PLUGIN', 'BEFORE', $this, 'handleRender');
208d8f8b26SAnna Dabrowska        $controller->register_hook('PROSEMIRROR_PARSE_UNKNOWN', 'BEFORE', $this, 'handleNode');
218d8f8b26SAnna Dabrowska    }
228d8f8b26SAnna Dabrowska
238d8f8b26SAnna Dabrowska    /**
248d8f8b26SAnna Dabrowska     * Event handler for PROSEMIRROR_RENDER_PLUGIN
258d8f8b26SAnna Dabrowska     * Renders DokuWiki's instructions into JSON as required by schema
268d8f8b26SAnna Dabrowska     *
278d8f8b26SAnna Dabrowska     * @param Doku_Event $event Event object
288d8f8b26SAnna Dabrowska     * @return void
298d8f8b26SAnna Dabrowska     */
308d8f8b26SAnna Dabrowska    public function handleRender(Doku_Event $event) {
318d8f8b26SAnna Dabrowska        /*
328d8f8b26SAnna Dabrowska          $eventData = [
338d8f8b26SAnna Dabrowska            'name' => $name,
348d8f8b26SAnna Dabrowska            'data' => $data,
358d8f8b26SAnna Dabrowska            'state' => $state,
368d8f8b26SAnna Dabrowska            'match' => $match,
378d8f8b26SAnna Dabrowska            'renderer' => $this,
388d8f8b26SAnna Dabrowska        ];*/
398d8f8b26SAnna Dabrowska
408d8f8b26SAnna Dabrowska        $eventData = $event->data;
418d8f8b26SAnna Dabrowska        $imageData = $eventData['data'];
428d8f8b26SAnna Dabrowska
438d8f8b26SAnna Dabrowska        //check for our data
440ec94f66SAndreas Gohr        if (
450ec94f66SAndreas Gohr            $eventData['name'] !== 'diagrams_mediafile' &&
460ec94f66SAndreas Gohr            $eventData['name'] !== 'diagrams_embed'
470ec94f66SAndreas Gohr        ) return;
488d8f8b26SAnna Dabrowska
498d8f8b26SAnna Dabrowska        $event->preventDefault();
508d8f8b26SAnna Dabrowska
510ec94f66SAndreas Gohr        if($eventData['name'] === 'diagrams_mediafile') {
520ec94f66SAndreas Gohr            $url = $imageData['url'];
530ec94f66SAndreas Gohr        } else {
540ec94f66SAndreas Gohr            // we use a data uri that will be loaded in an img tag
550ec94f66SAndreas Gohr            // this should provide the same amount of security as our CSP but can be interactively
560ec94f66SAndreas Gohr            // changed during the edit session
570ec94f66SAndreas Gohr            $url = 'data:image/svg+xml;base64,' . base64_encode($imageData['svg']);
580ec94f66SAndreas Gohr        }
590ec94f66SAndreas Gohr
608d8f8b26SAnna Dabrowska        $node = new Node('diagrams');
610ec94f66SAndreas Gohr        $node->attr('type', $eventData['name'] === 'diagrams_mediafile' ? 'mediafile' : 'embed');
620ec94f66SAndreas Gohr        $node->attr('id', $imageData['src'] ?? ''); // only for mediafile
63*3d6886fdSAndreas Gohr        $node->attr('url', $url);
640ec94f66SAndreas Gohr        $node->attr('title', $imageData['title'] ?? '');
658d8f8b26SAnna Dabrowska        $node->attr('width', $imageData['width']);
668d8f8b26SAnna Dabrowska        $node->attr('height', $imageData['height']);
678d8f8b26SAnna Dabrowska        $node->attr('align', $imageData['align']);
688d8f8b26SAnna Dabrowska
698d8f8b26SAnna Dabrowska        $event->data['renderer']->addToNodestack($node);
708d8f8b26SAnna Dabrowska    }
718d8f8b26SAnna Dabrowska
728d8f8b26SAnna Dabrowska    /**
738d8f8b26SAnna Dabrowska     * Event handler for PROSEMIRROR_PARSE_UNKNOWN
748d8f8b26SAnna Dabrowska     * Translate the JSON from Prosemirror back to DokuWiki's syntax
758d8f8b26SAnna Dabrowska     *
768d8f8b26SAnna Dabrowska     * @param Doku_Event $event
778d8f8b26SAnna Dabrowska     * @return void
788d8f8b26SAnna Dabrowska     */
798d8f8b26SAnna Dabrowska    public function handleNode(Doku_Event $event)
808d8f8b26SAnna Dabrowska    {
818d8f8b26SAnna Dabrowska        /*
828d8f8b26SAnna Dabrowska          $eventData = [
838d8f8b26SAnna Dabrowska            'node' => $node,
848d8f8b26SAnna Dabrowska            'parent' => $parent,
858d8f8b26SAnna Dabrowska            'previous' => $previous,
868d8f8b26SAnna Dabrowska            'newNode' => null,
878d8f8b26SAnna Dabrowska        ];*/
888d8f8b26SAnna Dabrowska
898d8f8b26SAnna Dabrowska        // check for our node type
908d8f8b26SAnna Dabrowska        if ($event->data['node']['type'] !== 'diagrams') return;
918d8f8b26SAnna Dabrowska
928d8f8b26SAnna Dabrowska        $event->preventDefault();
938d8f8b26SAnna Dabrowska
940ec94f66SAndreas Gohr        if($event->data['node']['attrs']['type'] === 'mediafile') {
950ec94f66SAndreas Gohr            $node = new ImageNode($event->data['node'], $event->data['parent']);
960ec94f66SAndreas Gohr        } else {
970ec94f66SAndreas Gohr            $node = new DiagramsNode($event->data['node'], $event->data['parent']);
980ec94f66SAndreas Gohr        }
990ec94f66SAndreas Gohr
1008d8f8b26SAnna Dabrowska        $event->data['newNode'] = $node;
1018d8f8b26SAnna Dabrowska    }
1028d8f8b26SAnna Dabrowska}
103