fix: handle null activeElement in _spaceCatcher AND fix: guard _moveManual and _ariaChecked against dom-repeat race AND MORE#51
Conversation
WalkthroughIterate and initialize slider dots using actual rendered dot elements; replace per-dot click handlers with a single delegated listener stored on the component; use shadowRoot.activeElement safely for keyboard activation, and remove the delegated listener on detach. ChangesDot navigation & keyboard handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js (1)
372-380:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
_ariaChecked: out-of-bounds access whenthis.position >= dotElems.lengthThe guard
if (dotElems.length > 0)only ensures at least one dot exists, but Line 378 still unconditionally accessesdotElems[this.position]. During a dom-repeat race (which is exactly what this PR aims to fix),this.positioncan be greater than the number of rendered dots, causing an uncaughtTypeError: Cannot read properties of undefined.🛡️ Proposed fix
_ariaChecked: function () { var dotElems = this.$.container.querySelectorAll('.slider__dot'); - if (dotElems.length > 0) { + if (dotElems.length > 0 && this.position < dotElems.length) { for (var i = 0; i < dotElems.length; i++) { dotElems[i].setAttribute("aria-checked", "false"); }; dotElems[this.position].setAttribute("aria-checked", "true"); } },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js` around lines 372 - 380, The _ariaChecked method can access dotElems[this.position] out of bounds if this.position >= dotElems.length; update _ariaChecked to verify bounds before accessing or setting the "true" attribute (e.g., check this.position !== undefined && this.position >= 0 && this.position < dotElems.length or clamp this.position to dotElems.length - 1) after you clear all dots; specifically modify the _ariaChecked function to only call dotElems[this.position].setAttribute when the index is valid to avoid the TypeError during dom-repeat races.
🧹 Nitpick comments (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js (1)
375-377: 💤 Low valueSonarCloud warning: prefer
for…ofover index-basedforloopSonarCloud flags Lines 375-377 for using a
forloop with a simple sequential iteration wherefor…ofis idiomatic.♻️ Proposed refactor
- for (var i = 0; i < dotElems.length; i++) { - dotElems[i].setAttribute("aria-checked", "false"); - }; - dotElems[this.position].setAttribute("aria-checked", "true"); + for (const dot of dotElems) { + dot.setAttribute("aria-checked", "false"); + } + dotElems[this.position].setAttribute("aria-checked", "true");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js` around lines 375 - 377, Replace the index-based loop that clears aria-checked on dotElems with a for...of iteration: locate the loop iterating over dotElems (the block starting with "for (var i = 0; i < dotElems.length; i++)" in l2t-paper-slider.js) and change it to use "for (const dotElem of dotElems) { dotElem.setAttribute('aria-checked', 'false'); }" so the code uses the idiomatic for…of construct while preserving the same behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js`:
- Around line 541-550: The _spaceCatcher function uses a legacy var and a raw
parseInt which SonarCloud flags; update the function to declare nextPos with
const or let (prefer const when not reassigned) and call parseInt with an
explicit radix (e.g., parseInt(nextPos, 10)) or use Number(nextPos) to convert,
and keep the existing logic that calls this.movePos(parseInt(nextPos, 10) - 1)
when shadowRoot.activeElement has an aria-posinset, otherwise
this.movePos((this.position + 1) % this.totalSlides); ensure you only change the
declaration and numeric conversion (nextPos, _spaceCatcher, movePos, position,
totalSlides) to satisfy SonarCloud.
- Around line 478-490: _moveManual currently adds anonymous click handlers to
each .slider__dot on every call, causing duplicate listeners; change it to
attach a single delegated click handler on this.$.container (or use a named
bound handler stored as this._dotClickHandler) that checks
event.target.classList.contains('slider__dot') (or aria-posinset) and calls
this.movePos(pos - 1); before adding the handler remove any existing one
(removeEventListener using this._dotClickHandler) or only add it once, and keep
setting aria-labels and this._dotStyles for the dots but do not attach per-dot
listeners.
---
Outside diff comments:
In
`@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js`:
- Around line 372-380: The _ariaChecked method can access
dotElems[this.position] out of bounds if this.position >= dotElems.length;
update _ariaChecked to verify bounds before accessing or setting the "true"
attribute (e.g., check this.position !== undefined && this.position >= 0 &&
this.position < dotElems.length or clamp this.position to dotElems.length - 1)
after you clear all dots; specifically modify the _ariaChecked function to only
call dotElems[this.position].setAttribute when the index is valid to avoid the
TypeError during dom-repeat races.
---
Nitpick comments:
In
`@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js`:
- Around line 375-377: Replace the index-based loop that clears aria-checked on
dotElems with a for...of iteration: locate the loop iterating over dotElems (the
block starting with "for (var i = 0; i < dotElems.length; i++)" in
l2t-paper-slider.js) and change it to use "for (const dotElem of dotElems) {
dotElem.setAttribute('aria-checked', 'false'); }" so the code uses the idiomatic
for…of construct while preserving the same behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: eeded5f8-7a76-48bf-aa86-9de6c59927be
📒 Files selected for processing (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js`:
- Around line 487-490: Replace the use of "var dot" and the unsafe arithmetic
coercion in the delegated click handler _dotClickListener: declare the found
element with const (or let) instead of var, read the aria-posinset attribute
with Number.parseInt(dot.getAttribute('aria-posinset'), 10), check that the
parsed value is a finite number (not NaN) and only then call this.movePos(parsed
- 1); keep using e.target.closest('.slider__dot') and the existing movePos
method name to locate the fix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c8c8f3bb-5cdd-4a76-8135-f2d47fc74198
📒 Files selected for processing (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js
|
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js (1)
487-490:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
_dotClickListener:isNaNguard still missing after partial fix.
Number.parseInt(dot.getAttribute('aria-posinset'), 10) - 1passesNaNtomovePosif the attribute is absent or non-numeric. The current code degrades gracefully (_moveInd(undefined)exits early), but the explicitisNaNguard from the proposed fix was not applied.🛡️ Proposed fix
- if (dot) this$.movePos(Number.parseInt(dot.getAttribute('aria-posinset'), 10) - 1); + if (dot) { + const pos = Number.parseInt(dot.getAttribute('aria-posinset'), 10); + if (!isNaN(pos)) this$.movePos(pos - 1); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js` around lines 487 - 490, The click handler _dotClickListener currently passes NaN to movePos when aria-posinset is missing or non-numeric; change it to parse the attribute into a numeric index (use Number.parseInt or Number.parseInt(..., 10)), check with Number.isNaN (or !Number.isNaN) before computing "- 1" and only call this$.movePos when the parsed index is a valid number; reference _dotClickListener, the '.slider__dot' element, its 'aria-posinset' attribute, and the movePos(...) call so the guard is applied before invoking movePos.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In
`@src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js`:
- Around line 487-490: The click handler _dotClickListener currently passes NaN
to movePos when aria-posinset is missing or non-numeric; change it to parse the
attribute into a numeric index (use Number.parseInt or Number.parseInt(...,
10)), check with Number.isNaN (or !Number.isNaN) before computing "- 1" and only
call this$.movePos when the parsed index is a valid number; reference
_dotClickListener, the '.slider__dot' element, its 'aria-posinset' attribute,
and the movePos(...) call so the guard is applied before invoking movePos.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 22729320-9e40-4337-8693-a38caa71f859
📒 Files selected for processing (1)
src/main/resources/META-INF/resources/frontend/paper-slider/l2t-paper-slider.js



Close #49
Close #50
Summary by CodeRabbit
Bug Fixes
Accessibility