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