From 763dc210a8bd5cb789079562d22c82a49bb29513 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Sat, 18 May 2024 08:36:33 -0600 Subject: [PATCH 1/3] Add visual indicator for scrolled-to comment Related to #63 Implements visual feedback for scrolled-to comments in Zendesk Link Collector extension. - Adds a new function `highlightComment` to apply a temporary highlight to a comment after scrolling to it. - Modifies the `scrollToComment` function to call `highlightComment`, providing a visual indication of the scrolled-to comment. - Ensures the highlight fades away after a few seconds, improving user experience by clearly indicating the comment of interest. --- src/content-scripts/contentscript.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/content-scripts/contentscript.js b/src/content-scripts/contentscript.js index 9030064..ff88765 100644 --- a/src/content-scripts/contentscript.js +++ b/src/content-scripts/contentscript.js @@ -13,6 +13,7 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { document.querySelector(`[id="comment-${request.auditID}"]`); if (element) { element.scrollIntoView({ behavior: "smooth", block: "center" }); + highlightComment(element); // Call the new highlight function after scrolling return; } @@ -31,6 +32,7 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (event.type == "Comment") { if (comment.outerHTML == event.html_body) { comment.scrollIntoView({ behavior: "smooth", block: "center" }); + highlightComment(comment); // Call the new highlight function after scrolling return; } } @@ -130,3 +132,12 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { return true; }); + +// Function to visually highlight the scrolled-to comment +function highlightComment(element) { + element.style.transition = "background-color 0.5s ease"; + element.style.backgroundColor = "#ffff99"; // Temporary highlight color + setTimeout(() => { + element.style.backgroundColor = ""; // Remove highlight after a few seconds + }, 2000); // Ensure the highlight fades away after a few seconds +} From 11a2d8a56cd47024faf16a71821ba037cf26a281 Mon Sep 17 00:00:00 2001 From: bagtoad <47394200+BagToad@users.noreply.github.com> Date: Sat, 18 May 2024 10:00:11 -0600 Subject: [PATCH 2/3] feat: Add visual indicator for scrolled-to comment & refactor scroll-to comment function to prevent duplicate messages --- src/content-scripts/contentscript.js | 79 ++++++++++++++++++---------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/content-scripts/contentscript.js b/src/content-scripts/contentscript.js index ff88765..0bd1d19 100644 --- a/src/content-scripts/contentscript.js +++ b/src/content-scripts/contentscript.js @@ -4,41 +4,42 @@ console.log("Zendesk Link Collector - loaded content script"); browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { // Scroll to the comment. if (request.type == "scroll") { - const element = document.querySelector( - `[data-comment-id="${request.commentID}"]` - ) - ? // Older Zendesk versions. - document.querySelector(`[data-comment-id="${request.commentID}"]`) - : // Newer Zendesk versions. - document.querySelector(`[id="comment-${request.auditID}"]`); - if (element) { - element.scrollIntoView({ behavior: "smooth", block: "center" }); - highlightComment(element); // Call the new highlight function after scrolling - return; - } - - // Last resort, sometimes zendesk does not add the data-comment-id or id attributes to the comments. - // Get the comment from the audits endpoint, find the comment with the same HTML in the DOM and scroll to it. - const url = new URL(document.URL); - const urlArr = url.href.split("/"); - const ticketID = urlArr[urlArr.length - 1]; + // This is async because it contains a fetch which we must wait for before sending a response. + (async () => { + const element = document.querySelector( + `[data-comment-id="${request.commentID}"]` + ) + ? // Older Zendesk versions. + document.querySelector(`[data-comment-id="${request.commentID}"]`) + : // Newer Zendesk versions. + document.querySelector(`[id="comment-${request.auditID}"]`); + if (element) { + element.scrollIntoView({ behavior: "smooth", block: "center" }); + highlightComment(element); + return; + } + // Last resort, sometimes zendesk does not add the data-comment-id or id attributes to the comments. + // Get the comment from the audits endpoint, find the comment with the same HTML in the DOM and scroll to it. + const url = new URL(document.URL); + const urlArr = url.href.split("/"); + const ticketID = urlArr[urlArr.length - 1]; - fetch( - `${url.protocol}//${url.hostname}/api/v2/tickets/${ticketID}/audits/${request.auditID}` - ).then(async function (response) { + const response = await fetch( + `${url.protocol}//${url.hostname}/api/v2/tickets/${ticketID}/audits/${request.auditID}` + ); const data = await response.json(); document.querySelectorAll(".zd-comment").forEach((comment) => { data.audit.events.forEach((event) => { if (event.type == "Comment") { if (comment.outerHTML == event.html_body) { comment.scrollIntoView({ behavior: "smooth", block: "center" }); - highlightComment(comment); // Call the new highlight function after scrolling + highlightComment(comment); return; } } }); }); - }); + })(); } // Code from https://stackoverflow.com/questions/55214828/how-to-make-a-cross-origin-request-in-a-content-script-currently-blocked-by-cor/55215898#55215898 @@ -133,11 +134,31 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { return true; }); -// Function to visually highlight the scrolled-to comment function highlightComment(element) { - element.style.transition = "background-color 0.5s ease"; - element.style.backgroundColor = "#ffff99"; // Temporary highlight color - setTimeout(() => { - element.style.backgroundColor = ""; // Remove highlight after a few seconds - }, 2000); // Ensure the highlight fades away after a few seconds + let highlightElement = element.parentElement; + // Traverse up the DOM tree until an 'article' element is found + while ( + highlightElement && + highlightElement.nodeName.toLowerCase() !== "article" + ) { + highlightElement = highlightElement.parentElement; + } + + // If an 'article' element is found + if (highlightElement) { + // Save the original background color + const originalColor = highlightElement.style.backgroundColor; + + highlightElement.style.transition = "background-color 0.5s ease"; + highlightElement.style.backgroundColor = "#ffff99"; + setTimeout(() => { + // Set the background color back to its original color to start the fade-out transition + highlightElement.style.backgroundColor = originalColor; + }, 2000); + + // After the transition is complete, remove the style attribute + setTimeout(() => { + highlightElement.removeAttribute("style"); + }, 2500); // Ensure the style attribute is removed after the transition is complete + } } From 357feededc67468554b05463cc695e5e65f32c00 Mon Sep 17 00:00:00 2001 From: bagtoad <47394200+BagToad@users.noreply.github.com> Date: Sat, 18 May 2024 10:11:10 -0600 Subject: [PATCH 3/3] refactor: Improve highlightComment function and add counter for DOM traversal --- src/content-scripts/contentscript.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/content-scripts/contentscript.js b/src/content-scripts/contentscript.js index 0bd1d19..44836fe 100644 --- a/src/content-scripts/contentscript.js +++ b/src/content-scripts/contentscript.js @@ -135,18 +135,21 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { }); function highlightComment(element) { - let highlightElement = element.parentElement; - // Traverse up the DOM tree until an 'article' element is found + let highlightElement = element; + let counter = 0; + const maxCounter = 20; + // Traverse up the DOM tree until an 'article' element is found or counter reaches 10 while ( highlightElement && - highlightElement.nodeName.toLowerCase() !== "article" + highlightElement.nodeName.toLowerCase() !== "article" && + counter < maxCounter ) { highlightElement = highlightElement.parentElement; + counter++; } - // If an 'article' element is found + // If an 'article' element is found or the nth parent is reached, highlight whatever the element is. if (highlightElement) { - // Save the original background color const originalColor = highlightElement.style.backgroundColor; highlightElement.style.transition = "background-color 0.5s ease"; @@ -159,6 +162,7 @@ function highlightComment(element) { // After the transition is complete, remove the style attribute setTimeout(() => { highlightElement.removeAttribute("style"); - }, 2500); // Ensure the style attribute is removed after the transition is complete + }, 2500); // Ensure the style attribute is removed after the transition is complete. + // This is very important to ensure the HTML of this element stays the same as what is returned by the audits endpoint. } }