]> git.proxmox.com Git - mirror_xterm.js.git/blob - src/utils/DomElementObjectPool.ts
Merge branch 'master' into pull_getCoords_into_module
[mirror_xterm.js.git] / src / utils / DomElementObjectPool.ts
1 /**
2 * @module xterm/utils/DomElementObjectPool
3 * @license MIT
4 */
5
6 /**
7 * An object pool that manages acquisition and releasing of DOM elements for
8 * when reuse is desirable.
9 */
10 export class DomElementObjectPool {
11 private static readonly OBJECT_ID_ATTRIBUTE = 'data-obj-id';
12
13 private static _objectCount = 0;
14
15 private _type: string;
16 private _pool: HTMLElement[];
17 private _inUse: {[key: string]: HTMLElement};
18
19 /**
20 * @param type The DOM element type (div, span, etc.).
21 */
22 constructor(private type: string) {
23 this._type = type;
24 this._pool = [];
25 this._inUse = {};
26 }
27
28 /**
29 * Acquire an element from the pool, creating it if the pool is empty.
30 */
31 public acquire(): HTMLElement {
32 let element: HTMLElement;
33 if (this._pool.length === 0) {
34 element = this._createNew();
35 } else {
36 element = this._pool.pop();
37 }
38 this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)] = element;
39 return element;
40 }
41
42 /**
43 * Release an element back into the pool. It's up to the caller of this
44 * function to ensure that all external references to the element have been
45 * removed.
46 * @param element The element being released.
47 */
48 public release(element: HTMLElement): void {
49 if (!this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)]) {
50 throw new Error('Could not release an element not yet acquired');
51 }
52 delete this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)];
53 this._cleanElement(element);
54 this._pool.push(element);
55 }
56
57 /**
58 * Creates a new element for the pool.
59 */
60 private _createNew(): HTMLElement {
61 const element = document.createElement(this._type);
62 const id = DomElementObjectPool._objectCount++;
63 element.setAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE, id.toString(10));
64 return element;
65 }
66
67 /**
68 * Resets an element back to a "clean state".
69 * @param element The element to be cleaned.
70 */
71 private _cleanElement(element: HTMLElement): void {
72 element.className = '';
73 element.innerHTML = '';
74 }
75 }