diff --git a/src/index.test.ts b/src/index.test.ts index ad1348f..5988490 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -109,4 +109,32 @@ describe('requestDOMPermit', () => { document.body.innerHTML = ''; }); }); + test('should accept an explicit DOM element and generate a unique key', () => { + const el = document.createElement('div'); + el.dataset.key = 'my-custom-key'; + el.dataset.clone = 'true'; + document.head.innerHTML = + ''; + + document.body.appendChild(el); + + const promise = requestDOMPermit(el); + const generatedKey = el.dataset.key; + expect(generatedKey).toMatch(/^my-custom-key-\d+$/); + + const listener = jest.fn(() => { + window.dispatchEvent( + new CustomEvent('decoyActive', { + detail: { key: generatedKey }, + }) + ); + }); + window.addEventListener('decoy', listener); + return promise.then(res => { + expect(listener).toHaveBeenCalled(); + expect(res).toEqual([el]); + document.head.innerHTML = ''; + document.body.innerHTML = ''; + }); + }); }); diff --git a/src/index.ts b/src/index.ts index 5fadbe9..c51bf7a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -99,8 +99,8 @@ export const getApplication = memoize( return isGeneratedBy('PL NEWS WEB') ? APPLICATIONS.PLN : isGeneratedBy('PL CORE') - ? APPLICATIONS.PLC - : null; + ? APPLICATIONS.PLC + : null; } ); @@ -125,8 +125,8 @@ export const getTier = memoize(function _getTier(): TIERS | null { return areAnyPartialsInHostname(['presentation-layer.abc']) ? TIERS.PREVIEW : areAnyPartialsInHostname(['www.abc', 'newsapp.abc']) - ? TIERS.LIVE - : null; + ? TIERS.LIVE + : null; }); // Store references to PL decoy activation requests and granted DOM permits @@ -140,11 +140,11 @@ export const whenDOMReady: Promise = new Promise(resolve => /in/.test(document.readyState) ? setTimeout(advanceAfterReadyStateComplete, 9) : getGeneration() !== GENERATIONS.PL || - PresentationLayerCustomEvents.AH in window - ? resolve() - : window.addEventListener(PresentationLayerCustomEvents.AH, () => - resolve() - ); + PresentationLayerCustomEvents.AH in window + ? resolve() + : window.addEventListener(PresentationLayerCustomEvents.AH, () => + resolve() + ); })() ); @@ -172,11 +172,21 @@ function bindGlobalRevocationHandler() { }); } +/** Counter to create unique keys for requestDomPermit when key not provided */ +let autoKeyIndex = 0; // Allow us to obtain a permit to modify the DOM at various points export function requestDOMPermit( - key: string, + keyOrElement: string | HTMLElement, onRevokeHandler?: () => void ): Promise { + let key: string; + if (typeof keyOrElement === 'string') { + key = keyOrElement; + } else { + const baseKey = keyOrElement.dataset.key || 'auto-key'; + key = `${baseKey}-${autoKeyIndex++}`; + keyOrElement.dataset.key = key; + } return whenDOMReady.then( () => new Promise(resolve => {