59 lines
1.9 KiB
JavaScript
59 lines
1.9 KiB
JavaScript
/**
|
|
* A mapping between internal element IDs and DOM element IDs.
|
|
*/
|
|
var private_registry = {};
|
|
|
|
/**
|
|
* Register a custom element.
|
|
*
|
|
* This function is designed to be tolerant of naming conflicts. If
|
|
* registration fails, we modify the name, and try again. As a result, this
|
|
* function returns the real element name to use.
|
|
*
|
|
* Calling this function multiple times will *not* register multiple elements.
|
|
* We store a private registry mapping internal element names to DOM names.
|
|
* Thus, the proper way to use this function is to call it every time you are
|
|
* about to work with custom element names.
|
|
*
|
|
* @param {string} element_name The internal name of the element.
|
|
* @param {function} element_class The class of the element.
|
|
*
|
|
* You must call this function with the same class every time.
|
|
*
|
|
* @returns {string} The actual element name.
|
|
* @throws Throws an error if two different elements were registered with the
|
|
* same internal name.
|
|
*/
|
|
export function register_element(element_name, element_class) {
|
|
if (private_registry[element_name] !== undefined) {
|
|
if (private_registry[element_name].class !== element_class) {
|
|
throw new Error("Internal naming conflict on " + element_name);
|
|
} else {
|
|
return private_registry[element_name].name;
|
|
}
|
|
}
|
|
|
|
let tries = 0;
|
|
|
|
while (true) {
|
|
try {
|
|
let external_name = element_name;
|
|
if (tries > 0) {
|
|
external_name = external_name + "-" + tries;
|
|
}
|
|
|
|
window.customElements.define(external_name, element_class);
|
|
private_registry[element_name] = {
|
|
"class": element_class,
|
|
"name": external_name,
|
|
"internal_name": element_name
|
|
};
|
|
|
|
return external_name;
|
|
} catch (e) {
|
|
if (e instanceof NotSupportedError) {
|
|
tries += 1;
|
|
}
|
|
}
|
|
}
|
|
} |