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