import HTMLElement from '../html-element/HTMLElement.js';
import INode from '../node/INode.js';
import IHTMLElement from '../html-element/IHTMLElement.js';
import INodeList from '../node/INodeList.js';
import IHTMLCollection from '../element/IHTMLCollection.js';
import IElement from '../element/IElement.js';
import NodeList from '../node/NodeList.js';
import HTMLCollection from '../element/HTMLCollection.js';
/**
* HTML Unknown Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLUnknownElement.
*/
export default class HTMLUnknownElement extends HTMLElement implements IHTMLElement {
private _customElementDefineCallback: () => void = null;
/**
* Connects this element to another element.
*
* @param parentNode Parent node.
*/
public _connectToNode(parentNode: INode = null): void {
const tagName = this.tagName;
// This element can potentially be a custom element that has not been defined yet
// Therefore we need to register a callback for when it is defined in CustomElementRegistry and replace it with the registered element (see #404)
if (tagName.includes('-')) {
const callbacks = this.ownerDocument.defaultView.customElements._callbacks;
if (parentNode && !this._customElementDefineCallback) {
const callback = (): void => {
if (this.parentNode) {
const newElement = this.ownerDocument.createElement(tagName);
(>newElement.childNodes) = this.childNodes;
(>newElement.children) = this.children;
(newElement.isConnected) = this.isConnected;
newElement._rootNode = this._rootNode;
newElement._formNode = this._formNode;
newElement._selectNode = this._selectNode;
newElement._textAreaNode = this._textAreaNode;
newElement._observers = this._observers;
newElement._isValue = this._isValue;
newElement._attributes = this._attributes;
(>this.childNodes) = new NodeList();
(>this.children) = new HTMLCollection();
this._rootNode = null;
this._formNode = null;
this._selectNode = null;
this._textAreaNode = null;
this._observers = [];
this._isValue = null;
this._attributes = {};
for (let i = 0, max = this.parentNode.childNodes.length; i < max; i++) {
if (this.parentNode.childNodes[i] === this) {
this.parentNode.childNodes[i] = newElement;
break;
}
}
if ((this.parentNode).children) {
for (let i = 0, max = (this.parentNode).children.length; i < max; i++) {
if ((this.parentNode).children[i] === this) {
(this.parentNode).children[i] = newElement;
break;
}
}
}
if (newElement.isConnected && newElement.connectedCallback) {
newElement.connectedCallback();
}
}
};
callbacks[tagName] = callbacks[tagName] || [];
callbacks[tagName].push(callback);
this._customElementDefineCallback = callback;
} else if (!parentNode && callbacks[tagName] && this._customElementDefineCallback) {
const index = callbacks[tagName].indexOf(this._customElementDefineCallback);
if (index !== -1) {
callbacks[tagName].splice(index, 1);
}
if (!callbacks[tagName].length) {
delete callbacks[tagName];
}
this._customElementDefineCallback = null;
}
}
super._connectToNode(parentNode);
}
}