jekyll-theme-chirpy 5.3.2 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }