]> Lady’s Gitweb - WWW/blob - sources/calendar/index.xhtml
Improve calendar display
[WWW] / sources / calendar / index.xhtml
1 <?xml version="1.0"?>
2 <article xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:书社="urn:fdc:ladys.computer:20231231:Shu1She4" lang="en" xml:lang="en">
3 <style><![CDATA[@charset "UTF-8";
4 #widget h2{ Margin-Inline: Auto; Margin-Block-End: 1REM; Border-Block-End: Thin Solid; Padding-Inline: 1CH; Max-Inline-Size: Max-Content }
5 #widget>footer{ Display: Grid; Margin-Block: 1REM; Margin-Inline: Auto; Max-Inline-Size: Max-Content; Grid-Template-Columns: 1FR 1FR 1FR; Gap: 1CH }
6 #widget>div{ Display: Flex; Margin-Block: 1REM; Flex-Flow: Row Wrap; Gap: 1REM }
7 #widget>div>div:First-Child{ Min-Inline-Size: Max-Content; Inline-Size: 27REM; Flex: Auto;}
8 #widget>div>div:First-Child>table{ Margin-Inline: Auto; Font-Variant-Numeric: Lining-Nums Tabular-Nums; Text-Align-Last: Auto }
9 #widget>div>div:First-Child>table th{ Border-Block-End: Thin Solid; Text-Align: Center }
10 #widget>div>div:First-Child>table td{ Position: Relative; Border: Thin Solid; Padding: 0; Block-Size: 3.5EM; Inline-Size: 3.5EM; Vertical-Align: Top; Background: #1A1A1A; Text-Align: Start }
11 #widget>div>div:First-Child>table td:Nth-Last-Child(-n+3),#widget>div>div:First-Child>table td:Nth-Child(-n+2):Nth-Last-Child(-n+6),#widget>div>div:First-Child>table td:Nth-Child(3):Nth-Last-Child(4){ Background-Image: Repeating-Linear-Gradient(To Bottom Right, Transparent 0PX, Transparent .5PX, #686868 1PX, #686868 1.5PX, Transparent 2PX) }
12 #widget>div>div:First-Child>table td>b{ Display: Block; Margin-Inline-End: Auto; Border: Thin #F3DEE3 Solid; Padding: 2PX; Width: 3CH; Color: #1A1A1A; Background: #F3DEE3; Box-Shadow: Inset -1PX -1PX CurrentColor; Font-Style: Italic; Text-Align: Center }
13 #widget>div>div:First-Child>table td>small{ Display: Block; Position: Absolute; Inset-Block-End: 0; Inset-Inline-End: 0; Margin-Block-Start: Auto; Margin-Inline-Start: Auto; Border-Block-Start: Thin Dashed; Border-Inline-Start: Thin Dashed; Padding-Inline: .5CH; Width: Max-Content; Max-Width: 100%; Color: #F3DEE3; Background: #1A1A1A; Font-Size: .75EM; Font-Style: Italic }
14 #widget>div>div:First-Child>table td>small.weekend{ Text-Decoration: Underline }
15 #widget>div>div:First-Child>table td.today{ Box-Shadow: 1PX 1PX #700020 }
16 #widget>div>div:First-Child>table td.today>b{ Color: #992244 }
17 #widget>div>div:First-Child>table td.today>small{ Background: #700020 }
18 #widget>div>div{ Width: 16REM Flex: None}
19 ]]></style>
20 <meta itemprop="urn:fdc:ladys.computer:20231231:Shu1She4:title" content="Calendar | Lady’s Computer"/>
21 <h1><small><a href="/">Lady’s Computer</a> ∷ </small>Calendar</h1>
22 <!--<details>
23 <summary>About this calendar…</summary>
24 </details>-->
25 <aside id="widget">
26 <template>
27 <h2/>
28 <div>
29 <div>
30 <table>
31 <thead>
32 <tr>
33 <th scope="col"></th>
34 <th scope="col"></th>
35 <th scope="col"></th>
36 <th scope="col"></th>
37 <th scope="col"></th>
38 <th scope="col"></th>
39 <th scope="col"></th>
40 <th scope="col"></th>
41 </tr>
42 </thead>
43 <tbody>
44 <tr/>
45 <tr/>
46 <tr/>
47 <tr/>
48 <tr/>
49 </tbody>
50 </table>
51 </div>
52 <div/>
53 </div>
54 <footer>
55 <button type="button">Previous</button>
56 <button type="button">Current</button>
57 <button type="button">Next</button>
58 </footer>
59 </template>
60 <noscript>Calendar widget requires Javascript!</noscript>
61 <script><![CDATA[#!js
62 const widget= document.getElementById("widget")
63 const template= widget.querySelector("#widget>template")
64 const day= +Date.UTC(1970, 0, 2)
65 const today= new Date();
66 const lmn= (name, atts, ...children) =>
67 { const elt= document.createElement(name)
68 elt.replaceChildren(...children)
69 for (const att in (atts ?? {}))
70 { elt.setAttribute(att, atts[att])}
71 return elt}
72 const dateForDay= (start, month, dayInMonth) => new Date
73 ( +start + ((month - 1) * 40 + dayInMonth - 1) * day)
74 const td= (start, month, dayInMonth) =>
75 { const elt= document.createElement("td")
76 const date= dateForDay(start, month, dayInMonth)
77 const label= lmn("b", null, `${dayInMonth}`.padStart(2, "0"))
78 const caption= lmn
79 ( "small"
80 , date.getUTCDay() == 0 || date.getUTCDay() == 6
81 ? {class: "weekend"}
82 : null
83 , lmn
84 ( "abbr"
85 , { title
86 : [ "Sunday"
87 , "Monday"
88 , "Tuesday"
89 , "Wednesday"
90 , "Thursday"
91 , "Friday"
92 , "Saturday"][date.getUTCDay()]}
93 , "SMTWÞFL"[date.getUTCDay()])
94 , " " + `${date.getUTCDate()}`.padStart(2, "0") + " "
95 , [ lmn("abbr", {title: "January"}, "Jan")
96 , lmn("abbr", {title: "February"}, "Feb")
97 , lmn("abbr", {title: "March"}, "Mar")
98 , lmn("abbr", {title: "April"}, "Apr")
99 , lmn("abbr", {title: "May"}, "May")
100 , lmn("abbr", {title: "June"}, "Jun")
101 , lmn("abbr", {title: "July"}, "Jul")
102 , lmn("abbr", {title: "August"}, "Aug")
103 , lmn("abbr", {title: "September"}, "Sep")
104 , lmn("abbr", {title: "October"}, "Oct")
105 , lmn("abbr", {title: "November"}, "Nov")
106 , lmn("abbr", {title: "December"}, "Dec")][date.getUTCMonth()])
107 elt.replaceChildren(label, " ", caption)
108 if
109 ( date.getUTCFullYear() == today.getFullYear()
110 && date.getUTCMonth() == today.getMonth()
111 && date.getUTCDate() == today.getDate())
112 { elt.className= "today"}
113 return elt}
114 const renderCalendarIncludingDate= (date) =>
115 { const start= new Date
116 ( Date.UTC
117 ( date.getUTCFullYear()
118 - ! ( date.getUTCMonth() > 8
119 || date.getUTCMonth() == 8 && date.getUTCDate() >= 22)
120 , 8
121 , 22))
122 const dayInYear= Math.floor
123 ( ( Date.UTC
124 ( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
125 - start)
126 / day)
127 const month= Math.floor(dayInYear / 40) + 1
128 const view= template.content.cloneNode(true)
129 const year= start.getUTCFullYear() - 1999
130 if (month == 10)
131 { const title= document.createElement("i")
132 title.textContent= "Fetes"
133 view.querySelector("h2").replaceChildren(title, ` ${year}`)}
134 else
135 { const tide= document.createElement("i")
136 tide.textContent= month == 5 ? "·en·tide" : "·tide"
137 view.querySelector("h2").replaceChildren
138 ( [ "Lake"
139 , "Hallow"
140 , "Yule"
141 , "Carnival"
142 , "Lent"
143 , "Eastre"
144 , "Lithe"
145 , "Lammas"
146 , "Weod"][month - 1] ?? month
147 , tide
148 , ` ${year}`)}
149 const calendar= view.querySelector("table")
150 const intercalaryDays= 5
151 + ( new Date
152 ( Date.UTC(start.getUTCFullYear() + 1) + Date.UTC(1970, 2, 1))
153 . getUTCMonth()
154 === 1)
155 if (month == 10)
156 { calendar.tHead.rows[0].replaceChildren
157 ( ...[ ...calendar.tHead.rows[0].cells].slice(0, intercalaryDays))
158 calendar.tBodies[0].rows[0].replaceChildren
159 ( ...new Array(intercalaryDays).fill().map
160 ( (_, n) => td(start, 10, n + 1)))
161 calendar.tBodies[0].replaceChildren(calendar.tBodies[0].rows[0])}
162 else
163 { [...calendar.tBodies[0].rows].forEach
164 ( (row, m) => row.replaceChildren
165 ( ...new Array(8).fill().map
166 ( (_, n) => td(start, month, m * 8 + n + 1))))}
167 view.querySelector("button:First-Child").addEventListener
168 ( "click"
169 , () => renderCalendarIncludingDate
170 ( new Date(+dateForDay(start, month, 1) - 1 * day)))
171 view.querySelector
172 ( "button:Not(:First-Child):Not(:Last-Child)")
173 . addEventListener
174 ( "click"
175 , () => renderCalendarIncludingDate
176 ( new Date
177 ( Date.UTC
178 ( today.getFullYear(), today.getMonth(), today.getDate()))))
179 view.querySelector("button:Last-Child").addEventListener
180 ( "click"
181 , () => renderCalendarIncludingDate
182 ( new Date
183 ( +dateForDay(start, month, 1)
184 + (month == 10 ? intercalaryDays : 40) * day)))
185 widget.replaceChildren(view)}
186 renderCalendarIncludingDate
187 ( new Date
188 ( Date.UTC(today.getFullYear(), today.getMonth(), today.getDate())))
189 ]]></script>
190 </aside>
191 </article>
This page took 0.137057 seconds and 5 git commands to generate.