1<?php 2 3namespace dokuwiki\plugin\prosemirror\parser; 4 5use dokuwiki\Extension\Event; 6use dokuwiki\plugin\prosemirror\ProsemirrorException; 7 8abstract class Node implements NodeInterface 9{ 10 private static $nodeclass = [ 11 'text' => TextNode::class, 12 'paragraph' => ParagraphNode::class, 13 'list_paragraph' => ParagraphNode::class, 14 'bullet_list' => ListNode::class, 15 'ordered_list' => ListNode::class, 16 'heading' => HeadingNode::class, 17 'preformatted' => PreformattedNode::class, 18 'code_block' => CodeBlockNode::class, 19 'blockquote' => QuoteNode::class, 20 'image' => ImageNode::class, 21 'hard_break' => HardBreakNode::class, 22 'horizontal_rule' => HruleNode::class, 23 'footnote' => FootnoteNode::class, 24 'smiley' => SmileyNode::class, 25 'table' => TableNode::class, 26 'table_row' => TableRowNode::class, 27 'table_cell' => TableCellNode::class, 28 'table_header' => TableCellNode::class, 29 'rss' => RSSNode::class, 30 'dwplugin_inline' => PluginNode::class, 31 'dwplugin_block' => PluginNode::class, 32 ]; 33 34 private static $linkClasses = [ 35 'interwikilink' => InterwikiLinkNode::class, 36 'internallink' => InternalLinkNode::class, 37 'emaillink' => EmailLinkNode::class, 38 'externallink' => ExternalLinkNode::class, 39 'windowssharelink' => WindowsShareLinkNode::class, 40 'other' => ExternalLinkNode::class, 41 ]; 42 43 /** 44 * Get a Node instance of the correct type 45 * 46 * @param array $node 47 * @param Node $parent 48 * @param Node|null $previous 49 * 50 * @return Node 51 */ 52 public static function getSubNode($node, Node $parent, Node $previous = null) 53 { 54 try { 55 if ($node['type'] === 'link') { 56 $linkType = $node['attrs']['data-type']; 57 return new self::$linkClasses[$linkType]($node, $parent, $previous); 58 } 59 60 if (isset(self::$nodeclass[$node['type']])) { 61 return new self::$nodeclass[$node['type']]($node, $parent, $previous); 62 } 63 $eventData = [ 64 'node' => $node, 65 'parent' => $parent, 66 'previous' => $previous, 67 'newNode' => null, 68 ]; 69 $event = new Event('PROSEMIRROR_PARSE_UNKNOWN', $eventData); 70 if ($event->advise_before() || !is_a($eventData['newNode'], self::class)) { 71 $exception = new ProsemirrorException('Invalid node type received: ' . $node['type'], 0); 72 $exception->addExtraData('nodeData', $node); 73 $exception->addExtraData('parentNodeType', get_class($parent)); 74 75 throw $exception; 76 } 77 return $eventData['newNode']; 78 } catch (\Error $e) { 79 $exception = new ProsemirrorException( 80 'FIXME: better message for general error! Invalid node type received: ' . $node['type'], 81 0, 82 $e 83 ); 84 $exception->addExtraData('nodeData', $node); 85 $exception->addExtraData('parentNodeType', get_class($parent)); 86 87 throw $exception; 88 } 89 } 90 91 /** 92 * Get the node's representation as DokuWiki Syntax 93 * 94 * @return string 95 */ 96 abstract public function toSyntax(); 97} 98