Skip to content

Commit 08341a7

Browse files
authored
Merge pull request #50 from koudaiii/koudaiii/refactor
Add configuration const
2 parents 601319a + 1df0b5b commit 08341a7

File tree

1 file changed

+102
-47
lines changed

1 file changed

+102
-47
lines changed

src/content.js

Lines changed: 102 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
// Configuration constants
2+
const CONFIG = {
3+
DEFAULT_LANGUAGE: 'en-us',
4+
DOMAIN: 'learn.microsoft.com',
5+
URL_PATTERN: /https:\/\/learn\.microsoft\.com\/([^\/]+)\//,
6+
DEBUG_PARAM: 'jp-learn-microsoft-com-update-checker-debug',
7+
SELECTORS: {
8+
DATE_ELEMENT: 'local-time',
9+
THEME_BUTTON: 'button[data-theme-to][aria-pressed="true"]',
10+
},
11+
STYLES: {
12+
ALERT: {
13+
margin: '5px',
14+
padding: '10px',
15+
},
16+
INFO: {
17+
marginTop: '0',
18+
marginLeft: '3px',
19+
},
20+
},
21+
CLASSES: {
22+
ALERT: 'alert is-primary',
23+
THEMES: {
24+
dark: 'text-color-dark',
25+
'high-contrast': 'text-color-high-contrast',
26+
light: 'text-color-light',
27+
default: 'text-color',
28+
},
29+
},
30+
TIME_CONSTANTS: {
31+
MILLISECONDS_IN_MINUTE: 1000 * 60,
32+
MILLISECONDS_IN_HOUR: 1000 * 60 * 60,
33+
MILLISECONDS_IN_DAY: 1000 * 60 * 60 * 24,
34+
MILLISECONDS_IN_YEAR: 1000 * 60 * 60 * 24 * 365,
35+
},
36+
};
37+
138
// languageLabels is a dictionary that maps message from language codes to the corresponding language
239
// Default languageLabels is 'last updated on'
340
// Add more languageLabels as needed
@@ -21,31 +58,78 @@ const timeAgoLabels = {
2158
// 'fr-fr': { years: 'il y a ans', days: 'il y a jours', hours: 'il y a heures', minutes: 'il y a minutes', justNow: 'à l\'instant' },
2259
};
2360

