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