jekyll-theme-chirpy 5.3.2 → 5.5.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.
@@ -51,31 +51,52 @@
51
51
  {% assign _img_content = nil %}
52
52
  {% assign _img_snippets = _content | split: IMG_TAG %}
53
53
 
54
+ <!-- CDN URL -->
55
+ {% if site.img_cdn %}
56
+ {% if site.img_cdn contains '//' %}
57
+ {% assign _path_prefix = site.img_cdn %}
58
+ {% else %}
59
+ {% assign _path_prefix = site.img_cdn | relative_url %}
60
+ {% endif %}
61
+ {% else %}
62
+ {% assign _path_prefix = site.baseurl %}
63
+ {% endif %}
64
+
65
+ <!-- Add image path -->
66
+ {% if page.img_path %}
67
+ {% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
68
+ {% assign _path_prefix = _path_prefix | append: _path %}
69
+ {% endif %}
70
+
54
71
  {% for _img_snippet in _img_snippets %}
55
72
  {% if forloop.first %}
56
73
  {% assign _img_content = _img_snippet %}
57
74
  {% continue %}
58
75
  {% endif %}
59
76
 
60
- {% assign _width = nil %}
61
- {% assign _height = nil %}
62
- {% assign _src = nil %}
63
-
64
77
  {% assign _left = _img_snippet | split: '>' | first %}
65
78
  {% assign _right = _img_snippet | remove: _left %}
66
79
 
67
- {% assign _left = _left | remove: ' /' %}
68
- {% assign _left = _left | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
69
- {% assign _attrs = _left | split: ' ' %}
80
+ {% unless _left contains 'src=' %}
81
+ {% continue %}
82
+ {% endunless %}
83
+
84
+ {% assign _left = _left | remove: ' /' | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
85
+ {% assign _attrs = _left | split: '" ' %}
86
+
87
+ {% assign _width = nil %}
88
+ {% assign _height = nil %}
89
+ {% assign _lqip = nil %}
90
+ {% assign _class = nil %}
70
91
 
71
92
  {% for _attr in _attrs %}
72
- {% assign _pair = _attr | split: '=' %}
73
- {% if _pair.size < 2 %}
93
+ {% unless _attr contains '=' %}
74
94
  {% continue %}
75
- {% endif %}
95
+ {% endunless %}
76
96
 
97
+ {% assign _pair = _attr | remove: '"' | split: '=' %}
77
98
  {% capture _key %}{{ _pair | first }}{% endcapture %}
78
- {% capture _value %}{{ _pair | last | replace: '"', '' }}{% endcapture %}
99
+ {% capture _value %}{{ _pair | last }}{% endcapture %}
79
100
 
80
101
  {% case _key %}
81
102
  {% when 'width' %}
@@ -84,62 +105,91 @@
84
105
  {% assign _height = _value %}
85
106
  {% when 'src' %}
86
107
  {% assign _src = _value %}
108
+ {% when 'lqip' %}
109
+ {% assign _lqip = _value %}
110
+ {% when 'class' %}
111
+ {% assign _class = _value %}
87
112
  {% endcase %}
88
113
 
89
- {% if _width and _height and _src %}
90
- {% break %}
91
- {% endif %}
92
114
  {% endfor %}
93
115
 
94
- {% if _src %}
95
- {% unless _src contains '://' %}
96
-
97
- <!-- Add CDN URL -->
98
- {% if site.img_cdn %}
99
- {% if site.img_cdn contains '//' %}
100
- {% assign _src_prefix = site.img_cdn %}
101
- {% else %}
102
- {% assign _src_prefix = site.img_cdn | relative_url %}
103
- {% endif %}
104
- {% else %}
105
- {% assign _src_prefix = site.baseurl %}
106
- {% endif %}
107
-
108
- <!-- Add image path -->
109
- {% if page.img_path %}
110
- {% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
111
- {% assign _src_prefix = _src_prefix | append: _path %}
112
- {% endif %}
113
-
114
- {% assign _final_src = _src_prefix | append: _src %}
115
- {% assign _left = _left | replace: _src, _final_src %}
116
-
117
- {% endunless %}
116
+ <!-- take out classes -->
117
+ {% if _class %}
118
+ {% capture _old_class %}class="{{ _class }}"{% endcapture %}
119
+ {% assign _left = _left | remove: _old_class %}
120
+ {% endif %}
118
121
 
119
- <!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
122
+ {% assign _final_src = nil %}
120
123
 
121
- {% assign _left = _left | replace: 'src=', 'data-src=' %}
124
+ {% unless _src contains '//' %}
125
+ {% assign _final_src = _path_prefix | append: _src %}
126
+ {% capture _src_from %}"{{ _src }}"{% endcapture %}
127
+ {% capture _src_to %}"{{ _final_src }}"{% endcapture %}
128
+ {% assign _left = _left | replace: _src_from, _src_to %}
129
+ {% endunless %}
122
130
 
131
+ {% if _lqip %}
132
+ {% unless _lqip contains ':' %}
133
+ {% assign _final_lqip = _path_prefix | append: _lqip %}
134
+ {% capture _lqip_from %}"{{ _lqip }}"{% endcapture %}
135
+ {% capture _lqip_to %}"{{ _final_lqip }}"{% endcapture %}
136
+ {% assign _left = _left | replace: _lqip_from, _lqip_to %}
137
+ {% endunless %}
123
138
  {% endif %}
124
139
 
125
- <!-- Add SVG placehoder to prevent layout reflow -->
126
-
127
- {% if _width and _height %}
128
- {%- capture _svg -%}
129
- src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
130
- {%- endcapture -%}
140
+ <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
141
+ {% assign _left = _left | replace: 'src=', 'data-src=' %}
142
+ {% if _left contains 'class=' %}
143
+ {% assign _left = _left | replace: 'class="', 'class="lazyload '%}
144
+ {% else %}
145
+ {% assign _left = _left | append: ' class="lazyload"' %}
146
+ {% endif %}
131
147
 
132
- {% assign _left = _svg | append: ' ' | append: _left %}
148
+ <!-- add image placeholder -->
149
+ {% if _lqip %}
150
+ {% assign _left = _left | replace: ' lqip=', ' data-lqip="true" src=' %}
151
+ {% else %}
152
+ {% if _width and _height %}
153
+ <!-- add SVG placehoder -->
154
+ {%- capture _svg -%}
155
+ src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
156
+ {%- endcapture -%}
157
+ {% assign _left = _svg | append: ' ' | append: _left %}
158
+ {% assign _class = _class | append: ' shimmer' %}
159
+ {% endif %}
133
160
  {% endif %}
134
161
 
135
162
  <!-- Bypass the HTML-proofer test -->
136
163
  {% assign _left = _left | append: ' data-proofer-ignore' %}
137
164
 
165
+ <!-- make sure the `<img>` is wrapped by `<a>` -->
166
+ {% assign _parent = _right | slice: 1, 4 %}
167
+
168
+ {% if _parent == '</a>' %}
169
+ <!-- add class to exist <a> tag -->
170
+ {% assign _size = _img_content | size | minus: 1 %}
171
+ {% capture _class %}
172
+ class="img-link{% unless _lqip %} shimmer{% endunless %}"
173
+ {% endcapture %}
174
+ {% assign _img_content = _img_content | slice: 0, _size | append: _class | append: '>' %}
175
+
176
+ {% else %}
177
+ <!-- create the image wrapper -->
178
+ {%- capture _wrapper_start -%}
179
+ <a href="{{ _final_src | default: _src }}" class="popup img-link {{ _class }}">
180
+ {%- endcapture -%}
181
+ {% assign _img_content = _img_content | append: _wrapper_start %}
182
+ {% assign _right = _right | prepend: '></a' %}
183
+ {% endif %}
184
+
185
+ <!-- combine -->
138
186
  {% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
139
187
 
140
188
  {% endfor %}
141
189
 
142
- {% assign _content = _img_content %}
190
+ {% if _img_content %}
191
+ {% assign _content = _img_content %}
192
+ {% endif %}
143
193
 
144
194
  {% endif %}
145
195
 
@@ -227,54 +277,6 @@
227
277
 
228
278
  {% assign _content = _heading_content %}
229
279
 
230
- <!-- Wrap prompt element of blockquote with the <div> tag -->
231
-
232
- {% assign blockquote_start = '<blockquote class=' %}
233
- {% assign blockquote_end = '</blockquote>' %}
234
- {% assign cls_prefix = 'prompt-' %}
235
-
236
- {% if _content contains blockquote_start %}
237
-
238
- {% assign _prompt_content = nil %}
239
- {% assign _prompt_snippets = _content | split: blockquote_start %}
240
-
241
- {% for _snippet in _prompt_snippets %}
242
-
243
- {% if forloop.first %}
244
- {% assign _prompt_content = _snippet %}
245
- {% continue %}
246
- {% endif %}
247
-
248
- {% assign left = _snippet | split: blockquote_end | first %}
249
- {% assign right = _snippet | slice: left.size, _snippet.size %}
250
-
251
- {% assign cls_str = left | split: '>' | first %}
252
- {% assign cls_array = cls_str | remove: '"' | split: ' ' %}
253
- {% assign is_prompt = false %}
254
-
255
- {% for cls in cls_array %}
256
- {% if cls contains cls_prefix %}
257
- {% assign is_prompt = true %}
258
- {% break %}
259
- {% endif %}
260
- {% endfor %}
261
-
262
- {% unless is_prompt %}
263
- {% assign _prompt_content = _prompt_content | append: blockquote_start | append: _snippet %}
264
- {% continue %}
265
- {% endunless %}
266
-
267
- {% assign left = left | slice: cls_str.size, left.size %}
268
- {% assign left = cls_str | append: '><div' | append: left | append: '</div>' %}
269
-
270
- {% assign _prompt_content = _prompt_content | append: blockquote_start | append: left | append: right %}
271
-
272
- {% endfor %}
273
-
274
- {% assign _content = _prompt_content %}
275
-
276
- {% endif %}
277
-
278
280
  <!-- return -->
279
281
 
280
282
  {{ _content }}
@@ -81,7 +81,17 @@
81
81
 
82
82
  {% if url %}
83
83
  <a href="{{ url }}" aria-label="{{ entry.type }}"
84
- {% unless entry.noblank %}target="_blank" rel="noopener"{% endunless %}>
84
+ {% assign link_types = nil %}
85
+ {% unless entry.noblank %}
86
+ {% assign link_types = link_types | append: " noopener" %}
87
+ target="_blank"
88
+ {% endunless %}
89
+
90
+ {% if entry.type == 'mastodon' %}
91
+ {% assign link_types = link_types | append: " me" %}
92
+ {% endif %}
93
+
94
+ {% if link_types %}rel="{{ link_types | lstrip }}"{% endif %}>
85
95
  <i class="{{ entry.icon }}"></i>
86
96
  </a>
87
97
  {% endif %}
data/_layouts/post.html CHANGED
@@ -27,30 +27,21 @@ tail_includes:
27
27
  {% endif %}
28
28
 
29
29
  {% if page.image %}
30
- {% capture bg %}
31
- {% unless page.image.no_bg %}{{ 'bg' }}{% endunless %}
32
- {% endcapture %}
33
-
34
- <div class="mt-3 mb-3">
35
- <img src="{{ page.image.path | default: page.image }}" class="preview-img {{ bg | strip }}"
36
- alt="{{ page.image.alt | default: "Preview Image" }}"
30
+ {% capture src %}src="{{ page.image.path | default: page.image }}"{% endcapture %}
31
+ {% capture class %}class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"{% endcapture %}
32
+ {% capture alt %}alt="{{ page.image.alt | default: "Preview Image" }}"{% endcapture %}
37
33
 
38
- {% if page.image.width %}
39
- width="{{ page.image.width }}"
40
- {% elsif page.image.w %}
41
- width="{{ page.image.w }}"
34
+ {% capture lqip %}
35
+ {% if page.image.lqip %}
36
+ lqip="{{ page.image.lqip }}"
42
37
  {% endif %}
38
+ {% endcapture %}
43
39
 
44
- {% if page.image.height %}
45
- height="{{ page.image.height }}"
46
- {% elsif page.image.h %}
47
- height="{{ page.image.h }}"
48
- {% endif %}>
49
-
50
- {% if page.image.alt %}
40
+ <div class="mt-3 mb-3">
41
+ <img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip | strip }}>
42
+ {%- if page.image.alt -%}
51
43
  <figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
52
- {% endif %}
53
-
44
+ {%- endif -%}
54
45
  </div>
55
46
  {% endif %}
56
47
 
@@ -83,6 +83,46 @@ a {
83
83
  img {
84
84
  max-width: 100%;
85
85
  height: auto;
86
+
87
+ &[data-src] {
88
+ &.lazyloaded {
89
+ -webkit-animation: fade-in 0.4s ease-in;
90
+ animation: fade-in 0.4s ease-in;
91
+ }
92
+
93
+ &[data-lqip="true"] {
94
+ &.lazyload,
95
+ &.lazyloading {
96
+ -webkit-filter: blur(20px);
97
+ filter: blur(20px);
98
+ }
99
+ }
100
+
101
+ &:not([data-lqip="true"]) {
102
+ &.lazyload,
103
+ &.lazyloading {
104
+ background: var(--img-bg);
105
+ }
106
+ }
107
+
108
+ &.shadow {
109
+ -webkit-filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
110
+ filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
111
+ box-shadow: none !important; /* cover the Bootstrap 4.6.1 styles */
112
+ }
113
+
114
+ @extend %img-caption;
115
+ }
116
+
117
+ @-webkit-keyframes fade-in {
118
+ from { opacity: 0; }
119
+ to { opacity: 1; }
120
+ }
121
+
122
+ @keyframes fade-in {
123
+ from { opacity: 0; }
124
+ to { opacity: 1; }
125
+ }
86
126
  }
87
127
 
88
128
  blockquote {
@@ -91,29 +131,28 @@ blockquote {
91
131
  color: var(--blockquote-text-color);
92
132
 
93
133
  &[class^="prompt-"] {
94
- display: flex;
95
134
  border-left: 0;
96
- border-radius: 6px;
97
- padding: 1rem;
135
+ padding: 1rem 1rem 1rem 3rem;
98
136
  color: var(--prompt-text-color);
99
137
 
138
+ @extend %rounded;
139
+
100
140
  &::before {
101
- font-family: "Font Awesome 5 Free";
102
141
  text-align: center;
103
142
  width: 1.25rem;
104
- margin-right: 0.75rem;
143
+ position: absolute;
144
+ left: 2.5rem;
145
+ margin-top: 0.4rem;
146
+ text-rendering: auto;
147
+ -webkit-font-smoothing: antialiased;
105
148
  }
106
149
 
107
- > div {
108
- max-width: calc(100% - 2rem);
109
-
110
- > :last-child {
111
- margin-bottom: 0;
112
- }
150
+ > p:last-child {
151
+ margin-bottom: 0;
113
152
  }
114
153
  }
115
154
 
116
- @include prompt("tip", "\f0eb", 400);
155
+ @include prompt("tip", "\f0eb", "regular");
117
156
  @include prompt("info", "\f06a");
118
157
  @include prompt("warning", "\f06a");
119
158
  @include prompt("danger", "\f071");
@@ -180,43 +219,6 @@ i { /* fontawesome icons */
180
219
  }
181
220
  }
182
221
 
183
- @-webkit-keyframes fade-in {
184
- from { opacity: 0; }
185
- to { opacity: 1; }
186
- }
187
-
188
- @keyframes fade-in {
189
- from { opacity: 0; }
190
- to { opacity: 1; }
191
- }
192
-
193
- img[data-src] {
194
- margin: 0.5rem 0;
195
-
196
- &[data-loaded="true"] {
197
- -webkit-animation: fade-in linear 0.5s;
198
- animation: fade-in linear 0.5s;
199
- }
200
-
201
- &.left {
202
- float: left;
203
- margin: 0.75rem 1rem 1rem 0;
204
- }
205
-
206
- &.right {
207
- float: right;
208
- margin: 0.75rem 0 1rem 1rem;
209
- }
210
-
211
- &.shadow {
212
- -webkit-filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
213
- filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.08));
214
- box-shadow: none !important; /* cover the Bootstrap 4.6.1 styles */
215
- }
216
-
217
- @extend %img-caption;
218
- }
219
-
220
222
  /* --- Panels --- */
221
223
 
222
224
  .access {
@@ -397,26 +399,14 @@ img[data-src] {
397
399
  margin-bottom: 1.5rem;
398
400
  }
399
401
 
400
- a {
401
- &.img-link {
402
- @extend %no-cursor;
403
- }
404
-
405
- /* created by `_includes/img-extra.html` */
406
- &.popup {
407
- cursor: zoom-in;
408
-
409
- > img[data-src]:not(.normal):not(.left):not(.right) {
402
+ p {
403
+ > img[data-src],
404
+ > a.popup {
405
+ &:not(.normal):not(.left):not(.right) {
410
406
  @include align-center;
411
407
  }
412
408
  }
413
-
414
- &:hover {
415
- code {
416
- @extend %link-hover;
417
- }
418
- }
419
- } /* a */
409
+ }
420
410
  }
421
411
 
422
412
  .pageviews .fa-spinner {
@@ -448,6 +438,14 @@ img[data-src] {
448
438
  overflow-wrap: break-word;
449
439
 
450
440
  a {
441
+ &.popup {
442
+ @extend %no-cursor;
443
+ @extend %img-caption;
444
+ @include mt-mb(0.5rem);
445
+
446
+ cursor: zoom-in;
447
+ }
448
+
451
449
  &:not(.img-link) {
452
450
  @extend %link-underline;
453
451
 
@@ -455,10 +453,6 @@ img[data-src] {
455
453
  @extend %link-hover;
456
454
  }
457
455
  }
458
-
459
- &.img-link {
460
- @extend %img-caption;
461
- }
462
456
  }
463
457
 
464
458
  ol,
@@ -544,6 +538,58 @@ img[data-src] {
544
538
  }
545
539
  }
546
540
 
541
+ .rounded-10 {
542
+ border-radius: 10px !important;
543
+ }
544
+
545
+ .img-link {
546
+ color: transparent;
547
+ display: inline-flex;
548
+ overflow: hidden;
549
+ }
550
+
551
+ .shimmer {
552
+ overflow: hidden;
553
+ position: relative;
554
+ background: var(--img-bg);
555
+
556
+ &::before {
557
+ content: "";
558
+ position: absolute;
559
+ background: var(--shimmer-bg);
560
+ height: 100%;
561
+ width: 100%;
562
+ -webkit-animation: shimmer 1s infinite;
563
+ animation: shimmer 1s infinite;
564
+ }
565
+
566
+ @-webkit-keyframes shimmer {
567
+ 0% { -webkit-transform: translateX(-100%); transform: translateX(-100%); }
568
+ 100% { -webkit-transform: translateX(100%); transform: translateX(100%); }
569
+ }
570
+
571
+ @keyframes shimmer {
572
+ 0% { -webkit-transform: translateX(-100%); transform: translateX(-100%); }
573
+ 100% { -webkit-transform: translateX(100%); transform: translateX(100%); }
574
+ }
575
+ }
576
+
577
+ .embed-video {
578
+ width: 100%;
579
+ height: 100%;
580
+ margin-bottom: 1rem;
581
+
582
+ @extend %rounded;
583
+
584
+ &.youtube {
585
+ aspect-ratio: 16 / 9;
586
+ }
587
+
588
+ &.twitch {
589
+ aspect-ratio: 310 / 189;
590
+ }
591
+ }
592
+
547
593
  /* --- buttons --- */
548
594
  .btn-lang {
549
595
  border: 1px solid !important;
@@ -613,6 +659,16 @@ img[data-src] {
613
659
  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
614
660
  }
615
661
 
662
+ .left {
663
+ float: left;
664
+ margin: 0.75rem 1rem 1rem 0 !important;
665
+ }
666
+
667
+ .right {
668
+ float: right;
669
+ margin: 0.75rem 0 1rem 1rem !important;
670
+ }
671
+
616
672
  /* --- Overriding --- */
617
673
 
618
674
  /* magnific-popup */
@@ -754,7 +810,7 @@ $sidebar-display: "sidebar-display";
754
810
  &:last-child {
755
811
  a {
756
812
  position: relative;
757
- left: $cursor-width / 2;
813
+ left: calc($cursor-width / 2);
758
814
  width: 100%;
759
815
  }
760
816
 
@@ -780,7 +836,7 @@ $sidebar-display: "sidebar-display";
780
836
 
781
837
  @for $i from 1 through $tab-count {
782
838
  $offset: $tab-count - $i;
783
- $top: -$offset * $tab-height + ($tab-height - $tab-cursor-height) / 2;
839
+ $top: (-$offset * $tab-height) + (($tab-height - $tab-cursor-height) * 0.5);
784
840
 
785
841
  @if $i < $tab-count {
786
842
  > li.active:nth-child(#{$i}),
@@ -1193,6 +1249,7 @@ $sidebar-display: "sidebar-display";
1193
1249
 
1194
1250
  div.d-flex {
1195
1251
  padding: 1.5rem 0;
1252
+ line-height: 1.65;
1196
1253
  flex-wrap: wrap;
1197
1254
  justify-content: space-around !important;
1198
1255
  }
@@ -1217,11 +1274,14 @@ $sidebar-display: "sidebar-display";
1217
1274
 
1218
1275
  .post-content {
1219
1276
  > blockquote[class^="prompt-"] {
1220
- @include pl-pr(1.25rem);
1221
1277
  @include ml-mr(-1.25rem);
1222
1278
 
1223
1279
  border-radius: 0;
1224
1280
  max-width: none;
1281
+
1282
+ &::before {
1283
+ left: 1rem;
1284
+ }
1225
1285
  }
1226
1286
  }
1227
1287
  }
@@ -90,6 +90,10 @@
90
90
  font-style: normal;
91
91
  }
92
92
 
93
+ %rounded {
94
+ border-radius: 6px;
95
+ }
96
+
93
97
  %img-caption {
94
98
  + em {
95
99
  display: block;
@@ -114,6 +118,11 @@
114
118
  text-decoration: none;
115
119
  }
116
120
 
121
+ @mixin mt-mb($value) {
122
+ margin-top: $value;
123
+ margin-bottom: $value;
124
+ }
125
+
117
126
  @mixin ml-mr($value) {
118
127
  margin-left: $value;
119
128
  margin-right: $value;
@@ -141,14 +150,14 @@
141
150
  transform: translateX(-50%);
142
151
  }
143
152
 
144
- @mixin prompt($type, $fw-icon, $icon-weight: 900) {
153
+ @mixin prompt($type, $fa-content, $fa-style: "solid") {
145
154
  &.prompt-#{$type} {
146
155
  background-color: var(--prompt-#{$type}-bg);
147
156
 
148
157
  &::before {
149
- content: $fw-icon;
158
+ content: $fa-content;
150
159
  color: var(--prompt-#{$type}-icon-color);
151
- font-weight: $icon-weight;
160
+ font: var(--fa-font-#{$fa-style});
152
161
  }
153
162
  }
154
163
  }