1<?php
2
3namespace dokuwiki\plugin\prosemirror\parser;
4
5use dokuwiki\File\MediaResolver;
6
7abstract class LinkNode extends Node implements InlineNodeInterface
8{
9
10
11    /** @var  InlineNodeInterface */
12    public $previous = null;
13
14    /** @var  Node */
15    protected $parent;
16
17    /** @var TextNode */
18    protected $textNode = null;
19
20    protected $attrs = [];
21
22    public function __construct($data, Node $parent, Node $previousNode = null)
23    {
24        $this->parent = &$parent;
25        if ($previousNode !== false) {
26            $this->previous = &$previousNode;
27        }
28
29        $this->attrs = $data['attrs'];
30
31        // every inline node needs a TextNode to track marks
32        $this->textNode = new TextNode(['marks' => $data['marks'] ?? null], $parent, $previousNode);
33    }
34
35
36    /**
37     * @param string $markType
38     */
39    public function increaseMark($markType)
40    {
41        return $this->textNode->increaseMark($markType);
42    }
43
44    public function getStartingNodeMarkScore($markType)
45    {
46        return $this->textNode->getStartingNodeMarkScore($markType);
47    }
48
49    protected function getDefaultLinkSyntax($inner)
50    {
51        $title = '';
52        $prefix = $this->textNode->getPrefixSyntax();
53        $postfix = $this->textNode->getPostfixSyntax();
54
55        if (!empty($this->attrs['data-name'])) {
56            $title = '|' . $this->attrs['data-name'];
57        } elseif (!empty($this->attrs['image-id'])) {
58            $imageAttrs = [];
59            foreach ($this->attrs as $key => $value) {
60                @list ($keyPrefix, $attrKey) = explode('-', $key, 2);
61                if ($keyPrefix === 'image') {
62                    $imageAttrs[$attrKey] = $value;
63                }
64            }
65            $imageNode = new ImageNode([
66                'attrs' => $imageAttrs,
67                'marks' => [],
68            ], $this);
69            $title = '|' . $imageNode->toSyntax();
70        }
71
72        return $prefix . '[[' . $inner . $title . ']]' . $postfix;
73    }
74
75    /**
76     * @param \renderer_plugin_prosemirror $renderer
77     * @param string                       $linktype
78     * @param string|array                 $name
79     * @param array                        $additionalAttributes
80     */
81    protected static function renderToJSON(
82        \renderer_plugin_prosemirror $renderer,
83        $linktype,
84        $inner,
85        $name,
86        $additionalAttributes = []
87    ) {
88        global $ID;
89        $isImage = is_array($name);
90        $linkNode = new \dokuwiki\plugin\prosemirror\schema\Node('link');
91        $linkNode->attr('data-type', $linktype);
92        $linkNode->attr('data-inner', $inner);
93        if ($isImage) {
94            ImageNode::addAttributes(
95                $linkNode,
96                $name['src'],
97                $name['title'],
98                $name['align'],
99                $name['width'],
100                $name['height'],
101                $name['cache'],
102                null,
103                'image-'
104            );
105            $linkNode->attr('data-resolvedImage', self::resolveImageTitle(
106                $ID,
107                $name['src'],
108                $name['title'],
109                $name['align'],
110                $name['width'],
111                $name['height'],
112                $name['cache']
113            ));
114        } else {
115            $linkNode->attr('data-name', $name);
116        }
117        foreach ($additionalAttributes as $attributeName => $attributeValue) {
118            $linkNode->attr($attributeName, $attributeValue);
119        }
120        foreach (array_keys($renderer->getCurrentMarks()) as $mark) {
121            $linkNode->addMark(new \dokuwiki\plugin\prosemirror\schema\Mark($mark));
122        }
123        $renderer->addToNodestack($linkNode);
124    }
125
126    public static function resolveImageTitle($pageId, $imageId, $title = null, $align = null, $width = null,
127        $height = null, $cache = null)
128    {
129        /** @var \Doku_Renderer_xhtml $xhtml_renderer */
130        $xhtml_renderer = p_get_renderer('xhtml');
131        $src = $imageId;
132        if (!media_isexternal($src)) {
133            $resolver = new MediaResolver(getNS($pageId));
134            $media = $resolver->resolveId($src);
135            if (!media_exists($media)) {
136                return '';
137            }
138        }
139        return $xhtml_renderer->_media(
140            $src,
141            $title ?: $imageId,
142            $align,
143            $width,
144            $height,
145            $cache
146        );
147    }
148}
149