datalog-theme 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +125 -0
- data/CITATION.cff +2 -2
- data/README.md +23 -17
- data/_data/cdn-integrity.yml +0 -30
- data/_includes/analytics/dashboard.html +3 -1
- data/_includes/components/api-function.html +20 -1
- data/_includes/components/enhanced-code-block.html +1 -1
- data/_includes/csp-meta.html +115 -11
- data/_includes/footer.html +19 -20
- data/_includes/head.html +60 -23
- data/_includes/header/navigation.html +12 -15
- data/_includes/header.html +28 -19
- data/_includes/layouts/default/article.html +5 -1
- data/_includes/meta/math-config.html +9 -5
- data/_includes/meta/schema.html +5 -2
- data/_includes/meta/scripts-loader.html +16 -32
- data/_includes/post/related-posts.html +4 -7
- data/_includes/search/index-data.json +9 -34
- data/_layouts/dataset.html +1 -0
- data/_layouts/default.html +16 -8
- data/_layouts/notebook.html +1 -0
- data/_layouts/package.html +1 -0
- data/_layouts/portfolio.html +1 -0
- data/_layouts/post.html +20 -5
- data/_layouts/project.html +2 -1
- data/_plugins/analytics_dashboard.rb +9 -3
- data/_plugins/config_validator.rb +12 -7
- data/_plugins/csp_generator.rb +18 -28
- data/_plugins/datalog_bibliography.rb +9 -7
- data/_plugins/datalog_comments.rb +8 -5
- data/_plugins/datalog_slides.rb +9 -8
- data/_plugins/i18n.rb +7 -8
- data/_plugins/image_optimizer.rb +17 -6
- data/_plugins/math_preprocessor.rb +33 -3
- data/_plugins/notebook_converter.rb +23 -4
- data/_plugins/plugin_loader.rb +3 -1
- data/_plugins/publications_generator.rb +8 -2
- data/_plugins/rouge_highlight_filter.rb +42 -0
- data/_plugins/search_code_blocks.rb +30 -0
- data/_plugins/search_normalizer.rb +15 -53
- data/_plugins/search_pages.rb +3 -4
- data/_sass/_academic-dashboard.scss +262 -0
- data/_sass/_base.scss +12 -0
- data/_sass/_components.scss +64 -1153
- data/_sass/_features.scss +17 -0
- data/_sass/_layout.scss +1 -1
- data/_sass/_notebooks.scss +322 -0
- data/_sass/_open-science-badges.scss +56 -0
- data/_sass/{_phase1-enhancements.scss → _post-components.scss} +1 -1
- data/_sass/_search-page.scss +530 -0
- data/_sass/_search.scss +46 -0
- data/_sass/_syntax-highlighting.scss +212 -97
- data/_sass/_theme.scss +29 -19
- data/_sass/_typography.scss +14 -0
- data/assets/css/main.scss +14 -0
- data/assets/js/dist/academic.js +1 -1
- data/assets/js/dist/analytics-dashboard.js +1 -1
- data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
- data/assets/js/dist/core.js +1 -1
- data/assets/js/dist/loader.js +1 -1
- data/assets/js/dist/notebook.js +1 -1
- data/assets/js/dist/search.js +1 -1
- data/assets/js/dist/visualizations.js +11 -2
- data/assets/js/loader.js +3 -1
- data/datalog-theme.gemspec +36 -23
- data/lib/datalog/cli.rb +34 -14
- data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
- data/lib/datalog/theme/package.rb +57 -0
- data/lib/datalog/theme/repository_checkout.rb +90 -0
- data/lib/datalog/theme/version.rb +1 -1
- data/lib/datalog/warning_filter.rb +5 -11
- data/lib/datalog-theme.rb +5 -0
- metadata +48 -133
- data/_data/academic.yml +0 -217
- data/_data/config/author.yml +0 -121
- data/_data/datasets.yml +0 -28
- data/_data/js_meta.json +0 -371
- data/_data/navigation.yml +0 -145
- data/_data/projects.yml +0 -41
- data/_data/publications.yml +0 -28
- data/_data/social.yml +0 -73
- data/_data/visualizations.yml +0 -51
- data/_includes/components/advanced-search.html +0 -682
- data/_includes/components/bookmark-system.html +0 -96
- data/_includes/components/comments.html +0 -244
- data/_includes/components/content-recommendations.html +0 -228
- data/_includes/components/email-preferences.html +0 -200
- data/_includes/components/enhanced-metadata.html +0 -228
- data/_includes/components/language-switcher.html +0 -396
- data/_includes/components/navigation-enhancements.html +0 -454
- data/_includes/components/newsletter-signup.html +0 -178
- data/_includes/components/popular-posts.html +0 -233
- data/_includes/components/reading-progress.html +0 -133
- data/_includes/components/reading-time.html +0 -121
- data/_includes/components/series-navigation.html +0 -124
- data/_includes/components/social-proof.html +0 -34
- data/_includes/components/user-preferences.html +0 -566
- data/_includes/meta/syntax-config.html +0 -19
- data/_layouts/archive.html +0 -282
- data/_layouts/post-sidebar.html +0 -183
- data/_sass/_phase3-enhancements.scss +0 -874
- data/_sass/_phase4-enhancements.scss +0 -1214
- data/_sass/_phase5-enhancements.scss +0 -414
- data/assets/js/academic.js +0 -262
- data/assets/js/analytics-dashboard.js +0 -382
- data/assets/js/core/dark-mode.js +0 -79
- data/assets/js/core/github-cards.js +0 -123
- data/assets/js/core/language-filter.js +0 -69
- data/assets/js/core/navigation.js +0 -184
- data/assets/js/core/scroll-progress.js +0 -45
- data/assets/js/core/search-hotkeys.js +0 -62
- data/assets/js/core/skip-links.js +0 -62
- data/assets/js/dist/manifest.json +0 -22
- data/assets/js/dist/meta.json +0 -371
- data/assets/js/main.js +0 -23
- data/assets/js/math.js +0 -818
- data/assets/js/notebook.js +0 -158
- data/assets/js/search/analytics.js +0 -91
- data/assets/js/search/app.js +0 -271
- data/assets/js/search/autocomplete.js +0 -120
- data/assets/js/search/engine.js +0 -260
- data/assets/js/search/filters.js +0 -45
- data/assets/js/search/render.js +0 -217
- data/assets/js/search/utils.js +0 -99
- data/assets/js/search.js +0 -354
- data/assets/js/visualizations.js +0 -816
- data/assets/publications/datalog-publications.bib +0 -8
- data/assets/publications/datalog-publications.ris +0 -9
- data/assets/publications/publications.bib +0 -30
- data/assets/templates/diogo-ribeiro-cv.md +0 -31
- data/assets/templates/diogo-ribeiro-cv.tex +0 -32
- data/lib/datalog/theme/theme.rb +0 -18
|
@@ -1,566 +0,0 @@
|
|
|
1
|
-
{%- comment -%}
|
|
2
|
-
User Preferences Panel Component
|
|
3
|
-
Provides customizable reading experience controls
|
|
4
|
-
|
|
5
|
-
Parameters:
|
|
6
|
-
- show_theme_toggle: Show dark/light theme toggle (default: true)
|
|
7
|
-
- show_font_size: Show font size controls (default: true)
|
|
8
|
-
- show_reading_mode: Show reading mode toggle (default: true)
|
|
9
|
-
- show_layout: Show layout preferences (default: true)
|
|
10
|
-
- position: Panel position (floating, sidebar) (default: floating)
|
|
11
|
-
{%- endcomment -%}
|
|
12
|
-
|
|
13
|
-
{%- assign show_theme_toggle = include.show_theme_toggle | default: true -%}
|
|
14
|
-
{%- assign show_font_size = include.show_font_size | default: true -%}
|
|
15
|
-
{%- assign show_reading_mode = include.show_reading_mode | default: true -%}
|
|
16
|
-
{%- assign show_layout = include.show_layout | default: true -%}
|
|
17
|
-
{%- assign position = include.position | default: "floating" -%}
|
|
18
|
-
|
|
19
|
-
<div class="user-preferences user-preferences--{{ position }}"
|
|
20
|
-
data-user-preferences
|
|
21
|
-
aria-label="User preferences">
|
|
22
|
-
|
|
23
|
-
<button type="button"
|
|
24
|
-
class="user-preferences__trigger"
|
|
25
|
-
data-preferences-trigger
|
|
26
|
-
aria-label="Open preferences"
|
|
27
|
-
aria-expanded="false"
|
|
28
|
-
aria-controls="preferences-panel">
|
|
29
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
30
|
-
width="24"
|
|
31
|
-
height="24"
|
|
32
|
-
viewBox="0 0 24 24"
|
|
33
|
-
fill="none"
|
|
34
|
-
stroke="currentColor"
|
|
35
|
-
stroke-width="2"
|
|
36
|
-
stroke-linecap="round"
|
|
37
|
-
stroke-linejoin="round"
|
|
38
|
-
aria-hidden="true">
|
|
39
|
-
<circle cx="12" cy="12" r="3"></circle>
|
|
40
|
-
<path d="M12 1v6m0 6v6m7.071-13.071l-4.243 4.243m0 5.656l4.243 4.243M1 12h6m6 0h6m-13.071 7.071l4.243-4.243m5.656 0l4.243 4.243"></path>
|
|
41
|
-
</svg>
|
|
42
|
-
<span class="user-preferences__trigger-text">Preferences</span>
|
|
43
|
-
</button>
|
|
44
|
-
|
|
45
|
-
<div class="user-preferences__panel"
|
|
46
|
-
id="preferences-panel"
|
|
47
|
-
data-preferences-panel
|
|
48
|
-
role="dialog"
|
|
49
|
-
aria-modal="true"
|
|
50
|
-
aria-labelledby="preferences-title"
|
|
51
|
-
hidden>
|
|
52
|
-
|
|
53
|
-
<div class="user-preferences__header">
|
|
54
|
-
<h3 class="user-preferences__title" id="preferences-title">
|
|
55
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
56
|
-
width="20"
|
|
57
|
-
height="20"
|
|
58
|
-
viewBox="0 0 24 24"
|
|
59
|
-
fill="none"
|
|
60
|
-
stroke="currentColor"
|
|
61
|
-
stroke-width="2"
|
|
62
|
-
aria-hidden="true">
|
|
63
|
-
<circle cx="12" cy="12" r="3"></circle>
|
|
64
|
-
<path d="M12 1v6m0 6v6m7.071-13.071l-4.243 4.243m0 5.656l4.243 4.243M1 12h6m6 0h6m-13.071 7.071l4.243-4.243m5.656 0l4.243 4.243"></path>
|
|
65
|
-
</svg>
|
|
66
|
-
Customize Your Experience
|
|
67
|
-
</h3>
|
|
68
|
-
|
|
69
|
-
<button type="button"
|
|
70
|
-
class="user-preferences__close"
|
|
71
|
-
data-preferences-close
|
|
72
|
-
aria-label="Close preferences">
|
|
73
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
74
|
-
width="20"
|
|
75
|
-
height="20"
|
|
76
|
-
viewBox="0 0 24 24"
|
|
77
|
-
fill="none"
|
|
78
|
-
stroke="currentColor"
|
|
79
|
-
stroke-width="2"
|
|
80
|
-
aria-hidden="true">
|
|
81
|
-
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
82
|
-
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
83
|
-
</svg>
|
|
84
|
-
</button>
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
<div class="user-preferences__content">
|
|
88
|
-
|
|
89
|
-
{%- if show_theme_toggle -%}
|
|
90
|
-
<div class="preference-section">
|
|
91
|
-
<h4 class="preference-section__title">
|
|
92
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
93
|
-
width="18"
|
|
94
|
-
height="18"
|
|
95
|
-
viewBox="0 0 24 24"
|
|
96
|
-
fill="none"
|
|
97
|
-
stroke="currentColor"
|
|
98
|
-
stroke-width="2"
|
|
99
|
-
aria-hidden="true">
|
|
100
|
-
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
|
101
|
-
</svg>
|
|
102
|
-
Theme
|
|
103
|
-
</h4>
|
|
104
|
-
|
|
105
|
-
<div class="preference-section__control">
|
|
106
|
-
<div class="theme-toggle" data-theme-control>
|
|
107
|
-
<button type="button"
|
|
108
|
-
class="theme-toggle__option"
|
|
109
|
-
data-theme="light"
|
|
110
|
-
aria-label="Light theme">
|
|
111
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
112
|
-
width="20"
|
|
113
|
-
height="20"
|
|
114
|
-
viewBox="0 0 24 24"
|
|
115
|
-
fill="none"
|
|
116
|
-
stroke="currentColor"
|
|
117
|
-
stroke-width="2">
|
|
118
|
-
<circle cx="12" cy="12" r="5"></circle>
|
|
119
|
-
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
120
|
-
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
121
|
-
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
122
|
-
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
123
|
-
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
124
|
-
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
125
|
-
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
126
|
-
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
127
|
-
</svg>
|
|
128
|
-
<span>Light</span>
|
|
129
|
-
</button>
|
|
130
|
-
|
|
131
|
-
<button type="button"
|
|
132
|
-
class="theme-toggle__option"
|
|
133
|
-
data-theme="dark"
|
|
134
|
-
aria-label="Dark theme">
|
|
135
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
136
|
-
width="20"
|
|
137
|
-
height="20"
|
|
138
|
-
viewBox="0 0 24 24"
|
|
139
|
-
fill="none"
|
|
140
|
-
stroke="currentColor"
|
|
141
|
-
stroke-width="2">
|
|
142
|
-
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
|
143
|
-
</svg>
|
|
144
|
-
<span>Dark</span>
|
|
145
|
-
</button>
|
|
146
|
-
|
|
147
|
-
<button type="button"
|
|
148
|
-
class="theme-toggle__option"
|
|
149
|
-
data-theme="auto"
|
|
150
|
-
aria-label="Auto theme (system)">
|
|
151
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
152
|
-
width="20"
|
|
153
|
-
height="20"
|
|
154
|
-
viewBox="0 0 24 24"
|
|
155
|
-
fill="none"
|
|
156
|
-
stroke="currentColor"
|
|
157
|
-
stroke-width="2">
|
|
158
|
-
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
|
159
|
-
<line x1="8" y1="21" x2="16" y2="21"></line>
|
|
160
|
-
<line x1="12" y1="17" x2="12" y2="21"></line>
|
|
161
|
-
</svg>
|
|
162
|
-
<span>Auto</span>
|
|
163
|
-
</button>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
{%- endif -%}
|
|
168
|
-
|
|
169
|
-
{%- if show_font_size -%}
|
|
170
|
-
<div class="preference-section">
|
|
171
|
-
<h4 class="preference-section__title">
|
|
172
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
173
|
-
width="18"
|
|
174
|
-
height="18"
|
|
175
|
-
viewBox="0 0 24 24"
|
|
176
|
-
fill="none"
|
|
177
|
-
stroke="currentColor"
|
|
178
|
-
stroke-width="2"
|
|
179
|
-
aria-hidden="true">
|
|
180
|
-
<polyline points="4 7 4 4 20 4 20 7"></polyline>
|
|
181
|
-
<line x1="9" y1="20" x2="15" y2="20"></line>
|
|
182
|
-
<line x1="12" y1="4" x2="12" y2="20"></line>
|
|
183
|
-
</svg>
|
|
184
|
-
Font Size
|
|
185
|
-
</h4>
|
|
186
|
-
|
|
187
|
-
<div class="preference-section__control">
|
|
188
|
-
<div class="font-size-control" data-font-size-control>
|
|
189
|
-
<button type="button"
|
|
190
|
-
class="font-size-control__button"
|
|
191
|
-
data-action="decrease"
|
|
192
|
-
aria-label="Decrease font size">
|
|
193
|
-
<span class="font-size-control__label">A-</span>
|
|
194
|
-
</button>
|
|
195
|
-
|
|
196
|
-
<div class="font-size-control__display">
|
|
197
|
-
<span data-font-size-value>100</span>%
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<button type="button"
|
|
201
|
-
class="font-size-control__button"
|
|
202
|
-
data-action="increase"
|
|
203
|
-
aria-label="Increase font size">
|
|
204
|
-
<span class="font-size-control__label">A+</span>
|
|
205
|
-
</button>
|
|
206
|
-
|
|
207
|
-
<button type="button"
|
|
208
|
-
class="font-size-control__reset"
|
|
209
|
-
data-action="reset"
|
|
210
|
-
aria-label="Reset font size">
|
|
211
|
-
Reset
|
|
212
|
-
</button>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
{%- endif -%}
|
|
217
|
-
|
|
218
|
-
{%- if show_reading_mode -%}
|
|
219
|
-
<div class="preference-section">
|
|
220
|
-
<h4 class="preference-section__title">
|
|
221
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
222
|
-
width="18"
|
|
223
|
-
height="18"
|
|
224
|
-
viewBox="0 0 24 24"
|
|
225
|
-
fill="none"
|
|
226
|
-
stroke="currentColor"
|
|
227
|
-
stroke-width="2"
|
|
228
|
-
aria-hidden="true">
|
|
229
|
-
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
|
|
230
|
-
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
|
|
231
|
-
</svg>
|
|
232
|
-
Reading Mode
|
|
233
|
-
</h4>
|
|
234
|
-
|
|
235
|
-
<div class="preference-section__control">
|
|
236
|
-
<label class="toggle-switch">
|
|
237
|
-
<input type="checkbox"
|
|
238
|
-
data-reading-mode-toggle
|
|
239
|
-
aria-label="Enable reading mode (focus mode)">
|
|
240
|
-
<span class="toggle-switch__slider"></span>
|
|
241
|
-
<span class="toggle-switch__label">
|
|
242
|
-
Focus mode (minimal distractions)
|
|
243
|
-
</span>
|
|
244
|
-
</label>
|
|
245
|
-
</div>
|
|
246
|
-
</div>
|
|
247
|
-
{%- endif -%}
|
|
248
|
-
|
|
249
|
-
{%- if show_layout -%}
|
|
250
|
-
<div class="preference-section">
|
|
251
|
-
<h4 class="preference-section__title">
|
|
252
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
253
|
-
width="18"
|
|
254
|
-
height="18"
|
|
255
|
-
viewBox="0 0 24 24"
|
|
256
|
-
fill="none"
|
|
257
|
-
stroke="currentColor"
|
|
258
|
-
stroke-width="2"
|
|
259
|
-
aria-hidden="true">
|
|
260
|
-
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
261
|
-
<line x1="9" y1="3" x2="9" y2="21"></line>
|
|
262
|
-
</svg>
|
|
263
|
-
Layout
|
|
264
|
-
</h4>
|
|
265
|
-
|
|
266
|
-
<div class="preference-section__control">
|
|
267
|
-
<div class="layout-toggle" data-layout-control>
|
|
268
|
-
<button type="button"
|
|
269
|
-
class="layout-toggle__option"
|
|
270
|
-
data-layout="default"
|
|
271
|
-
aria-label="Default layout">
|
|
272
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
273
|
-
<rect x="3" y="3" width="18" height="18" rx="2"></rect>
|
|
274
|
-
</svg>
|
|
275
|
-
<span>Default</span>
|
|
276
|
-
</button>
|
|
277
|
-
|
|
278
|
-
<button type="button"
|
|
279
|
-
class="layout-toggle__option"
|
|
280
|
-
data-layout="wide"
|
|
281
|
-
aria-label="Wide layout">
|
|
282
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
283
|
-
<rect x="2" y="6" width="20" height="12" rx="2"></rect>
|
|
284
|
-
</svg>
|
|
285
|
-
<span>Wide</span>
|
|
286
|
-
</button>
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
</div>
|
|
290
|
-
{%- endif -%}
|
|
291
|
-
|
|
292
|
-
</div>
|
|
293
|
-
|
|
294
|
-
<div class="user-preferences__footer">
|
|
295
|
-
<button type="button"
|
|
296
|
-
class="user-preferences__reset-all"
|
|
297
|
-
data-reset-all-preferences
|
|
298
|
-
aria-label="Reset all preferences to defaults">
|
|
299
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
300
|
-
width="16"
|
|
301
|
-
height="16"
|
|
302
|
-
viewBox="0 0 24 24"
|
|
303
|
-
fill="none"
|
|
304
|
-
stroke="currentColor"
|
|
305
|
-
stroke-width="2"
|
|
306
|
-
aria-hidden="true">
|
|
307
|
-
<polyline points="1 4 1 10 7 10"></polyline>
|
|
308
|
-
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
|
|
309
|
-
</svg>
|
|
310
|
-
Reset All to Defaults
|
|
311
|
-
</button>
|
|
312
|
-
</div>
|
|
313
|
-
|
|
314
|
-
</div>
|
|
315
|
-
|
|
316
|
-
<div class="user-preferences__backdrop"
|
|
317
|
-
data-preferences-backdrop
|
|
318
|
-
hidden></div>
|
|
319
|
-
</div>
|
|
320
|
-
|
|
321
|
-
<script>
|
|
322
|
-
(function() {
|
|
323
|
-
'use strict';
|
|
324
|
-
|
|
325
|
-
const STORAGE_KEY = 'userPreferences';
|
|
326
|
-
const DEFAULTS = {
|
|
327
|
-
theme: 'auto',
|
|
328
|
-
fontSize: 100,
|
|
329
|
-
readingMode: false,
|
|
330
|
-
layout: 'default'
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
class UserPreferences {
|
|
334
|
-
constructor() {
|
|
335
|
-
this.preferences = this.loadPreferences();
|
|
336
|
-
this.panel = document.querySelector('[data-user-preferences]');
|
|
337
|
-
if (!this.panel) return;
|
|
338
|
-
|
|
339
|
-
this.initElements();
|
|
340
|
-
this.attachEventListeners();
|
|
341
|
-
this.applyPreferences();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
initElements() {
|
|
345
|
-
this.trigger = this.panel.querySelector('[data-preferences-trigger]');
|
|
346
|
-
this.panelContent = this.panel.querySelector('[data-preferences-panel]');
|
|
347
|
-
this.backdrop = this.panel.querySelector('[data-preferences-backdrop]');
|
|
348
|
-
this.closeBtn = this.panel.querySelector('[data-preferences-close]');
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
attachEventListeners() {
|
|
352
|
-
// Open/close panel
|
|
353
|
-
this.trigger?.addEventListener('click', () => this.togglePanel());
|
|
354
|
-
this.closeBtn?.addEventListener('click', () => this.closePanel());
|
|
355
|
-
this.backdrop?.addEventListener('click', () => this.closePanel());
|
|
356
|
-
|
|
357
|
-
// ESC key to close
|
|
358
|
-
document.addEventListener('keydown', (e) => {
|
|
359
|
-
if (e.key === 'Escape' && !this.panelContent?.hidden) {
|
|
360
|
-
this.closePanel();
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// Theme control
|
|
365
|
-
const themeButtons = this.panel.querySelectorAll('[data-theme]');
|
|
366
|
-
themeButtons.forEach(btn => {
|
|
367
|
-
btn.addEventListener('click', (e) => {
|
|
368
|
-
const theme = e.currentTarget.dataset.theme;
|
|
369
|
-
this.setTheme(theme);
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
// Font size control
|
|
374
|
-
const fontSizeControl = this.panel.querySelector('[data-font-size-control]');
|
|
375
|
-
if (fontSizeControl) {
|
|
376
|
-
fontSizeControl.addEventListener('click', (e) => {
|
|
377
|
-
const button = e.target.closest('button');
|
|
378
|
-
if (!button) return;
|
|
379
|
-
|
|
380
|
-
const action = button.dataset.action;
|
|
381
|
-
if (action === 'increase') this.changeFontSize(10);
|
|
382
|
-
else if (action === 'decrease') this.changeFontSize(-10);
|
|
383
|
-
else if (action === 'reset') this.resetFontSize();
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Reading mode toggle
|
|
388
|
-
const readingModeToggle = this.panel.querySelector('[data-reading-mode-toggle]');
|
|
389
|
-
readingModeToggle?.addEventListener('change', (e) => {
|
|
390
|
-
this.setReadingMode(e.target.checked);
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
// Layout control
|
|
394
|
-
const layoutButtons = this.panel.querySelectorAll('[data-layout]');
|
|
395
|
-
layoutButtons.forEach(btn => {
|
|
396
|
-
btn.addEventListener('click', (e) => {
|
|
397
|
-
const layout = e.currentTarget.dataset.layout;
|
|
398
|
-
this.setLayout(layout);
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
// Reset all
|
|
403
|
-
const resetAllBtn = this.panel.querySelector('[data-reset-all-preferences]');
|
|
404
|
-
resetAllBtn?.addEventListener('click', () => this.resetAll());
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
togglePanel() {
|
|
408
|
-
const isHidden = this.panelContent.hidden;
|
|
409
|
-
if (isHidden) {
|
|
410
|
-
this.openPanel();
|
|
411
|
-
} else {
|
|
412
|
-
this.closePanel();
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
openPanel() {
|
|
417
|
-
this.panelContent.hidden = false;
|
|
418
|
-
this.backdrop.hidden = false;
|
|
419
|
-
this.trigger?.setAttribute('aria-expanded', 'true');
|
|
420
|
-
document.body.style.overflow = 'hidden';
|
|
421
|
-
|
|
422
|
-
// Focus first interactive element
|
|
423
|
-
const firstButton = this.panelContent.querySelector('button');
|
|
424
|
-
firstButton?.focus();
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
closePanel() {
|
|
428
|
-
this.panelContent.hidden = true;
|
|
429
|
-
this.backdrop.hidden = true;
|
|
430
|
-
this.trigger?.setAttribute('aria-expanded', 'false');
|
|
431
|
-
document.body.style.overflow = '';
|
|
432
|
-
this.trigger?.focus();
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
setTheme(theme) {
|
|
436
|
-
this.preferences.theme = theme;
|
|
437
|
-
this.savePreferences();
|
|
438
|
-
this.applyTheme();
|
|
439
|
-
this.updateThemeButtons();
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
applyTheme() {
|
|
443
|
-
const { theme } = this.preferences;
|
|
444
|
-
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
445
|
-
const isDark = theme === 'auto' ? prefersDark : theme === 'dark';
|
|
446
|
-
|
|
447
|
-
document.body.classList.toggle('dark-mode', isDark);
|
|
448
|
-
document.body.dataset.theme = isDark ? 'dark' : 'light';
|
|
449
|
-
document.documentElement.dataset.theme = isDark ? 'dark' : 'light';
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
updateThemeButtons() {
|
|
453
|
-
const buttons = this.panel.querySelectorAll('[data-theme]');
|
|
454
|
-
buttons.forEach(btn => {
|
|
455
|
-
const isActive = btn.dataset.theme === this.preferences.theme;
|
|
456
|
-
btn.classList.toggle('theme-toggle__option--active', isActive);
|
|
457
|
-
btn.setAttribute('aria-pressed', isActive);
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
changeFontSize(delta) {
|
|
462
|
-
const newSize = Math.max(80, Math.min(140, this.preferences.fontSize + delta));
|
|
463
|
-
this.preferences.fontSize = newSize;
|
|
464
|
-
this.savePreferences();
|
|
465
|
-
this.applyFontSize();
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
resetFontSize() {
|
|
469
|
-
this.preferences.fontSize = DEFAULTS.fontSize;
|
|
470
|
-
this.savePreferences();
|
|
471
|
-
this.applyFontSize();
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
applyFontSize() {
|
|
475
|
-
const { fontSize } = this.preferences;
|
|
476
|
-
document.documentElement.style.setProperty('--user-font-size', `${fontSize}%`);
|
|
477
|
-
|
|
478
|
-
const display = this.panel.querySelector('[data-font-size-value]');
|
|
479
|
-
if (display) display.textContent = fontSize;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
setReadingMode(enabled) {
|
|
483
|
-
this.preferences.readingMode = enabled;
|
|
484
|
-
this.savePreferences();
|
|
485
|
-
this.applyReadingMode();
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
applyReadingMode() {
|
|
489
|
-
document.body.classList.toggle('reading-mode', this.preferences.readingMode);
|
|
490
|
-
|
|
491
|
-
const toggle = this.panel.querySelector('[data-reading-mode-toggle]');
|
|
492
|
-
if (toggle) toggle.checked = this.preferences.readingMode;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
setLayout(layout) {
|
|
496
|
-
this.preferences.layout = layout;
|
|
497
|
-
this.savePreferences();
|
|
498
|
-
this.applyLayout();
|
|
499
|
-
this.updateLayoutButtons();
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
applyLayout() {
|
|
503
|
-
document.body.dataset.layout = this.preferences.layout;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
updateLayoutButtons() {
|
|
507
|
-
const buttons = this.panel.querySelectorAll('[data-layout]');
|
|
508
|
-
buttons.forEach(btn => {
|
|
509
|
-
const isActive = btn.dataset.layout === this.preferences.layout;
|
|
510
|
-
btn.classList.toggle('layout-toggle__option--active', isActive);
|
|
511
|
-
btn.setAttribute('aria-pressed', isActive);
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
resetAll() {
|
|
516
|
-
if (confirm('Reset all preferences to defaults?')) {
|
|
517
|
-
this.preferences = { ...DEFAULTS };
|
|
518
|
-
this.savePreferences();
|
|
519
|
-
this.applyPreferences();
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
applyPreferences() {
|
|
524
|
-
this.applyTheme();
|
|
525
|
-
this.applyFontSize();
|
|
526
|
-
this.applyReadingMode();
|
|
527
|
-
this.applyLayout();
|
|
528
|
-
this.updateThemeButtons();
|
|
529
|
-
this.updateLayoutButtons();
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
loadPreferences() {
|
|
533
|
-
try {
|
|
534
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
535
|
-
return stored ? { ...DEFAULTS, ...JSON.parse(stored) } : { ...DEFAULTS };
|
|
536
|
-
} catch (e) {
|
|
537
|
-
console.error('Failed to load preferences:', e);
|
|
538
|
-
return { ...DEFAULTS };
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
savePreferences() {
|
|
543
|
-
try {
|
|
544
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.preferences));
|
|
545
|
-
} catch (e) {
|
|
546
|
-
console.error('Failed to save preferences:', e);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Initialize when DOM is ready
|
|
552
|
-
if (document.readyState === 'loading') {
|
|
553
|
-
document.addEventListener('DOMContentLoaded', () => new UserPreferences());
|
|
554
|
-
} else {
|
|
555
|
-
new UserPreferences();
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// Listen for system theme changes
|
|
559
|
-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
560
|
-
const prefs = new UserPreferences();
|
|
561
|
-
if (prefs.preferences.theme === 'auto') {
|
|
562
|
-
prefs.applyTheme();
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
})();
|
|
566
|
-
</script>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{%- comment -%}
|
|
2
|
-
Decides whether the Prism assets are needed on this page. Exposes prism_enabled.
|
|
3
|
-
|
|
4
|
-
Resolution order: the page's `syntax_highlighting` front matter, then
|
|
5
|
-
`theme_options.syntax_highlighting.load`: `auto` (the default) loads Prism only
|
|
6
|
-
when the rendered page contains a code block; `always` loads it on every page.
|
|
7
|
-
{%- endcomment -%}
|
|
8
|
-
{%- assign syntax_settings = site.theme_options.syntax_highlighting | default: {} -%}
|
|
9
|
-
{%- assign syntax_load = syntax_settings.load | default: 'auto' -%}
|
|
10
|
-
{%- if page.syntax_highlighting != nil -%}
|
|
11
|
-
{%- assign prism_enabled = page.syntax_highlighting -%}
|
|
12
|
-
{%- elsif syntax_load == 'auto' -%}
|
|
13
|
-
{%- assign prism_enabled = false -%}
|
|
14
|
-
{%- if content contains '<pre' or content contains 'class="language-' or content contains 'class="highlight' -%}
|
|
15
|
-
{%- assign prism_enabled = true -%}
|
|
16
|
-
{%- endif -%}
|
|
17
|
-
{%- else -%}
|
|
18
|
-
{%- assign prism_enabled = true -%}
|
|
19
|
-
{%- endif -%}
|