-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
153 lines (122 loc) · 4.14 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const DEFAULT_YEAR = new Date().getFullYear();
const DEFAULT_LOCALE = String(
navigator.language || navigator.userLanguage
).slice(0, 2);
function parseHash() {
const fields = document.location.hash.slice(1).split("|");
var year, locale;
if (fields.length == 1) {
year = Number(fields[0]);
} else {
year = Number(fields[1]);
locale = fields[0];
}
return { year: year || DEFAULT_YEAR, locale: locale || DEFAULT_LOCALE };
}
function setHash({ year, locale }) {
const current = parseHash();
history.pushState(
null,
null,
`#${locale || current.locale}|${year || current.year}`
);
}
function drawCalendar() {
const date = new Date();
const { year, locale } = parseHash();
date.setFullYear(year);
date.setHours(12); // to prevent strange things happening if executed exactly around midnight...
document.title = `Linear-Kalender für ${year}`;
const container = document.getElementById("calendar");
container.replaceChildren();
// generate months 01-12
for (let m = 0; m < 12; m++) {
date.setMonth(m, 1);
const month = document.createElement("div");
month.className = "month";
// title bar colors
month.style.setProperty("--start-hue", 240 - m * 30);
month.style.setProperty("--end-hue", 240 - (m + 1) * 30);
// title
const monthTitle = document.createElement("div");
monthTitle.className = "title";
monthTitle.append(date.toLocaleString(locale, { month: "long" }));
if (m == 0) {
// add year to January title
const yearTitle = document.createElement("div");
yearTitle.className = "year";
yearTitle.append(year);
monthTitle.prepend(yearTitle);
}
month.append(monthTitle);
// days
const lastDayOfMonth = new Date(year, m + 1, 0).getDate();
const daysWrapper = document.createElement("div");
daysWrapper.className = "days";
daysWrapper.style.setProperty("--number-of-days", lastDayOfMonth);
for (let d = 1; d <= lastDayOfMonth; d++) {
date.setMonth(m, d);
const dayNumber = document.createElement("div");
dayNumber.className = `day number weekday-${date.getDay()}`;
dayNumber.append(d);
const dayTitle = document.createElement("div");
dayTitle.className = `day title weekday-${date.getDay()}`;
const dayTitleSpan = document.createElement("span");
dayTitleSpan.append(date.toLocaleString(locale, { weekday: "long" })); // TODO: option for "short"?
dayTitle.append(dayTitleSpan);
const dayNotes = document.createElement("div");
dayNotes.className = `day notes weekday-${date.getDay()}`;
daysWrapper.append(dayNumber, dayTitle, dayNotes);
}
month.append(daysWrapper);
container.append(month);
}
}
function setupLocaleInput(localeInput) {
// const LANGUAGES_LIST is defined in languages.js which has to be included in the same html file
const supportedLocales = Intl.DateTimeFormat.supportedLocalesOf(
Object.keys(LANGUAGES_LIST),
{ localeMatcher: "lookup" }
);
for (const code of supportedLocales) {
if (!LANGUAGES_LIST[code]) {
continue;
}
const option = document.createElement("option");
option.setAttribute("value", code);
option.append(
`${LANGUAGES_LIST[code].name} (${LANGUAGES_LIST[code].nativeName})`
);
localeInput.append(option);
}
}
// ----------------------------------------------------------------------------------
(function main() {
const yearInput = document.getElementById("yearInput");
const localeInput = document.getElementById("localeInput");
setupLocaleInput(localeInput);
const { year, locale } = parseHash();
yearInput.value = year;
localeInput.value = locale;
if (year != DEFAULT_YEAR || locale != DEFAULT_LOCALE) {
setHash(year, locale);
}
window.addEventListener(
"hashchange",
({ newURL, oldURL }) => {
if (newURL != oldURL) {
drawCalendar();
}
},
false
);
yearInput.addEventListener("input", (e) => {
setHash({ year: Number(yearInput.value) });
drawCalendar();
});
localeInput.addEventListener("input", (e) => {
setHash({ locale: localeInput.value });
drawCalendar();
});
drawCalendar();
})();