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