Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/sdk/makeNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,33 @@ export default ({ sdk, parent = null, attributes: initialAttributes }) => {
onAttributeChange("timezone", tz => updateIntls(tz, getAttribute("locale")))
onAttributeChange("locale", locale => updateIntls(getAttribute("timezone"), locale))

const pauseReasons = new Set()
const computeAggregatePaused = () => {
const blurReason = !getAttribute("autofetchOnWindowBlur") && getAttribute("blurred")
return Boolean(blurReason) || pauseReasons.size > 0
}
const applyAggregatePaused = () => {
updateAttribute("paused", computeAggregatePaused())
}
const addPauseReason = reasonId => {
if (!reasonId) return
pauseReasons.add(reasonId)
applyAggregatePaused()
}
const removePauseReason = reasonId => {
if (!reasonId) return
if (!pauseReasons.delete(reasonId)) return
applyAggregatePaused()
}
onAttributeChange("blurred", applyAggregatePaused)
onAttributeChange("autofetchOnWindowBlur", applyAggregatePaused)

const destroy = () => {
if (parent) parent.removeChild(getId())

listeners.offAll()
attributeListeners.offAll()
pauseReasons.clear()
setTimeout(() => (parent = null), 2000)
destroyIntls()
}
Expand Down Expand Up @@ -220,6 +242,8 @@ export default ({ sdk, parent = null, attributes: initialAttributes }) => {
formatTime,
formatDate,
formatXAxis,
addPauseReason,
removePauseReason,
}

return instance
Expand Down
66 changes: 66 additions & 0 deletions src/sdk/makeNode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,72 @@ describe("makeNode", () => {
})
})

describe("pause reasons", () => {
it("starts with no reasons and paused=false (assuming blur is off)", () => {
expect(node.getAttribute("paused")).toBeUndefined()
})

it("addPauseReason flips paused to true", () => {
node.addPauseReason("hover")
expect(node.getAttribute("paused")).toBe(true)
})

it("removePauseReason after the only reason flips paused back to false", () => {
node.addPauseReason("hover")
node.removePauseReason("hover")
expect(node.getAttribute("paused")).toBe(false)
})

it("composes multiple reasons — removing one keeps paused true while others remain", () => {
node.addPauseReason("hover")
node.addPauseReason("modal")
expect(node.getAttribute("paused")).toBe(true)
node.removePauseReason("hover")
expect(node.getAttribute("paused")).toBe(true)
node.removePauseReason("modal")
expect(node.getAttribute("paused")).toBe(false)
})

it("is idempotent — same reason id added twice acts as one", () => {
node.addPauseReason("hover")
node.addPauseReason("hover")
node.removePauseReason("hover")
expect(node.getAttribute("paused")).toBe(false)
})

it("ignores empty/missing reason ids", () => {
node.addPauseReason("")
node.addPauseReason(null)
node.addPauseReason(undefined)
expect(node.getAttribute("paused")).toBeUndefined()
})

it("recomputes when the blur attributes flip — window blur fires pause without an explicit reason", () => {
node.updateAttribute("autofetchOnWindowBlur", false)
node.updateAttribute("blurred", true)
expect(node.getAttribute("paused")).toBe(true)
node.updateAttribute("blurred", false)
expect(node.getAttribute("paused")).toBe(false)
})

it("blur and explicit reasons combine — un-blurring keeps paused true if a reason is still registered", () => {
node.updateAttribute("autofetchOnWindowBlur", false)
node.updateAttribute("blurred", true)
node.addPauseReason("modal")
expect(node.getAttribute("paused")).toBe(true)
node.updateAttribute("blurred", false)
expect(node.getAttribute("paused")).toBe(true)
node.removePauseReason("modal")
expect(node.getAttribute("paused")).toBe(false)
})

it("autofetchOnWindowBlur=true disables the blur reason — paused stays false while blurred", () => {
node.updateAttribute("autofetchOnWindowBlur", true)
node.updateAttribute("blurred", true)
expect(node.getAttribute("paused")).toBe(false)
})
})

describe("inheritance", () => {
it("inherits parent attributes", () => {
mockParent.getAttributes.mockReturnValue({
Expand Down