element
var body = document.body;
const skip_content_text = document.getElementById("snipp_skip_content_txt").textContent.trim();
// Insert the "Skip to main content" link immediately after the opening tag
body.insertAdjacentHTML('afterbegin', `${skip_content_text} `);
let _page = document.getElementById('page').value;
let _pages = document.getElementById('pages')?.value || null;
if (_page == "search-page" || _pages =="cat-sub-page") {
// Select the buttons and the ul element
console.log(_page);
const list_button = document.getElementById("list_button");
const grid_button = document.getElementById("grid_button");
const srch_list = document.getElementById("main-content");
const switch_to_list_view_text = document.getElementById("snipp_switch_to_list_view").textContent.trim();
const snipp_switch_to_grid_view_text = document.getElementById("snipp_switch_to_grid_view").textContent.trim();
list_button.setAttribute('aria-label', switch_to_list_view_text);
grid_button.setAttribute('aria-label', snipp_switch_to_grid_view_text);
// Function to handle button click and class toggling
function handleButtonClick(buttonClicked, otherButton, className) {
// Update ul's class based on the button clicked
srch_list.className = className;
// Update active state for buttons
buttonClicked.classList.add("active");
otherButton.classList.remove("active");
}
// Define the classes based on page type
let listClass, gridClass;
if (_page === "search-page") {
listClass = "search-results-sections";
gridClass = "search-results-section";
} else {
listClass = "cat-sub-page-sections";
gridClass = "cat-sub-page-section";
}
// Add event listeners
list_button.addEventListener("click", () => handleButtonClick(list_button, grid_button, listClass));
grid_button.addEventListener("click", () => handleButtonClick(grid_button, list_button, gridClass));
}
if (_page == "search-page" || _page == "home-page") {
let search_header = document.getElementById("search-header");
search_header.remove();
}
if (_page != "search-page" && _page != "home-page") {
let search_header = document.getElementById("search-header");
search_header.style.display = 'flex';
}
if (_page == "art-page") {
const collapsible = document.querySelectorAll(".collapsible-nav, .collapsible-sidebar");
collapsible.forEach((element) => {
const toggle = element.querySelector(".collapsible-nav-toggle, .collapsible-sidebar-toggle");
element.addEventListener("click", () => {
toggleNavigation(toggle, element);
});
element.addEventListener("keyup", (event) => {
//console.log("escape");
if (event.keyCode === ESCAPE) {
closeNavigation(toggle, element);
}
});
});
const parentDivs = document.querySelectorAll('.article-body-content');
// Loop through each parent div
parentDivs.forEach(parentDiv => {
// Select all descendants of the current parent div
const allDescendants = parentDiv.querySelectorAll('*'); // Select all elements within the parent div
// Loop through all descendants and remove the style attribute
allDescendants.forEach(descendant => {
descendant.removeAttribute('style');
// Remove the id="isPasted" attribute, if it exists
if (descendant.id === "isPasted") {
descendant.removeAttribute('id');
}
});
});
// DOM manipulation to append a div and modify buttons after render
const questionElement = document.querySelector(".article-survey-rating-question");
if (questionElement) {
const newSpan = document.createElement("div");
const newspan_text = document.getElementById("snipp_rate_article_txt").textContent.trim();
//console.log(newspan_text);
newSpan.textContent = newspan_text;
newSpan.className = "additional-info-span"; // Add a class for styling if needed
questionElement.insertAdjacentElement("afterend", newSpan);
}
// Modify Yes and No buttons
const positiveButton = document.querySelector('button[name="positiveButton"]');
const negativeButton = document.querySelector('button[name="negativeButton"]');
if (positiveButton) {
const positiveButton_text = document.getElementById("snipp_helpful_txt").textContent.trim();
positiveButton.innerHTML = `${positiveButton_text} `; // Add icon and modify text
}
if (negativeButton) {
const negativeButton_text = document.getElementById("snipp_nothelpful_txt").textContent.trim();
negativeButton.innerHTML = `${negativeButton_text} `; // Add icon and modify text
}
document.querySelector('button[name="positiveButton"]').addEventListener('click', function() {
setTimeout(() => {
// Select the survey wrapper element
const surveyWrapper = document.querySelector('.article-survey-success-wrapper');
const surveyWrapper_heading_text = document.getElementById("snipp_feedback_submitted_txt").textContent.trim();
const surveyWrapper_text = document.getElementById("snipp_appreciate_feedback_txt").textContent.trim();
if (surveyWrapper) {
// Update inner HTML and make the survey wrapper visible
surveyWrapper.innerHTML = `${surveyWrapper_heading_text} ${surveyWrapper_text}
`;
surveyWrapper.style.visibility = "visible";
} else {
console.error('Survey wrapper not found.');
}
}, 1500);
});
/*document.querySelector('button[name="negativeButton"]').addEventListener('click', function() {
// Get all elements
const links = document.querySelectorAll('#toc li a');
let textOutput = '';
// Loop through each link and collect text
links.forEach(link => {
textOutput += link.textContent + '\n'; // Add each link text with a newline
});
// Set a timeout to push text into the textarea
setTimeout(() => {
Select the label element with attribute `for="writtenFeedback"`
const label = document.querySelector('label[for="writtenFeedback"]');
label.classList.add("label-db");
Change the text content of the label
if (label) {
label.textContent = "What made this article not helpful?";
}
document.getElementById('writtenFeedback').value = textOutput; // Push text into textarea
document.querySelector('button[type="submit"]').textContent = "Submit feedback";
document.getElementById("writtenFeedback").placeholder = "What made this article not helpful?";
}, 1000); // Delay of 1 second
});*/
document.querySelectorAll('.accordion-headers').forEach((button, index) => {
// Select the accordion content (the div right after the button)
const accordionContent = button.nextElementSibling;
// Assign unique IDs to each accordion content if they don't have one already
const contentId = `accordion-content-${index}`;
if (!accordionContent.id) {
accordionContent.id = contentId; // Set id dynamically if it doesn't exist
}
// Set the necessary accessibility attributes dynamically
button.setAttribute('role', 'button'); // Set role="button"
button.setAttribute('tabindex', '0'); // Make the button focusable
button.setAttribute('aria-expanded', 'false'); // Set aria-expanded initially to false
button.setAttribute('aria-controls', contentId); // Link the button to its content
// Set initial state for accordion content
accordionContent.style.maxHeight = '0'; // Initially hide content
accordionContent.style.overflow = 'hidden'; // Prevent overflow when collapsed
// Optional: Add a transition for smooth opening/closing
accordionContent.style.transition = 'max-height 0.5s ease-out';
// Click event to toggle accordion
button.addEventListener('click', () => {
toggleAccordion(button, accordionContent);
});
// Keyboard event for Enter or Space keys
button.addEventListener('keydown', (event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault(); // Prevent page scroll for Space key
toggleAccordion(button, accordionContent);
}
});
function toggleAccordion(button, accordionContent) {
// Get the current expanded state
const isExpanded = button.getAttribute('aria-expanded') === 'true';
if (isExpanded) {
// Collapse the accordion
button.setAttribute('aria-expanded', 'false');
accordionContent.style.maxHeight = '0'; // Collapse the content
} else {
// Expand the accordion
button.setAttribute('aria-expanded', 'true');
accordionContent.style.maxHeight = accordionContent.scrollHeight + 'px'; // Expand to content height
}
// Toggle the active class for styling (optional)
button.classList.toggle('active', !isExpanded);
}
// Footnote click handling
const footnoteRefs = document.querySelectorAll("sup a[href^='#']");
//console.log(footnoteRefs);
footnoteRefs.forEach(ref => {
ref.addEventListener("click", function(event) {
event.preventDefault();
const targetId = this.getAttribute("href").substring(1);
const footnote = document.getElementById(targetId);
if (!footnote) return;
const accordionContent = footnote.closest(".accordion-contents");
if (accordionContent) {
const accordionHeader = accordionContent.previousElementSibling;
// Open the accordion only if it's closed
if (accordionHeader.getAttribute("aria-expanded") === "false") {
// Use your toggleAccordion function
accordionHeader.click();
}
// Scroll to footnote
footnote.scrollIntoView({ behavior: "smooth", block: "center" });
} else {
// Footnote outside accordion, just scroll
footnote.scrollIntoView({ behavior: "smooth", block: "center" });
}
});
});
// ✅ HEADING / TEXT ANCHOR LINKS ( )
const headingRefs = document.querySelectorAll(".article-body-content a[href^='#']:not(sup a)");
headingRefs.forEach(ref => {
ref.addEventListener("click", function (event) {
event.preventDefault();
const targetId = this.getAttribute("href").substring(1);
const targetHeading = document.getElementById(targetId);
if (!targetHeading) return;
const accordionHeader = targetHeading.closest(".accordion-headers");
if (accordionHeader) {
if (accordionHeader.getAttribute("aria-expanded") === "false") {
accordionHeader.click();
}
accordionHeader.scrollIntoView({ behavior: "smooth", block: "center" });
} else {
targetHeading.scrollIntoView({ behavior: "smooth", block: "center" });
}
});
});
});
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
const submitButton = document.querySelector('button[type="submit"]:not([disabled])');
//console.log("Checking for submit button:", submitButton);
if (submitButton && !submitButton.hasAttribute('data-listener-attached')) {
submitButton.addEventListener('click', handleSubmitButtonClick);
submitButton.setAttribute('data-listener-attached', 'true');
//console.log("Event listener added to submit button.");
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
document.querySelector('button[name="negativeButton"]').addEventListener('click', function() {
setTimeout(() => {
const submitButton = document.querySelector('button[type="submit"]');
const feedbackTextarea = document.getElementById("writtenFeedback");
const feedBackForm = document.querySelector('.article-survey-form');
if (submitButton && feedbackTextarea) {
// Update submit button text
submitButton.textContent = document.getElementById("snipp_submit_feedback_txt").textContent.trim();
// Update placeholder text of the feedback textarea
feedbackTextarea.placeholder = document.getElementById("snipp_article_not_helpful_txt").textContent.trim();
feedBackForm.style.visibility = "visible";
}
if (submitButton && feedbackTextarea) {
//console.log("Triggering submit button click.");
submitButton.click();
}
}, 1500);
});
const element = document.getElementById('toc-wrapper');
const targetDiv = document.querySelector('.article-inner-container');
const footer = document.querySelector('.artcile-footer');
const top_header = document.querySelector('.nav');
const top_hero = document.querySelector('.innerpage-banner');
if (element && targetDiv && footer) {
let targetPosition = targetDiv.getBoundingClientRect().top + window.scrollY - 24;
let elementWidth = element.offsetWidth;
let total_height = top_header.clientHeight + top_hero.clientHeight;
let footerPosition = footer.getBoundingClientRect().top + window.scrollY - element.clientHeight - 24;
// Function to update target position and element width
function updateValues() {
targetPosition = targetDiv.getBoundingClientRect().top + window.scrollY - 24;
elementWidth = element.offsetWidth;
total_height = top_header.clientHeight + top_hero.clientHeight;
footerPosition = footer.getBoundingClientRect().top + window.scrollY - element.clientHeight - 24;
}
// Update values initially
updateValues();
// Update values on window resize
window.addEventListener('resize', updateValues);
const resizeObserver = new ResizeObserver(updateValues);
resizeObserver.observe(document.body);
// Handle scrolling
window.addEventListener('scroll', () => {
const windowWidth = window.innerWidth; // Get window width on scroll
if (windowWidth > 991) { // Check if window width is greater than 991px
if (window.scrollY >= targetPosition) {
element.classList.add('scrolled');
element.style.width = `${elementWidth}px`;
element.style.top = `${window.scrollY + 24 - total_height}px`;
} else {
element.classList.remove('scrolled');
element.style.width = ''; // Reset width if scrolled class is removed
element.style.top = '';
}
if (window.scrollY >= footerPosition) {
element.classList.add('scrolled-sticky');
} else {
element.classList.remove('scrolled-sticky');
}
} else {
// Reset for smaller window sizes
element.classList.remove('scrolled', 'scrolled-sticky');
element.style.width = ''; // Reset width if scrolled class is removed
element.style.top = '';
}
});
}
// Select all elements with the class "refrence-aria-label"
const spanElements = document.querySelectorAll('.reference-aria-label, .footnote-aria-label');
// Check if any elements exist
if (spanElements.length > 0) {
// Iterate through each element
spanElements.forEach((span) => {
const parentAnchor = span.parentElement; // Get the parent element
if (parentAnchor && parentAnchor.tagName === 'A') {
parentAnchor.setAttribute('aria-label', span.textContent.trim()); // Set aria-label
}
});
}
}
if (_page != "art-page") {
sessionStorage.removeItem("selectedLang");
sessionStorage.removeItem("selectedArtId");
}
// Select the paragraph
const renew_paragraph = document.querySelector('.desc span');
if (renew_paragraph) {
// Replace the target phrases with bold versions
renew_paragraph.innerHTML = renew_paragraph.innerHTML
.replace(/Rush Hour Rewards/g, 'Rush Hour Rewards ')
.replace(/Nest Renew/g, 'Nest Renew ');
}
const search_snippetElement = document.getElementById('search_plc_txt');
const searchInput = document.getElementById('searchInput');
if (search_snippetElement && searchInput) {
searchInput.placeholder = search_snippetElement.textContent.trim();
}
const banner_snippet = document.getElementById('snipp_nest_renew_banner_txt');
const hero_img = document.getElementById('hero-img');
if (banner_snippet && hero_img) {
hero_img.alt = banner_snippet.textContent.trim();
}
const search_icon_snippet = document.getElementById('snipp_icon_search_txt');
const search_icon_img = document.getElementById('search-img');
if (search_icon_snippet && search_icon_img) {
search_icon_img.alt = search_icon_snippet.textContent.trim();
}
const close_btn_snippet = document.getElementById('snipp_close_icon_txt');
const close_btn = document.getElementById('close-btn-img');
if (close_btn_snippet && close_btn) {
close_btn.alt = close_btn_snippet.textContent.trim();
}
const icon_search_snippet = document.getElementById('snipp_search_txt');
const icon_search_img = document.getElementById('icon-search');
if (icon_search_snippet && icon_search_img) {
icon_search_img.alt = icon_search_snippet.textContent.trim();
}
const renew_family_snippet = document.getElementById('snipp_family_of_three_txt');
const renew_family_img = document.getElementById('renew-family-banner');
if (renew_family_snippet && renew_family_img) {
renew_family_img.alt = renew_family_snippet.textContent.trim();
}
const renew_banner_snippet = document.getElementById('snipp_renew_banner_link');
const renew_banner_element = document.getElementById('renew_banner_link');
if (renew_banner_snippet && renew_banner_element) {
renew_banner_element.href = renew_banner_snippet.textContent.trim();
}
const nest_descrip_snippet = document.getElementById('snipp_nest_thermostat_descp');
const nest_descrip_element = document.getElementById('nest-description-anchor');
if (nest_descrip_snippet && nest_descrip_element) {
nest_descrip_element.href = nest_descrip_snippet.textContent.trim();
}
const rush_hour_url_snippet = document.getElementById('snipp_rush_hour_url');
const rush_hour_url_element = document.getElementById('rush_hours_link');
if (rush_hour_url_snippet && rush_hour_url_element) {
rush_hour_url_element.href = rush_hour_url_snippet.textContent.trim();
}
const login_snippet = document.getElementById('snipp_login_url');
const login_element = document.getElementById('nav-link-0');
if (login_snippet && login_element) {
login_element.href = login_snippet.textContent.trim();
}
const need_help_with_thermostat_snippet = document.getElementById('snipp_need_help_with_thermostat');
const need_help_with_thermostat_element = document.getElementById('footer_link_nest_thermostat');
if (need_help_with_thermostat_snippet && need_help_with_thermostat_element) {
need_help_with_thermostat_element.href = need_help_with_thermostat_snippet.textContent.trim();
}
const sidebar_toggle_icon_snippet = document.getElementById('snipp_sidebar_toggle_icon').textContent.trim();;
const sidebar_toggle_icon_element = document.getElementById('sidebar-toggle-icon');
if (sidebar_toggle_icon_snippet && sidebar_toggle_icon_element) {
sidebar_toggle_icon_element.setAttribute('aria-label', sidebar_toggle_icon_snippet);
}
// Select the element
const selectElement = document.querySelector('.language-select');
const selectElement_text = snipp_choose_language.textContent.trim();
// Add aria-label to the element
selectElement.setAttribute('aria-label', selectElement_text);
selectElement.setAttribute('autocomplete', 'off');
// Add lang attributes to the elements
const options = selectElement.options;
options[0].setAttribute('lang', 'en-US'); // English (US)
options[1].setAttribute('lang', 'es-US'); // Español (US)
// Remove disabled attribute from both options
options[0].removeAttribute('disabled');
options[1].removeAttribute('disabled');
});
// Function to handle the submit button action
function handleSubmitButtonClick() {
setTimeout(() => {
const surveyWrapper = document.querySelector('.article-survey-success-wrapper');
const surveyWrapper_heading_text = document.getElementById("snipp_feedback_submitted_txt").textContent.trim();
const surveyWrapper_text = document.getElementById("snipp_appreciate_feedback_txt").textContent.trim();
if (surveyWrapper) {
surveyWrapper.innerHTML = `${surveyWrapper_heading_text} ${surveyWrapper_text}
`;
surveyWrapper.style.visibility = "visible";
//console.log("Submit button click handled.");
}
}, 1500);
}
// Vanilla JS debounce function, by Josh W. Comeau:
// https://www.joshwcomeau.com/snippets/javascript/debounce/
function debounce(callback, wait) {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
// Define variables for search field
let searchFormFilledClassName = "search-has-value";
let searchFormSelector = "form[role='search']";
// Clear the search input, and then return focus to it
function clearSearchInput(event) {
event.target
.closest(searchFormSelector)
.classList.remove(searchFormFilledClassName);
//let form_suggestion = document.getElementById("form-suggestion");
let input;
if (event.target.tagName === "INPUT") {
input = event.target;
} else if (event.target.tagName === "BUTTON") {
input = event.target.previousElementSibling;
} else {
input = event.target.closest("button").previousElementSibling;
}
input.value = "";
input.focus();
//form_suggestion.remove();
}
// Have the search input and clear button respond
// when someone presses the escape key, per:
// https://twitter.com/adambsilver/status/1152452833234554880
function clearSearchInputOnKeypress(event) {
const searchInputDeleteKeys = ["Delete", "Escape"];
if (searchInputDeleteKeys.includes(event.key)) {
clearSearchInput(event);
}
}
// Create an HTML button that all users -- especially keyboard users --
// can interact with, to clear the search input.
// To learn more about this, see:
// https://adrianroselli.com/2019/07/ignore-typesearch.html#Delete
// https://www.scottohara.me/blog/2022/02/19/custom-clear-buttons.html
function buildClearSearchButton() {
const button = document.getElementById('close-btn');;
button.addEventListener("click", clearSearchInput);
button.addEventListener("keyup", clearSearchInputOnKeypress);
return button;
}
// Append the clear button to the search form
function appendClearSearchButton(input, form) {
const searchClearButton = buildClearSearchButton(input.id);
form.append(searchClearButton);
if (input.value.length > 0) {
form.classList.add(searchFormFilledClassName);
}
}
// Add a class to the search form when the input has a value;
// Remove that class from the search form when the input doesn't have a value.
// Do this on a delay, rather than on every keystroke.
const toggleClearSearchButtonAvailability = debounce((event) => {
const form = event.target.closest(searchFormSelector);
form.classList.toggle(
searchFormFilledClassName,
event.target.value.length > 0
);
}, 200);
// Search
window.addEventListener("DOMContentLoaded", () => {
// Set up clear functionality for the search field
const searchForms = [...document.querySelectorAll(searchFormSelector)];
const searchInputs = searchForms.map((form) =>
form.querySelector("input[type='search']")
);
searchInputs.forEach((input) => {
appendClearSearchButton(input, input.closest(searchFormSelector));
input.addEventListener("keyup", clearSearchInputOnKeypress);
input.addEventListener("keyup", toggleClearSearchButtonAvailability);
});
});
const key = "returnFocusTo";
function saveFocus() {
const activeElementId = document.activeElement.getAttribute("id");
sessionStorage.setItem(key, "#" + activeElementId);
}
function returnFocus() {
const returnFocusTo = sessionStorage.getItem(key);
if (returnFocusTo) {
sessionStorage.removeItem("returnFocusTo");
const returnFocusToEl = document.querySelector(returnFocusTo);
returnFocusToEl && returnFocusToEl.focus && returnFocusToEl.focus();
}
}
function toggleNavigation(toggle, menu) {
const isExpanded = menu.classList.contains("expanded");
if (isExpanded) {
menu.classList.remove("expanded");
} else {
menu.classList.add("expanded");
}
toggle.setAttribute("aria-expanded", !isExpanded);
}
function closeNavigation(toggle, menu) {
menu.classList.remove("expanded");
toggle.setAttribute("aria-expanded", false);
toggle.focus();
}