From 4dcfb7b703c9f5863ca0e1db181b56b49b0a6c98 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 01:06:12 +0000
Subject: [PATCH 1/3] Initial plan
From db3f61c016a3a8545550204ec00066d389d80f6b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 01:08:11 +0000
Subject: [PATCH 2/3] Replace innerHTML with secure DOM APIs to prevent XSS
vulnerabilities
Co-authored-by: rwoll <11915034+rwoll@users.noreply.github.com>
---
app.js | 46 +++++++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/app.js b/app.js
index 2448fa2..570fe2c 100644
--- a/app.js
+++ b/app.js
@@ -76,16 +76,28 @@ function renderUpcomingDates() {
const container = document.getElementById('upcoming-dates');
const dates = getNextPatchTuesdays(12);
- container.innerHTML = dates.map((date, index) => {
+ // Clear existing content
+ container.replaceChildren();
+
+ dates.forEach((date, index) => {
const daysAway = getDaysAway(date);
const isFirst = index === 0;
- return `
-
- ${formatDate(date)}
- ${formatDaysAway(daysAway)}
-
- `;
- }).join('');
+
+ const dateItem = document.createElement('div');
+ dateItem.className = isFirst ? 'date-item highlight' : 'date-item';
+
+ const dateSpan = document.createElement('span');
+ dateSpan.className = 'date';
+ dateSpan.textContent = formatDate(date);
+
+ const badgeSpan = document.createElement('span');
+ badgeSpan.className = isFirst ? 'badge primary' : 'badge';
+ badgeSpan.textContent = formatDaysAway(daysAway);
+
+ dateItem.appendChild(dateSpan);
+ dateItem.appendChild(badgeSpan);
+ container.appendChild(dateItem);
+ });
}
/**
@@ -107,19 +119,19 @@ function populateSelectors() {
'July', 'August', 'September', 'October', 'November', 'December'
];
- monthSelect.innerHTML = months.map((month, index) =>
- ``
- ).join('');
+ // Clear existing options and populate months
+ monthSelect.replaceChildren();
+ months.forEach((month, index) => {
+ const option = new Option(month, index, index === defaultMonth, index === defaultMonth);
+ monthSelect.add(option);
+ });
// Populate years (5 years before to 10 years after current year)
- const years = [];
+ yearSelect.replaceChildren();
for (let y = currentYear - 5; y <= currentYear + 10; y++) {
- years.push(y);
+ const option = new Option(y, y, y === defaultYear, y === defaultYear);
+ yearSelect.add(option);
}
-
- yearSelect.innerHTML = years.map(year =>
- ``
- ).join('');
}
/**
From c0c26624f82d24a8fb67696f4eb073c69202f5ea Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 01:09:25 +0000
Subject: [PATCH 3/3] Refactor Option constructor calls for clarity
Co-authored-by: rwoll <11915034+rwoll@users.noreply.github.com>
---
app.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app.js b/app.js
index 570fe2c..b96f179 100644
--- a/app.js
+++ b/app.js
@@ -122,14 +122,16 @@ function populateSelectors() {
// Clear existing options and populate months
monthSelect.replaceChildren();
months.forEach((month, index) => {
- const option = new Option(month, index, index === defaultMonth, index === defaultMonth);
+ const isSelected = index === defaultMonth;
+ const option = new Option(month, index, isSelected, isSelected);
monthSelect.add(option);
});
// Populate years (5 years before to 10 years after current year)
yearSelect.replaceChildren();
for (let y = currentYear - 5; y <= currentYear + 10; y++) {
- const option = new Option(y, y, y === defaultYear, y === defaultYear);
+ const isSelected = y === defaultYear;
+ const option = new Option(y, y, isSelected, isSelected);
yearSelect.add(option);
}
}