You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.9 KiB
96 lines
2.9 KiB
<?php
|
|
/**
|
|
* @license MIT
|
|
* Copyright 2017 Dustin Wilson, J. King et al.
|
|
* See LICENSE and AUTHORS files for details
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
namespace MensBeam\HTML\DOM;
|
|
|
|
// This is a map of elements which need to be kept in memory; it exists because
|
|
// of the peculiar way PHP works. Derived DOM classes (such as
|
|
// HTMLTemplateElement) won't remain as such in the DOM (meaning they will
|
|
// revert to being what is registered for elements in Document) unless at least
|
|
// one reference is kept for the element somewhere in userspace. This is that
|
|
// somewhere.
|
|
class ElementMap {
|
|
// List of documents is necessary because when Document objects are destructed
|
|
// it's not possible to check for a document's existence without triggering a
|
|
// fatal error. Keeping document references around fixes that.
|
|
protected static array $documents = [];
|
|
protected static array $elements = [];
|
|
|
|
|
|
public static function add(Element $element): bool {
|
|
$document = $element->ownerDocument;
|
|
$index = self::index($document);
|
|
if ($index === -1) {
|
|
self::$documents[] = $document;
|
|
self::$elements[count(self::$documents) - 1][] = $element;
|
|
return true;
|
|
}
|
|
|
|
foreach (self::$elements[$index] as $v) {
|
|
if ($v === $element) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
self::$elements[$index][] = $element;
|
|
return true;
|
|
}
|
|
|
|
public static function delete(Element $element): bool {
|
|
$document = $element->ownerDocument;
|
|
$index = self::index($document);
|
|
if ($index !== -1) {
|
|
foreach (self::$elements[$index] as $k => $v) {
|
|
if ($v === $element) {
|
|
unset(self::$elements[$index][$k]);
|
|
self::$elements[$index] = array_values(self::$elements[$index]);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function destroy(Document $document): bool {
|
|
$index = self::index($document);
|
|
if ($index !== -1) {
|
|
unset(self::$documents[$index]);
|
|
unset(self::$elements[$index]);
|
|
self::$documents = array_values(self::$documents);
|
|
self::$elements = array_values(self::$elements);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function has(Element $element): bool {
|
|
$document = $element->ownerDocument;
|
|
$index = self::index($document);
|
|
if ($index !== -1) {
|
|
foreach (self::$elements[$index] as $v) {
|
|
if ($v === $element) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected static function index(Document $document): int {
|
|
foreach (self::$documents as $k => $d) {
|
|
if ($d === $document) {
|
|
return $k;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
|