@primer/live-region-element
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -25,3 +25,3 @@ const Ordering = { | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
var __privateMethod$1 = (obj, member, method) => { | ||
__accessCheck$1(obj, member, "access private method"); | ||
@@ -42,3 +42,3 @@ return method; | ||
__privateGet$1(this, _heap).push(value); | ||
__privateMethod(this, _heapifyUp, heapifyUp_fn).call(this); | ||
__privateMethod$1(this, _heapifyUp, heapifyUp_fn).call(this); | ||
} | ||
@@ -51,3 +51,3 @@ pop() { | ||
} | ||
__privateMethod(this, _heapifyDown, heapifyDown_fn).call(this); | ||
__privateMethod$1(this, _heapifyDown, heapifyDown_fn).call(this); | ||
return item; | ||
@@ -65,3 +65,3 @@ } | ||
__privateGet$1(this, _heap).pop(); | ||
__privateMethod(this, _heapifyDown, heapifyDown_fn).call(this); | ||
__privateMethod$1(this, _heapifyDown, heapifyDown_fn).call(this); | ||
} | ||
@@ -134,44 +134,2 @@ clear() { | ||
function throttle(fn, wait) { | ||
const queue = []; | ||
let timeoutId = null; | ||
function processQueue() { | ||
if (timeoutId !== null) { | ||
return; | ||
} | ||
if (queue.length === 0) { | ||
return; | ||
} | ||
const args = queue.shift(); | ||
if (args === void 0) { | ||
return; | ||
} | ||
fn(...args); | ||
timeoutId = window.setTimeout(() => { | ||
timeoutId = null; | ||
processQueue(); | ||
}, wait); | ||
} | ||
function throttled(...args) { | ||
queue.push(args); | ||
if (timeoutId === null) { | ||
processQueue(); | ||
} | ||
} | ||
throttled.cancel = () => { | ||
if (timeoutId !== null) { | ||
clearTimeout(timeoutId); | ||
timeoutId = null; | ||
} | ||
queue.length = 0; | ||
}; | ||
return throttled; | ||
} | ||
var __defProp = Object.defineProperty; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
var __accessCheck = (obj, member, msg) => { | ||
@@ -195,10 +153,28 @@ if (!member.has(obj)) | ||
}; | ||
var _queue, _timeoutId; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
var _pending, _queue, _timeoutId, _performWork, performWork_fn, _updateContainerWithMessage, updateContainerWithMessage_fn; | ||
const DEFAULT_THROTTLE_DELAY_MS = 500; | ||
class LiveRegionElement extends HTMLElement { | ||
constructor({ waitMs } = {}) { | ||
constructor() { | ||
super(); | ||
__privateAdd(this, _performWork); | ||
__privateAdd(this, _updateContainerWithMessage); | ||
/** | ||
* A flag to indicate if a message has been announced and we are currently | ||
* waiting for the delay to pass before announcing the next message. | ||
*/ | ||
__privateAdd(this, _pending, void 0); | ||
/** | ||
* A priority queue to store messages to be announced by the live region. | ||
*/ | ||
__privateAdd(this, _queue, void 0); | ||
/** | ||
* The id for a timeout being used by the live region to either wait until the | ||
* next message or wait until the delay has passed before announcing the next | ||
* message | ||
*/ | ||
__privateAdd(this, _timeoutId, void 0); | ||
__publicField(this, "updateContainerWithMessage"); | ||
if (!this.shadowRoot) { | ||
@@ -209,2 +185,3 @@ const template2 = getTemplate(); | ||
} | ||
__privateSet(this, _pending, false); | ||
__privateSet(this, _timeoutId, null); | ||
@@ -214,16 +191,18 @@ __privateSet(this, _queue, new MinHeap({ | ||
})); | ||
this.updateContainerWithMessage = throttle((message) => { | ||
const { contents, politeness } = message; | ||
const container = this.shadowRoot?.getElementById(politeness); | ||
if (!container) { | ||
throw new Error(`Unable to find container for message. Expected a container with id="${politeness}"`); | ||
} | ||
if (container.textContent === contents) { | ||
container.textContent = `${contents}\xA0`; | ||
} else { | ||
container.textContent = contents; | ||
} | ||
}, waitMs ?? DEFAULT_THROTTLE_DELAY_MS); | ||
} | ||
/** | ||
* The delay in milliseconds to wait between announcements. This helps to | ||
* prevent announcements getting dropped if multiple are made at the same time. | ||
*/ | ||
get delay() { | ||
const value = this.getAttribute("delay"); | ||
if (value) { | ||
return parseInt(value, 10); | ||
} | ||
return DEFAULT_THROTTLE_DELAY_MS; | ||
} | ||
set delay(value) { | ||
this.setAttribute("delay", `${value}`); | ||
} | ||
/** | ||
* Announce a message using a live region with a corresponding politeness | ||
@@ -234,9 +213,10 @@ * level. | ||
const { delayMs, politeness = "polite" } = options; | ||
const now = Date.now(); | ||
const item = { | ||
politeness, | ||
contents: message, | ||
scheduled: delayMs !== void 0 ? Date.now() + delayMs : "immediate" | ||
scheduled: delayMs !== void 0 ? now + delayMs : now | ||
}; | ||
__privateGet(this, _queue).insert(item); | ||
this.performWork(); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
return () => { | ||
@@ -257,34 +237,2 @@ __privateGet(this, _queue).delete(item); | ||
} | ||
performWork() { | ||
let message = __privateGet(this, _queue).peek(); | ||
if (!message) { | ||
return; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
__privateSet(this, _timeoutId, null); | ||
} | ||
if (message.scheduled === "immediate") { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
this.updateContainerWithMessage(message); | ||
} | ||
this.performWork(); | ||
return; | ||
} | ||
const now = Date.now(); | ||
if (message.scheduled <= now) { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
this.updateContainerWithMessage(message); | ||
} | ||
this.performWork(); | ||
return; | ||
} | ||
const timeout = message.scheduled > now ? message.scheduled - now : 0; | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
this.performWork(); | ||
}, timeout)); | ||
} | ||
getMessage(politeness = "polite") { | ||
@@ -298,3 +246,3 @@ const container = this.shadowRoot?.getElementById(politeness); | ||
/** | ||
* Stop any pending messages from being announced by the live region | ||
* Prevent pending messages from being announced by the live region. | ||
*/ | ||
@@ -306,8 +254,59 @@ clear() { | ||
} | ||
this.updateContainerWithMessage.cancel(); | ||
__privateGet(this, _queue).clear(); | ||
} | ||
} | ||
_pending = new WeakMap(); | ||
_queue = new WeakMap(); | ||
_timeoutId = new WeakMap(); | ||
_performWork = new WeakSet(); | ||
performWork_fn = function() { | ||
if (__privateGet(this, _pending)) { | ||
return; | ||
} | ||
let message = __privateGet(this, _queue).peek(); | ||
if (!message) { | ||
return; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
__privateSet(this, _timeoutId, null); | ||
} | ||
const now = Date.now(); | ||
if (message.scheduled <= now) { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
__privateMethod(this, _updateContainerWithMessage, updateContainerWithMessage_fn).call(this, message); | ||
} | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
return; | ||
} | ||
const timeout = message.scheduled > now ? message.scheduled - now : 0; | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
}, timeout)); | ||
}; | ||
_updateContainerWithMessage = new WeakSet(); | ||
updateContainerWithMessage_fn = function(message) { | ||
__privateSet(this, _pending, true); | ||
const { contents, politeness } = message; | ||
const container = this.shadowRoot?.getElementById(politeness); | ||
if (!container) { | ||
__privateSet(this, _pending, false); | ||
throw new Error(`Unable to find container for message. Expected a container with id="${politeness}"`); | ||
} | ||
if (container.textContent === contents) { | ||
container.textContent = `${contents}\xA0`; | ||
} else { | ||
container.textContent = contents; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
} | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
__privateSet(this, _pending, false); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
}, this.delay)); | ||
}; | ||
function getTextContent(element) { | ||
@@ -351,8 +350,2 @@ let value = ""; | ||
} | ||
if (a.scheduled === "immediate" && b.scheduled !== "immediate") { | ||
return Ordering.Less; | ||
} | ||
if (a.scheduled !== "immediate" && b.scheduled === "immediate") { | ||
return Ordering.Greater; | ||
} | ||
if (a.scheduled < b.scheduled) { | ||
@@ -359,0 +352,0 @@ return Ordering.Less; |
@@ -1,2 +0,1 @@ | ||
import { type Throttle } from './throttle'; | ||
type Politeness = 'polite' | 'assertive'; | ||
@@ -20,7 +19,2 @@ type AnnounceOptions = { | ||
}; | ||
type Message = { | ||
contents: string; | ||
politeness: Politeness; | ||
scheduled: number | 'immediate'; | ||
}; | ||
/** | ||
@@ -32,7 +26,10 @@ * A function to cancel a scheduled message. | ||
#private; | ||
updateContainerWithMessage: Throttle<(message: Message) => void>; | ||
constructor({ waitMs }?: { | ||
waitMs?: number; | ||
}); | ||
constructor(); | ||
/** | ||
* The delay in milliseconds to wait between announcements. This helps to | ||
* prevent announcements getting dropped if multiple are made at the same time. | ||
*/ | ||
get delay(): number; | ||
set delay(value: number); | ||
/** | ||
* Announce a message using a live region with a corresponding politeness | ||
@@ -47,6 +44,5 @@ * level. | ||
announceFromElement(element: HTMLElement, options?: AnnounceOptions): Cancel; | ||
performWork(): void; | ||
getMessage(politeness?: AnnounceOptions['politeness']): string | null; | ||
/** | ||
* Stop any pending messages from being announced by the live region | ||
* Prevent pending messages from being announced by the live region. | ||
*/ | ||
@@ -53,0 +49,0 @@ clear(): void; |
@@ -27,3 +27,3 @@ import { HTMLElement, customElements } from '@lit-labs/ssr-dom-shim'; | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
var __privateMethod$1 = (obj, member, method) => { | ||
__accessCheck$1(obj, member, "access private method"); | ||
@@ -44,3 +44,3 @@ return method; | ||
__privateGet$1(this, _heap).push(value); | ||
__privateMethod(this, _heapifyUp, heapifyUp_fn).call(this); | ||
__privateMethod$1(this, _heapifyUp, heapifyUp_fn).call(this); | ||
} | ||
@@ -53,3 +53,3 @@ pop() { | ||
} | ||
__privateMethod(this, _heapifyDown, heapifyDown_fn).call(this); | ||
__privateMethod$1(this, _heapifyDown, heapifyDown_fn).call(this); | ||
return item; | ||
@@ -67,3 +67,3 @@ } | ||
__privateGet$1(this, _heap).pop(); | ||
__privateMethod(this, _heapifyDown, heapifyDown_fn).call(this); | ||
__privateMethod$1(this, _heapifyDown, heapifyDown_fn).call(this); | ||
} | ||
@@ -136,44 +136,2 @@ clear() { | ||
function throttle(fn, wait) { | ||
const queue = []; | ||
let timeoutId = null; | ||
function processQueue() { | ||
if (timeoutId !== null) { | ||
return; | ||
} | ||
if (queue.length === 0) { | ||
return; | ||
} | ||
const args = queue.shift(); | ||
if (args === void 0) { | ||
return; | ||
} | ||
fn(...args); | ||
timeoutId = window.setTimeout(() => { | ||
timeoutId = null; | ||
processQueue(); | ||
}, wait); | ||
} | ||
function throttled(...args) { | ||
queue.push(args); | ||
if (timeoutId === null) { | ||
processQueue(); | ||
} | ||
} | ||
throttled.cancel = () => { | ||
if (timeoutId !== null) { | ||
clearTimeout(timeoutId); | ||
timeoutId = null; | ||
} | ||
queue.length = 0; | ||
}; | ||
return throttled; | ||
} | ||
var __defProp = Object.defineProperty; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
var __accessCheck = (obj, member, msg) => { | ||
@@ -197,10 +155,28 @@ if (!member.has(obj)) | ||
}; | ||
var _queue, _timeoutId; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
var _pending, _queue, _timeoutId, _performWork, performWork_fn, _updateContainerWithMessage, updateContainerWithMessage_fn; | ||
const DEFAULT_THROTTLE_DELAY_MS = 500; | ||
class LiveRegionElement extends (globalThis.HTMLElement ?? HTMLElement) { | ||
constructor({ waitMs } = {}) { | ||
constructor() { | ||
super(); | ||
__privateAdd(this, _performWork); | ||
__privateAdd(this, _updateContainerWithMessage); | ||
/** | ||
* A flag to indicate if a message has been announced and we are currently | ||
* waiting for the delay to pass before announcing the next message. | ||
*/ | ||
__privateAdd(this, _pending, void 0); | ||
/** | ||
* A priority queue to store messages to be announced by the live region. | ||
*/ | ||
__privateAdd(this, _queue, void 0); | ||
/** | ||
* The id for a timeout being used by the live region to either wait until the | ||
* next message or wait until the delay has passed before announcing the next | ||
* message | ||
*/ | ||
__privateAdd(this, _timeoutId, void 0); | ||
__publicField(this, "updateContainerWithMessage"); | ||
if (!this.shadowRoot) { | ||
@@ -211,2 +187,3 @@ const template2 = getTemplate(); | ||
} | ||
__privateSet(this, _pending, false); | ||
__privateSet(this, _timeoutId, null); | ||
@@ -216,16 +193,18 @@ __privateSet(this, _queue, new MinHeap({ | ||
})); | ||
this.updateContainerWithMessage = throttle((message) => { | ||
const { contents, politeness } = message; | ||
const container = this.shadowRoot?.getElementById(politeness); | ||
if (!container) { | ||
throw new Error(`Unable to find container for message. Expected a container with id="${politeness}"`); | ||
} | ||
if (container.textContent === contents) { | ||
container.textContent = `${contents}\xA0`; | ||
} else { | ||
container.textContent = contents; | ||
} | ||
}, waitMs ?? DEFAULT_THROTTLE_DELAY_MS); | ||
} | ||
/** | ||
* The delay in milliseconds to wait between announcements. This helps to | ||
* prevent announcements getting dropped if multiple are made at the same time. | ||
*/ | ||
get delay() { | ||
const value = this.getAttribute("delay"); | ||
if (value) { | ||
return parseInt(value, 10); | ||
} | ||
return DEFAULT_THROTTLE_DELAY_MS; | ||
} | ||
set delay(value) { | ||
this.setAttribute("delay", `${value}`); | ||
} | ||
/** | ||
* Announce a message using a live region with a corresponding politeness | ||
@@ -236,9 +215,10 @@ * level. | ||
const { delayMs, politeness = "polite" } = options; | ||
const now = Date.now(); | ||
const item = { | ||
politeness, | ||
contents: message, | ||
scheduled: delayMs !== void 0 ? Date.now() + delayMs : "immediate" | ||
scheduled: delayMs !== void 0 ? now + delayMs : now | ||
}; | ||
__privateGet(this, _queue).insert(item); | ||
this.performWork(); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
return () => { | ||
@@ -259,34 +239,2 @@ __privateGet(this, _queue).delete(item); | ||
} | ||
performWork() { | ||
let message = __privateGet(this, _queue).peek(); | ||
if (!message) { | ||
return; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
__privateSet(this, _timeoutId, null); | ||
} | ||
if (message.scheduled === "immediate") { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
this.updateContainerWithMessage(message); | ||
} | ||
this.performWork(); | ||
return; | ||
} | ||
const now = Date.now(); | ||
if (message.scheduled <= now) { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
this.updateContainerWithMessage(message); | ||
} | ||
this.performWork(); | ||
return; | ||
} | ||
const timeout = message.scheduled > now ? message.scheduled - now : 0; | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
this.performWork(); | ||
}, timeout)); | ||
} | ||
getMessage(politeness = "polite") { | ||
@@ -300,3 +248,3 @@ const container = this.shadowRoot?.getElementById(politeness); | ||
/** | ||
* Stop any pending messages from being announced by the live region | ||
* Prevent pending messages from being announced by the live region. | ||
*/ | ||
@@ -308,8 +256,59 @@ clear() { | ||
} | ||
this.updateContainerWithMessage.cancel(); | ||
__privateGet(this, _queue).clear(); | ||
} | ||
} | ||
_pending = new WeakMap(); | ||
_queue = new WeakMap(); | ||
_timeoutId = new WeakMap(); | ||
_performWork = new WeakSet(); | ||
performWork_fn = function() { | ||
if (__privateGet(this, _pending)) { | ||
return; | ||
} | ||
let message = __privateGet(this, _queue).peek(); | ||
if (!message) { | ||
return; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
__privateSet(this, _timeoutId, null); | ||
} | ||
const now = Date.now(); | ||
if (message.scheduled <= now) { | ||
message = __privateGet(this, _queue).pop(); | ||
if (message) { | ||
__privateMethod(this, _updateContainerWithMessage, updateContainerWithMessage_fn).call(this, message); | ||
} | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
return; | ||
} | ||
const timeout = message.scheduled > now ? message.scheduled - now : 0; | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
}, timeout)); | ||
}; | ||
_updateContainerWithMessage = new WeakSet(); | ||
updateContainerWithMessage_fn = function(message) { | ||
__privateSet(this, _pending, true); | ||
const { contents, politeness } = message; | ||
const container = this.shadowRoot?.getElementById(politeness); | ||
if (!container) { | ||
__privateSet(this, _pending, false); | ||
throw new Error(`Unable to find container for message. Expected a container with id="${politeness}"`); | ||
} | ||
if (container.textContent === contents) { | ||
container.textContent = `${contents}\xA0`; | ||
} else { | ||
container.textContent = contents; | ||
} | ||
if (__privateGet(this, _timeoutId) !== null) { | ||
clearTimeout(__privateGet(this, _timeoutId)); | ||
} | ||
__privateSet(this, _timeoutId, window.setTimeout(() => { | ||
__privateSet(this, _timeoutId, null); | ||
__privateSet(this, _pending, false); | ||
__privateMethod(this, _performWork, performWork_fn).call(this); | ||
}, this.delay)); | ||
}; | ||
function getTextContent(element) { | ||
@@ -353,8 +352,2 @@ let value = ""; | ||
} | ||
if (a.scheduled === "immediate" && b.scheduled !== "immediate") { | ||
return Ordering.Less; | ||
} | ||
if (a.scheduled !== "immediate" && b.scheduled === "immediate") { | ||
return Ordering.Greater; | ||
} | ||
if (a.scheduled < b.scheduled) { | ||
@@ -361,0 +354,0 @@ return Ordering.Less; |
{ | ||
"name": "@primer/live-region-element", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"type": "module", | ||
@@ -47,3 +47,3 @@ "main": "./dist/esm/index.js", | ||
"devDependencies": { | ||
"@custom-elements-manifest/analyzer": "^0.9.3", | ||
"@custom-elements-manifest/analyzer": "^0.9.4", | ||
"@rollup/plugin-inject": "^5.0.5", | ||
@@ -50,0 +50,0 @@ "@rollup/plugin-replace": "^5.0.5", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63900
18
1690