3 namespace Drupal\embed;
5 use Drupal\Component\Utility\Html;
8 * Wrapper methods for manipulating DOM entries.
10 * This utility trait should only be used in application-level code, such as
11 * classes that would implement ContainerInjectionInterface. Services registered
12 * in the Container should not use this trait but inject the appropriate service
13 * directly for easier testing.
15 trait DomHelperTrait {
18 * Rename a DOMNode tag.
20 * @param \DOMNode $node
21 * A DOMElement object.
25 protected function changeNodeName(\DOMNode &$node, $name = 'div') {
26 if ($node->nodeName != $name) {
27 /** @var \DOMElement $replacement_node */
28 $replacement_node = $node->ownerDocument->createElement($name);
30 // Copy all children of the original node to the new node.
31 if ($node->childNodes->length) {
32 foreach ($node->childNodes as $child) {
33 $child = $replacement_node->ownerDocument->importNode($child, TRUE);
34 $replacement_node->appendChild($child);
38 // Copy all attributes of the original node to the new node.
39 if ($node->attributes->length) {
40 foreach ($node->attributes as $attribute) {
41 $replacement_node->setAttribute($attribute->nodeName, $attribute->nodeValue);
45 $node->parentNode->replaceChild($replacement_node, $node);
46 $node = $replacement_node;
51 * Set the contents of a DOMNode.
53 * @param \DOMNode $node
55 * @param string $content
56 * The text or HTML that will replace the contents of $node.
58 protected function setNodeContent(\DOMNode $node, $content) {
59 // Remove all children of the DOMNode.
60 while ($node->hasChildNodes()) {
61 $node->removeChild($node->firstChild);
64 if (strlen($content)) {
65 // Load the contents into a new DOMDocument and retrieve the elements.
66 $replacement_nodes = Html::load($content)->getElementsByTagName('body')->item(0);
68 // Finally, import and append the contents to the original node.
69 foreach ($replacement_nodes->childNodes as $replacement_node) {
70 $replacement_node = $node->ownerDocument->importNode($replacement_node, TRUE);
71 $node->appendChild($replacement_node);
77 * Replace the contents of a DOMNode.
79 * @param \DOMNode $node
81 * @param string $content
82 * The text or HTML that will replace the contents of $node.
84 protected function replaceNodeContent(\DOMNode &$node, $content) {
85 if (strlen($content)) {
86 // Load the content into a new DOMDocument and retrieve the DOM nodes.
87 $replacement_nodes = Html::load($content)->getElementsByTagName('body')
92 $replacement_nodes = [$node->ownerDocument->createTextNode('')];
95 foreach ($replacement_nodes as $replacement_node) {
96 // Import the replacement node from the new DOMDocument into the original
97 // one, importing also the child nodes of the replacement node.
98 $replacement_node = $node->ownerDocument->importNode($replacement_node, TRUE);
99 $node->parentNode->insertBefore($replacement_node, $node);
101 $node->parentNode->removeChild($node);
105 * Convert the attributes on a DOMNode object to an array.
107 * This will also un-serialize any attribute values stored as JSON.
109 * @param \DOMNode $node
113 * The attributes as an associative array, keyed by the attribute names.
115 public function getNodeAttributesAsArray(\DOMNode $node) {
118 // Convert the data attributes to the context array.
119 foreach ($node->attributes as $attribute) {
120 $key = $attribute->nodeName;
121 $return[$key] = $attribute->nodeValue;
123 // Check for JSON-encoded attributes.
124 $data = json_decode($return[$key], TRUE, 10);
125 if ($data !== NULL && json_last_error() === JSON_ERROR_NONE) {
126 $return[$key] = $data;