1<?php
2
3namespace dokuwiki\plugin\prosemirror\parser;
4
5use dokuwiki\plugin\prosemirror\schema\Mark;
6
7class ImageNode extends Node implements InlineNodeInterface
8{
9    /** @var  Node */
10    protected $parent;
11
12    protected $attrs = [];
13
14    protected $textNode;
15
16    public function __construct($data, Node $parent, Node $previousNode = null)
17    {
18        $this->parent = &$parent;
19        $this->attrs = $data['attrs'];
20
21        // every inline node needs a TextNode to track marks
22        $this->textNode = new TextNode(['marks' => $data['marks'] ?? null], $parent, $previousNode);
23    }
24
25    public function toSyntax()
26    {
27        $title = '';
28        if (!empty($this->attrs['title'])) {
29            $title = '|' . $this->attrs['title'];
30        }
31
32        $leftAlign = '';
33        $rightAlign = '';
34        if (!empty($this->attrs['align'])) {
35            if ($this->attrs['align'] === 'left') {
36                $rightAlign = ' ';
37            } elseif ($this->attrs['align'] === 'right') {
38                $leftAlign = ' ';
39            } elseif ($this->attrs['align'] === 'center') {
40                $leftAlign = ' ';
41                $rightAlign = ' ';
42            }
43        }
44
45        $query = [];
46        if (!empty($this->attrs['height'])) {
47            $query[] = $this->attrs['width'] . 'x' . $this->attrs['height'];
48        } elseif (!empty($this->attrs['width'])) {
49            $query[] = $this->attrs['width'];
50        }
51        if (!empty($this->attrs['linking']) && $this->attrs['linking'] !== 'details') {
52            $query[] = $this->attrs['linking'];
53        }
54        if (!empty($this->attrs['cache']) && $this->attrs['cache'] !== 'cache') {
55            $query[] = $this->attrs['cache'];
56        }
57
58        $queryString = '';
59        if (!empty($query)) {
60            $queryString = '?' . implode('&', $query);
61        }
62
63
64        return '{{' . $leftAlign . $this->attrs['id'] . $queryString . $rightAlign . $title . '}}';
65    }
66
67    public static function render(
68        \renderer_plugin_prosemirror $renderer,
69        $src,
70        $title = null,
71        $align = null,
72        $width = null,
73        $height = null,
74        $cache = null,
75        $linking = null
76    ) {
77        $node = new \dokuwiki\plugin\prosemirror\schema\Node('image');
78
79        self::addAttributes(
80            $node,
81            $src,
82            $title,
83            $align,
84            $width,
85            $height,
86            $cache,
87            $linking
88        );
89
90        foreach (array_keys($renderer->getCurrentMarks()) as $mark) {
91            $node->addMark(new Mark($mark));
92        }
93
94        global $ID;
95        $node->attr(
96            'data-resolvedHtml',
97            self::resolveMedia($src, $title, $align, $width, $height, $cache, $linking)
98        );
99
100        $renderer->addToNodestack($node);
101    }
102
103    public static function addAttributes(
104        \dokuwiki\plugin\prosemirror\schema\Node $node,
105        $src,
106        $title = null,
107        $align = null,
108        $width = null,
109        $height = null,
110        $cache = null,
111        $linking = null,
112        $prefix = ''
113    ) {
114        $node->attr($prefix . 'src', ml($src));
115        $node->attr($prefix . 'title', $title);
116
117        $class = 'media';
118        if ($align === 'right') {
119            $class = 'mediaright';
120        } elseif ($align === 'left') {
121            $class = 'medialeft';
122        } elseif ($align === 'center') {
123            $class = 'mediacenter';
124        }
125
126        if ($cache !== null && $cache === 'cache') {
127            $cache = null;
128        }
129
130        $node->attr($prefix . 'class', $class);
131        $node->attr($prefix . 'align', $align);
132        $node->attr($prefix . 'width', $width);
133        $node->attr($prefix . 'height', $height);
134        $node->attr($prefix . 'id', $src);
135        $node->attr($prefix . 'cache', $cache);
136        $node->attr($prefix . 'linking', $linking);
137    }
138
139    public static function resolveMedia(
140        $src,
141        $title = null,
142        $align = null,
143        $width = null,
144        $height = null,
145        $cache = null,
146        $linking = null
147    ) {
148        $xhtml_renderer = p_get_renderer('xhtml');
149        if (media_isexternal($src) || link_isinterwiki($src)) {
150            $xhtml_renderer->externalmedia(
151                $src,
152                $title ?: $src,
153                $align,
154                $width,
155                $height,
156                $cache,
157                $linking
158            );
159        } else {
160            $xhtml_renderer->internalmedia(
161                $src,
162                $title ?: $src,
163                $align,
164                $width,
165                $height,
166                $cache,
167                $linking
168            );
169        }
170        return $xhtml_renderer->doc;
171    }
172
173    /**
174     * @param string $markType
175     */
176    public function increaseMark($markType)
177    {
178        return $this->textNode->increaseMark($markType);
179    }
180
181    public function getStartingNodeMarkScore($markType)
182    {
183        return $this->textNode->getStartingNodeMarkScore($markType);
184    }
185}
186