85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
/**
|
|
* A mapping between internal element IDs and DOM element IDs.
|
|
*/
|
|
var private_registry = {};
|
|
|
|
/**
|
|
* Lookup a previously registered custom element.
|
|
*
|
|
* @param {string} element_name The internal element name, previously used to
|
|
* register the element with the private registry.
|
|
*
|
|
* @returns {object|null} The element data in the registry, or null if there is
|
|
* no such element name registered.
|
|
*
|
|
* The returned object will have `name`, `class`, and `internal_name`
|
|
* properties listing the external name, implementing class, and internal name
|
|
* respectively.
|
|
*/
|
|
export function lookup_element(element_name) {
|
|
let data = private_registry[element_name];
|
|
if (data !== undefined) {
|
|
return {
|
|
"internal_name": element_name,
|
|
"name": data.name,
|
|
"class": data.class
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|
|
}
|
|
} |