1<?php 2 3namespace dokuwiki\plugin\prosemirror\schema; 4 5class NodeStack 6{ 7 /** @var Node[] */ 8 protected $stack = []; 9 10 /** @var int index to the top of the stack */ 11 protected $stacklength = -1; 12 13 /** @var Node the root node */ 14 protected $doc; 15 16 /** 17 * NodeStack constructor. 18 */ 19 public function __construct() 20 { 21 $node = new Node('doc'); 22 $this->doc = $node; 23 $this->top($node); 24 } 25 26 /** 27 * @return Node 28 */ 29 public function getDocNode() 30 { 31 return $this->stack[0]; 32 } 33 34 /** 35 * Get the current node (the one at the top of the stack) 36 * 37 * @return Node 38 */ 39 public function current() 40 { 41 return $this->stack[$this->stacklength]; 42 } 43 44 /** 45 * Get the document (top most level) node 46 * 47 * @return Node 48 */ 49 public function doc() 50 { 51 return $this->doc; 52 } 53 54 /** 55 * Make the given node the current one 56 * 57 * @param Node $node 58 */ 59 protected function top(Node $node) 60 { 61 $this->stack[] = $node; 62 $this->stacklength++; 63 } 64 65 /** 66 * Add a new child node to the current node and make it the new current node 67 * 68 * @param Node $node 69 */ 70 public function addTop(Node $node) 71 { 72 $this->add($node); 73 $this->top($node); 74 } 75 76 /** 77 * Pop the current node off the stack 78 * 79 * @param string $type The type of node that is expected. A RuntimeException is thrown if the current nod does not 80 * match 81 * 82 * @return Node 83 */ 84 public function drop($type) 85 { 86 /** @var Node $node */ 87 $node = array_pop($this->stack); 88 $this->stacklength--; 89 if ($node->getType() != $type) { 90 throw new \RuntimeException( 91 "Expected the current node to be of type $type found " . $node->getType() . " instead." 92 ); 93 } 94 return $node; 95 } 96 97 /** 98 * Add a new child node to the current node 99 * 100 * @param Node $node 101 */ 102 public function add(Node $node) 103 { 104 $this->current()->addChild($node); 105 } 106 107 /** 108 * Check if there have been any nodes added to the document 109 */ 110 public function isEmpty() 111 { 112 return !$this->doc->hasContent(); 113 } 114} 115