Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visual scroll-to comment indicator #73

Merged
merged 3 commits into from
May 18, 2024
Merged
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
78 changes: 57 additions & 21 deletions src/content-scripts/contentscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +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" });
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);
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
Expand Down Expand Up @@ -130,3 +133,36 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) {

return true;
});

function highlightComment(element) {
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" &&
counter < maxCounter
) {
highlightElement = highlightElement.parentElement;
counter++;
}

// If an 'article' element is found or the nth parent is reached, highlight whatever the element is.
if (highlightElement) {
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.
// This is very important to ensure the HTML of this element stays the same as what is returned by the audits endpoint.
}
}