]> Lady’s Gitweb - WWW/blob - sources/calendar/index.xhtml
Initial attempt at a calendar widget
[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-Child(n+6){ 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.today{ Box-Shadow: 1PX 1PX #700020 }
15 #widget>div>div:First-Child>table td.today>b{ Color: #992244 }
16 #widget>div>div:First-Child>table td.today>small{ Background: #700020 }
17 #widget>div>div{ Width: 16REM Flex: None}
18 ]]></style>
19 <meta itemprop="urn:fdc:ladys.computer:20231231:Shu1She4:title" content="Calendar | Lady’s Computer"/>
20 <h1><small><a href="/">Lady’s Computer</a> ∷ </small>Calendar</h1>
21 <!--<details>
22 <summary>About this calendar…</summary>
23 </details>-->
24 <aside id="widget">
25 <template>
26 <h2/>
27 <div>
28 <div>
29 <table>
30 <thead>
31 <tr>
32 <th scope="col"></th>
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 </tr>
41 </thead>
42 <tbody>
43 <tr/>
44 <tr/>
45 <tr/>
46 <tr/>
47 <tr/>
48 </tbody>
49 </table>
50 </div>
51 <div/>
52 </div>
53 <footer>
54 <button type="button">Previous</button>
55 <button type="button">Current</button>
56 <button type="button">Next</button>
57 </footer>
58 </template>
59 <noscript>Calendar widget requires Javascript!</noscript>
60 <script><![CDATA[#!js
61 const widget= document.getElementById("widget")
62 const template= widget.querySelector("#widget>template")
63 const day= +Date.UTC(1970, 0, 2)
64 const today = new Date();
65 const dateForDay= (start, month, dayInMonth) => new Date
66 ( +start + ((month - 1) * 40 + dayInMonth - 1) * day)
67 const td= (start, month, dayInMonth) =>
68 { const elt= document.createElement("td")
69 const date= dateForDay(start, month, dayInMonth)
70 const label= document.createElement("b")
71 label.textContent= `${dayInMonth}`.padStart(2, "0")
72 const caption= document.createElement("small")
73 caption.textContent= `${date.getUTCDate()}`.padStart(2, "0")
74 + [ " Jan"
75 , " Feb"
76 , " Mar"
77 , " Apr"
78 , " May"
79 , " Jun"
80 , " Jul"
81 , " Aug"
82 , " Sep"
83 , " Oct"
84 , " Nov"
85 , " Dec"][date.getUTCMonth()]
86 elt.replaceChildren(label, " ", caption)
87 if
88 ( date.getUTCFullYear() == today.getFullYear()
89 && date.getUTCMonth() == today.getMonth()
90 && date.getUTCDate() == today.getDate())
91 { elt.className= "today"}
92 return elt}
93 const renderCalendarIncludingDate= (date) =>
94 { const start= new Date
95 ( Date.UTC
96 ( date.getUTCFullYear()
97 - ! ( date.getUTCMonth() > 8
98 || date.getUTCMonth() == 8 && date.getUTCDate() >= 22)
99 , 8
100 , 22))
101 const dayInYear= Math.floor
102 ( ( Date.UTC
103 ( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
104 - start)
105 / day)
106 const month= Math.floor(dayInYear / 40) + 1
107 const view= template.content.cloneNode(true)
108 const year= start.getUTCFullYear() - 1999
109 if (month == 10)
110 { const title= document.createElement("i")
111 title.textContent= "Fetes"
112 view.querySelector("h2").replaceChildren(title, ` ${year}`)}
113 else
114 { const tide= document.createElement("i")
115 tide.textContent= month == 5 ? "·en·tide" : "·tide"
116 view.querySelector("h2").replaceChildren
117 ( [ "Lake"
118 , "Hallow"
119 , "Yule"
120 , "Carnival"
121 , "Lent"
122 , "Eastre"
123 , "Lithe"
124 , "Lammas"
125 , "Weod"][month - 1] ?? month
126 , tide
127 , ` ${year}`)}
128 const calendar= view.querySelector("table")
129 const intercalaryDays= 5
130 + ( new Date
131 ( Date.UTC(start.getUTCFullYear() + 1) + Date.UTC(1970, 2, 1))
132 . getUTCMonth()
133 === 1)
134 if (month == 10)
135 { calendar.tHead.rows[0].replaceChildren
136 ( ...[ ...calendar.tHead.rows[0].cells].slice(0, intercalaryDays))
137 calendar.tBodies[0].rows[0].replaceChildren
138 ( ...new Array(intercalaryDays).fill().map
139 ( (_, n) => td(start, 10, n + 1)))
140 calendar.tBodies[0].replaceChildren(calendar.tBodies[0].rows[0])}
141 else
142 { [...calendar.tBodies[0].rows].forEach
143 ( (row, m) => row.replaceChildren
144 ( ...new Array(8).fill().map
145 ( (_, n) => td(start, month, m * 8 + n + 1))))}
146 view.querySelector("button:First-Child").addEventListener
147 ( "click"
148 , () => renderCalendarIncludingDate
149 ( new Date(+dateForDay(start, month, 1) - 1 * day)))
150 view.querySelector
151 ( "button:Not(:First-Child):Not(:Last-Child)")
152 . addEventListener
153 ( "click"
154 , () => renderCalendarIncludingDate
155 ( new Date
156 ( Date.UTC
157 ( today.getFullYear(), today.getMonth(), today.getDate()))))
158 view.querySelector("button:Last-Child").addEventListener
159 ( "click"
160 , () => renderCalendarIncludingDate
161 ( new Date
162 ( +dateForDay(start, month, 1)
163 + (month == 10 ? intercalaryDays : 40) * day)))
164 widget.replaceChildren(view)}
165 renderCalendarIncludingDate
166 ( new Date
167 ( Date.UTC(today.getFullYear(), today.getMonth(), today.getDate())))
168 ]]></script>
169 </aside>
170 </article>
This page took 0.356812 seconds and 5 git commands to generate.