xref: /plugin/diagrams/action/prosemirror.php (revision 0ec94f66261066d45d3a211f0fade04069b99b28)
18d8f8b26SAnna Dabrowska<?php
28d8f8b26SAnna Dabrowska
3*0ec94f66SAndreas Gohruse dokuwiki\plugin\diagrams\parser\DiagramsNode;
4*0ec94f66SAndreas 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
44*0ec94f66SAndreas Gohr        if (
45*0ec94f66SAndreas Gohr            $eventData['name'] !== 'diagrams_mediafile' &&
46*0ec94f66SAndreas Gohr            $eventData['name'] !== 'diagrams_embed'
47*0ec94f66SAndreas Gohr        ) return;
488d8f8b26SAnna Dabrowska
498d8f8b26SAnna Dabrowska        $event->preventDefault();
508d8f8b26SAnna Dabrowska
51*0ec94f66SAndreas Gohr        if($eventData['name'] === 'diagrams_mediafile') {
52*0ec94f66SAndreas Gohr            $url = $imageData['url'];
53*0ec94f66SAndreas Gohr        } else {
54*0ec94f66SAndreas Gohr            // we use a data uri that will be loaded in an img tag
55*0ec94f66SAndreas Gohr            // this should provide the same amount of security as our CSP but can be interactively
56*0ec94f66SAndreas Gohr            // changed during the edit session
57*0ec94f66SAndreas Gohr            $url = 'data:image/svg+xml;base64,' . base64_encode($imageData['svg']);
58*0ec94f66SAndreas Gohr        }
59*0ec94f66SAndreas Gohr
608d8f8b26SAnna Dabrowska        $node = new Node('diagrams');
61*0ec94f66SAndreas Gohr        $node->attr('type', $eventData['name'] === 'diagrams_mediafile' ? 'mediafile' : 'embed');
62*0ec94f66SAndreas Gohr        $node->attr('id', $imageData['src'] ?? ''); // only for mediafile
63*0ec94f66SAndreas Gohr        $node->attr('data', $url); // FIXME rename to url here, in schema and everywhere
64*0ec94f66SAndreas 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
94*0ec94f66SAndreas Gohr        // FIXME for embedded mode we need a more custom node
95*0ec94f66SAndreas Gohr
96*0ec94f66SAndreas Gohr        if($event->data['node']['attrs']['type'] === 'mediafile') {
97*0ec94f66SAndreas Gohr            $node = new ImageNode($event->data['node'], $event->data['parent']);
98*0ec94f66SAndreas Gohr        } else {
99*0ec94f66SAndreas Gohr            $node = new DiagramsNode($event->data['node'], $event->data['parent']);
100*0ec94f66SAndreas Gohr        }
101*0ec94f66SAndreas Gohr
102*0ec94f66SAndreas Gohr
1038d8f8b26SAnna Dabrowska        $event->data['newNode'] = $node;
1048d8f8b26SAnna Dabrowska    }
1058d8f8b26SAnna Dabrowska}
106