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