From f777ff70491377ecb573b428f1973ed0e62000f9 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:06:34 -0500 Subject: [PATCH 1/4] Add guard for missing video modal comment selectors --- .../video-modal/commentsController.js | 65 ++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/js/ui/components/video-modal/commentsController.js b/js/ui/components/video-modal/commentsController.js index 5112e2e6..fce2f1ba 100644 --- a/js/ui/components/video-modal/commentsController.js +++ b/js/ui/components/video-modal/commentsController.js @@ -1,3 +1,5 @@ +import logger from "../../utils/logger.js"; + export class CommentsController { constructor({ modal } = {}) { this.modal = modal; @@ -10,9 +12,34 @@ export class CommentsController { } const root = playerModal?.querySelector("[data-comments-root]") || null; + const commentsDisabledPlaceholder = + playerModal?.querySelector("[data-comments-disabled-placeholder]") || + root?.querySelector("[data-comments-disabled]") || + null; + this.root = root; this.modal.commentsRoot = root; this.modal.commentsContainer = root; + this.modal.commentsDisabledPlaceholder = commentsDisabledPlaceholder; + + if (commentsDisabledPlaceholder) { + const disabledText = commentsDisabledPlaceholder.textContent || ""; + if (disabledText) { + this.modal.commentsDisabledPlaceholderDefaultText = disabledText; + } + } + + if (!root) { + logger.user.warn( + "[VideoModal:comments] Missing [data-comments-root]; disabling comments UI" + ); + this.modal.showCommentsDisabledMessage( + this.modal.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now." + ); + return; + } + this.modal.commentsCountLabel = root?.querySelector("[data-comments-count]") || null; this.modal.commentsEmptyState = @@ -21,10 +48,6 @@ export class CommentsController { root?.querySelector("[data-comments-list]") || null; this.modal.commentsLoadMoreButton = root?.querySelector("[data-comments-load-more]") || null; - this.modal.commentsDisabledPlaceholder = - playerModal?.querySelector("[data-comments-disabled-placeholder]") || - root?.querySelector("[data-comments-disabled]") || - null; this.modal.commentsComposer = root?.querySelector("[data-comments-composer]") || null; this.modal.commentsInput = @@ -44,6 +67,35 @@ export class CommentsController { this.modal.commentComposerHint || null; + const missingSelectors = [ + { selector: "[data-comments-list]", element: this.modal.commentsList }, + { + selector: "[data-comments-composer]", + element: this.modal.commentsComposer, + }, + { + selector: "[data-comments-input]", + element: this.modal.commentsInput, + }, + { + selector: "[data-comments-submit]", + element: this.modal.commentsSubmitButton, + }, + ] + .filter(({ element }) => !element) + .map(({ selector }) => selector); + + if (missingSelectors.length > 0) { + logger.user.warn( + `[VideoModal:comments] Missing required selectors: ${missingSelectors.join(", ")}; disabling comments UI` + ); + this.modal.showCommentsDisabledMessage( + this.modal.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now." + ); + return; + } + if (this.modal.commentComposerHint) { const hintText = this.modal.commentComposerHint.textContent || ""; if (hintText) { @@ -73,11 +125,6 @@ export class CommentsController { } if (this.modal.commentsDisabledPlaceholder) { - const disabledText = - this.modal.commentsDisabledPlaceholder.textContent || ""; - if (disabledText) { - this.modal.commentsDisabledPlaceholderDefaultText = disabledText; - } this.modal.commentsDisabledPlaceholder.setAttribute("hidden", ""); } From 047a465d669461495aa31d24db1d0d320fe24efe Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:12:13 -0500 Subject: [PATCH 2/4] Refine comments modal disable handling --- .../video-modal/commentsController.js | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/js/ui/components/video-modal/commentsController.js b/js/ui/components/video-modal/commentsController.js index fce2f1ba..ae453633 100644 --- a/js/ui/components/video-modal/commentsController.js +++ b/js/ui/components/video-modal/commentsController.js @@ -4,6 +4,7 @@ export class CommentsController { constructor({ modal } = {}) { this.modal = modal; this.root = null; + this.playerModal = null; } initialize({ playerModal } = {}) { @@ -11,6 +12,7 @@ export class CommentsController { return; } + this.playerModal = playerModal || null; const root = playerModal?.querySelector("[data-comments-root]") || null; const commentsDisabledPlaceholder = playerModal?.querySelector("[data-comments-disabled-placeholder]") || @@ -33,10 +35,11 @@ export class CommentsController { logger.user.warn( "[VideoModal:comments] Missing [data-comments-root]; disabling comments UI" ); - this.modal.showCommentsDisabledMessage( - this.modal.commentsDisabledPlaceholderDefaultText || - "Comments are unavailable right now." - ); + this.disableComments({ + reason: "missing-root", + message: this.modal.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now.", + }); return; } @@ -89,13 +92,19 @@ export class CommentsController { logger.user.warn( `[VideoModal:comments] Missing required selectors: ${missingSelectors.join(", ")}; disabling comments UI` ); - this.modal.showCommentsDisabledMessage( - this.modal.commentsDisabledPlaceholderDefaultText || - "Comments are unavailable right now." - ); + this.disableComments({ + reason: "missing-selectors", + message: this.modal.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now.", + }); return; } + if (this.playerModal) { + this.playerModal.removeAttribute("data-comments-disabled"); + this.playerModal.classList?.remove("comments-disabled"); + } + if (this.modal.commentComposerHint) { const hintText = this.modal.commentComposerHint.textContent || ""; if (hintText) { @@ -137,6 +146,35 @@ export class CommentsController { this.modal.attachCommentEventHandlers(); } + disableComments({ message = "", reason = "" } = {}) { + if (this.playerModal) { + this.playerModal.setAttribute("data-comments-disabled", "true"); + this.playerModal.classList?.add("comments-disabled"); + } + + if (this.modal.commentsList) { + this.modal.commentsList.setAttribute("hidden", ""); + this.modal.commentsList.classList?.add("hidden"); + } + + if (this.modal.commentsComposer) { + this.modal.commentsComposer.setAttribute("hidden", ""); + this.modal.commentsComposer.classList?.add("hidden"); + } + + const nextMessage = + typeof message === "string" && message.trim() + ? message.trim() + : this.modal.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now."; + + this.modal.showCommentsDisabledMessage(nextMessage); + logger.dev?.info?.( + "[VideoModal:comments] Disabled comments handling", + { reason: reason || "unknown" } + ); + } + update(action = {}) { if (!this.modal) { return; @@ -182,6 +220,10 @@ export class CommentsController { this.modal.commentsStatusMessage = null; this.modal.commentsCharCount = null; this.modal.commentComposerHint = null; + if (this.playerModal) { + this.playerModal.removeAttribute("data-comments-disabled"); + this.playerModal.classList?.remove("comments-disabled"); + } this.root = null; } } From 5c08f8771e39e2815e70915dc51aef043ea82fd6 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Dec 2025 09:19:04 -0500 Subject: [PATCH 3/4] Add fallback comments disabled placeholder --- .../video-modal/commentsController.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/js/ui/components/video-modal/commentsController.js b/js/ui/components/video-modal/commentsController.js index ae453633..45d2147b 100644 --- a/js/ui/components/video-modal/commentsController.js +++ b/js/ui/components/video-modal/commentsController.js @@ -17,6 +17,7 @@ export class CommentsController { const commentsDisabledPlaceholder = playerModal?.querySelector("[data-comments-disabled-placeholder]") || root?.querySelector("[data-comments-disabled]") || + this.ensureCommentsDisabledPlaceholder({ root }) || null; this.root = root; @@ -147,6 +148,17 @@ export class CommentsController { } disableComments({ message = "", reason = "" } = {}) { + const placeholder = + this.modal.commentsDisabledPlaceholder || + this.ensureCommentsDisabledPlaceholder({ root: this.root }) || + null; + if (!this.modal.commentsDisabledPlaceholder && placeholder) { + this.modal.commentsDisabledPlaceholder = placeholder; + if (placeholder.textContent) { + this.modal.commentsDisabledPlaceholderDefaultText = placeholder.textContent; + } + } + if (this.playerModal) { this.playerModal.setAttribute("data-comments-disabled", "true"); this.playerModal.classList?.add("comments-disabled"); @@ -226,5 +238,54 @@ export class CommentsController { } this.root = null; } + + getDocument() { + if (this.modal?.document) { + return this.modal.document; + } + if (this.playerModal?.ownerDocument) { + return this.playerModal.ownerDocument; + } + if (typeof document !== "undefined") { + return document; + } + return null; + } + + ensureCommentsDisabledPlaceholder({ root } = {}) { + const existing = + this.modal?.commentsDisabledPlaceholder || + root?.querySelector?.("[data-comments-disabled-placeholder]") || + this.playerModal?.querySelector?.("[data-comments-disabled-placeholder]"); + if (existing) { + return existing; + } + + const doc = this.getDocument(); + const container = root?.parentElement || this.playerModal || null; + if (!doc || !container) { + return null; + } + + const placeholder = doc.createElement("div"); + placeholder.setAttribute("data-comments-disabled-placeholder", ""); + placeholder.setAttribute("role", "status"); + placeholder.setAttribute("aria-live", "polite"); + placeholder.setAttribute("hidden", ""); + placeholder.classList.add("comment-thread__disabled"); + + const defaultText = + this.modal?.commentsDisabledPlaceholderDefaultText || + "Comments are unavailable right now."; + placeholder.textContent = defaultText; + + if (root?.parentElement) { + root.parentElement.insertBefore(placeholder, root); + } else { + container.insertBefore(placeholder, container.firstChild); + } + + return placeholder; + } } From 49adb42e368fd8cd49f2f1fbb7d01968a4ae677a Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:04:30 -0500 Subject: [PATCH 4/4] Fix logger import path for comments controller --- js/ui/components/video-modal/commentsController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/ui/components/video-modal/commentsController.js b/js/ui/components/video-modal/commentsController.js index 45d2147b..a89644f0 100644 --- a/js/ui/components/video-modal/commentsController.js +++ b/js/ui/components/video-modal/commentsController.js @@ -1,4 +1,4 @@ -import logger from "../../utils/logger.js"; +import logger from "../../../utils/logger.js"; export class CommentsController { constructor({ modal } = {}) {