/** * Merge another parent node into this node. * @param ParentNode $node */ public function mergeNode(ParentNode $node) { $child = $node->head; while ($child) { $next = $child->next; $this->appendChild($child); $child = $next; } foreach ($node->getChildProperties() as $name => $value) { $this->{$name} = $value; } }
/** * Parse an opening or closing tag. If a closing tag completes an opening tag then add the node * to the tree. * * @param string $tag; */ private function parseTag($tag) { /* * /* Todo: currently only supports single attribute * * Only supports single attributes, perhaps multiple attributes will be added in the * * future */ $closer = $attribute = $hasAttribute = false; if ($tag[0] !== '/') { // Opening tag, get the name and attribute $name = strtok($tag, '='); $attribute = strtok(''); $hasAttribute = $attribute !== false; } else { if (mb_strlen($tag) === 1) { // Closing tag with no name, treat as plain text $this->node->curText->text .= '[/]'; return; } else { // Closing tag $name = mb_substr($tag, 1); $closer = true; } } // Check that an opener exists if ($closer && isset($this->styles[$name])) { if (!empty($k = array_keys($this->nameStack, $name))) { if (isset($this->invalids[$name]) && $this->invalids[$name] > 0) { --$this->invalids[$name]; $this->node->curText->text .= '[' . $tag . ']'; return; } end($k); $idx = current($k); // Attempt to close the node. /** @noinspection PhpUndefinedMethodInspection */ $this->nodeStack[$idx][0]->close(); // Remove the rest of the stack array_splice($this->nodeStack, $idx); array_splice($this->nameStack, $idx); $idx1 = $idx - 1; $this->node = $this->nodeStack[$idx1][0]; $this->nodeStack[$idx1][1] = array_intersect_key($this->invalids, $this->nodeStack[$idx1][1]); $this->invalids =& $this->nodeStack[$idx1][1]; } else { // No opener is in the stack. Treat as plain text and move on. $this->node->curText->text .= '[' . $tag . ']'; } } else { if (isset($this->styles[$name][$hasAttribute])) { if (isset($this->invalids[$name])) { $this->addError('Invalid Tag Placement', '[' . $tag . '] cannot be used within ' . $this->node->getStackInput()); ++$this->invalids[$name]; $this->node->curText->text .= '[' . $tag . ']'; return; } if ($this->styles[$name][$hasAttribute]->parseContent) { $this->nameStack[] = $name; $this->nodeStack[] = [$this->node->addElement($this, $this->styles[$name][$hasAttribute], '[' . $tag . ']', $attribute), array_merge($this->invalids, array_fill_keys($this->styles[$name][$hasAttribute]->noTags, 0))]; $idx = count($this->nodeStack) - 1; $this->node = $this->nodeStack[$idx][0]; $this->invalids =& $this->nodeStack[$idx][1]; } else { $this->parseAsText($this->node->addElement($this, $this->styles[$name][$hasAttribute], '[' . $tag . ']', $attribute), $name); } } else { // All this work and it isn't actually a tag. $this->node->curText->text .= '[' . $tag . ']'; } } }
/** * @inheritdoc */ public function getStackInput() { return $this->parent->getStackInput() . $this->inputs[0]; }