61+
// Helper functions
62+
const getLanguageFromUrl = (url) => {
63+
const match = url.match(CONFIG.URL_PATTERN);
64+
return match ? match[1] : null;
65+
};
66+
67+
const getEnglishUrl = (url, currentLang) => {
68+
return url.replace(`/${currentLang}/`, `/${CONFIG.DEFAULT_LANGUAGE}/`);
69+
};
70+
71+
const calculateTimeAgo = (timeDifference, currentLang) => {
72+
const { MILLISECONDS_IN_YEAR, MILLISECONDS_IN_DAY, MILLISECONDS_IN_HOUR, MILLISECONDS_IN_MINUTE } = CONFIG.TIME_CONSTANTS;
73+
74+
const years = Math.floor(timeDifference / MILLISECONDS_IN_YEAR);
75+
const days = Math.floor((timeDifference % MILLISECONDS_IN_YEAR) / MILLISECONDS_IN_DAY);
76+
const hours = Math.floor((timeDifference % MILLISECONDS_IN_DAY) / MILLISECONDS_IN_HOUR);
77+
const minutes = Math.floor((timeDifference % MILLISECONDS_IN_HOUR) / MILLISECONDS_IN_MINUTE);
78+
79+
const labels = timeAgoLabels[currentLang] || {
80+
years: 'years ago',
81+
days: 'days ago',
82+
hours: 'hours ago',
83+
minutes: 'minutes ago',
84+
justNow: 'just now'
85+
};
86+
87+
if (years > 0) {
88+
return ` ${years} ${labels.years}`;
89+
} else if (days > 0) {
90+
return ` ${days} ${labels.days}`;
91+
} else if (hours > 0) {
92+
return ` ${hours} ${labels.hours}`;
93+
} else if (minutes > 0) {
94+
return ` ${minutes} ${labels.minutes}`;
95+
} else {
96+
return labels.justNow;
97+
}
98+
};
99+
100+
const getTextColorClass = (theme) => {
101+
return CONFIG.CLASSES.THEMES[theme] || CONFIG.CLASSES.THEMES.default;
102+
};
103+
104+
const applyStyles = (element, styles) => {
105+
Object.entries(styles).forEach(([key, value]) => {
106+
element.style[key] = value;
107+
});
108+
};
109+
24110
(async () => {
25111
// Get current URL
26112
const currentUrl = window.location.href;
27113

28114
// Use a regular expression to extract the language code
29-
const languageCodeMatch = currentUrl.match(/https:\/\/learn\.microsoft\.com\/([^\/]+)\//);
30-
const currentLang = languageCodeMatch ? languageCodeMatch[1] : null;
115+
const currentLang = getLanguageFromUrl(currentUrl);
31116
if (!currentLang) return;
32117

33118
// Check if the page(https://learn.microsoft.com/en-us) is in en-us, if so, return
34-
const lang = 'en-us';
35-
if (currentLang === lang) return;
119+
if (currentLang === CONFIG.DEFAULT_LANGUAGE) return;
36120

37-
const debug = new URLSearchParams(window.location.search).get("jp-learn-microsoft-com-update-checker-debug");
121+
const debug = new URLSearchParams(window.location.search).get(CONFIG.DEBUG_PARAM);
38122

39123
// Get local-time tag in current page
40-
const dataArticleDateElement = document.querySelector('local-time');
124+
const dataArticleDateElement = document.querySelector(CONFIG.SELECTORS.DATE_ELEMENT);
41125
if (!dataArticleDateElement) return;
42126

43127
// Parse article date
44128
const articleDateStr = dataArticleDateElement.getAttribute("datetime");
45129
const articleDate = new Date(articleDateStr);
46130

47131
// Translate URL to English
48-
const englishUrl = currentUrl.replace(`/${currentLang}/`, "/en-us/");
132+
const englishUrl = getEnglishUrl(currentUrl, currentLang);
49133

50134
try {
51135
// Get English page and parse update date
@@ -56,7 +140,7 @@ const timeAgoLabels = {
56140
const parser = new DOMParser();
57141
const doc = parser.parseFromString(data, "text/html");
58142

59-
const englishDateStr = doc.querySelector('local-time')?.getAttribute("datetime");
143+
const englishDateStr = doc.querySelector(CONFIG.SELECTORS.DATE_ELEMENT)?.getAttribute("datetime");
60144
if (!englishDateStr) return;
61145
const englishDate = new Date(englishDateStr);
62146

@@ -66,48 +150,21 @@ const timeAgoLabels = {
66150
const timeDifference = currentDate - englishDate;
67151

68152
// Create a new paragraph element to display the update information
69-
let timeAgo;
70-
const years = Math.floor(timeDifference / (1000 * 60 * 60 * 24 * 365));
71-
const days = Math.floor((timeDifference % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24));
72-
const hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
73-
const minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
74-
75-
const labels = timeAgoLabels[currentLang] || {
76-
years: 'years ago',
77-
days: 'days ago',
78-
hours: 'hours ago',
79-
minutes: 'minutes ago',
80-
justNow: 'just now'
81-
};
82-
83-
if (years > 0) {
84-
timeAgo = ` ${years} ${labels.years}`;
85-
} else if (days > 0) {
86-
timeAgo = ` ${days} ${labels.days}`;
87-
} else if (hours > 0) {
88-
timeAgo = ` ${hours} ${labels.hours}`;
89-
} else if (minutes > 0) {
90-
timeAgo = ` ${minutes} ${labels.minutes}`;
91-
} else {
92-
timeAgo = labels.justNow;
93-
}
94-
let timeAgoStr = ` (${timeAgo})`;
153+
const timeAgo = calculateTimeAgo(timeDifference, currentLang);
154+
const timeAgoStr = ` (${timeAgo})`;
95155

96156
const updateInfo = document.createElement("p");
97157
dataArticleDateElement.parentElement.appendChild(updateInfo);
98158

99159
const updateClass = () => {
100160
// if theme is selected, apply appropriate text color based on theme
101-
const textColorClass = ((theme) => {
102-
if (theme === "dark") return "text-color-dark";
103-
if (theme === "high-contrast") return "text-color-high-contrast";
104-
if (theme === "light") return "text-color-light";
105-
return "text-color";
106-
})(document.querySelector('button[data-theme-to][aria-pressed="true"]').getAttribute("data-theme-to"));
161+
const themeButton = document.querySelector(CONFIG.SELECTORS.THEME_BUTTON);
162+
const theme = themeButton.getAttribute("data-theme-to");
163+
const textColorClass = getTextColorClass(theme);
107164
console.log("textColorClass:", textColorClass);
108165

109166
// Add icon to update info
110-
informationIcon = "";
167+
let informationIcon = "";
111168

112169
console.log("English date:", englishDate);
113170
console.log("Article date:", articleDate);
@@ -116,14 +173,12 @@ const timeAgoLabels = {
116173
// Compare English date and Article date
117174
if (englishDate > articleDate || debug === "true") {
118175
// Display alert if English page is updated
119-
updateInfo.className = "alert is-primary"; // <class="alert is-primary"> is defined in CSS
120-
updateInfo.style.margin = "5px";
121-
updateInfo.style.padding = "10px";
176+
updateInfo.className = CONFIG.CLASSES.ALERT;
177+
applyStyles(updateInfo, CONFIG.STYLES.ALERT);
122178
informationIcon = `<span class="icon"><span class="docon docon-status-error-outline" aria-hidden="true" style="margin: 0px"></span></span>`;
123179
} else {
124180
// Display info if English page is not updated
125-
updateInfo.style.marginTop = "0"; // <p> default margin-top is 1rem
126-
updateInfo.style.marginLeft = "3px"; // <p> default margin-left is 0
181+
applyStyles(updateInfo, CONFIG.STYLES.INFO);
127182
updateInfo.className = textColorClass; // Apply appropriate text color based on theme
128183
}
129184

@@ -135,7 +190,7 @@ const timeAgoLabels = {
135190
}
136191
updateClass();
137192
const observer = new MutationObserver(updateClass);
138-
observer.observe(document.querySelector('button[data-theme-to][aria-pressed="true"]'), { attributes: true });
193+
observer.observe(document.querySelector(CONFIG.SELECTORS.THEME_BUTTON), { attributes: true });
139194
} catch (error) {
140195
console.error("Error fetching English page:", error);
141196
}

0 commit comments

Comments
 (0)