@vuepress/plugin-pwa 2.0.0-rc.14 → 2.0.0-rc.17
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.
- package/lib/client/components/PwaFoundPopup.d.ts +21 -0
- package/lib/client/components/PwaFoundPopup.js +56 -0
- package/lib/client/components/PwaInstall.d.ts +16 -0
- package/lib/client/components/PwaInstall.js +85 -0
- package/lib/client/components/PwaInstallModal.d.ts +33 -0
- package/lib/client/components/PwaInstallModal.js +169 -0
- package/lib/client/components/PwaReadyPopup.d.ts +21 -0
- package/lib/client/components/PwaReadyPopup.js +50 -0
- package/lib/client/components/icons.d.ts +9 -0
- package/lib/client/components/icons.js +25 -0
- package/lib/client/components/index.d.ts +3 -0
- package/lib/client/components/index.js +3 -0
- package/lib/client/composables/index.d.ts +2 -1
- package/lib/client/composables/index.js +2 -1
- package/lib/client/composables/setupPwa.d.ts +1 -0
- package/lib/client/composables/setupPwa.js +28 -0
- package/lib/client/composables/usePwaEvent.js +2 -3
- package/lib/client/composables/useRegisterSW.d.ts +2 -0
- package/lib/client/composables/useRegisterSW.js +29 -0
- package/lib/client/index.d.ts +2 -0
- package/lib/client/index.js +2 -0
- package/lib/client/styles/modal.css +402 -0
- package/lib/client/styles/popup.css +66 -0
- package/lib/client/styles/vars.css +12 -0
- package/lib/client/utils/forceUpdate.d.ts +6 -0
- package/lib/client/utils/forceUpdate.js +16 -0
- package/lib/client/utils/index.d.ts +4 -0
- package/lib/client/utils/index.js +4 -0
- package/lib/client/utils/registerSW.d.ts +15 -0
- package/lib/client/utils/registerSW.js +57 -0
- package/lib/client/utils/skipWaiting.d.ts +6 -0
- package/lib/client/utils/skipWaiting.js +15 -0
- package/lib/client/utils/unregisterSW.d.ts +10 -0
- package/lib/client/utils/unregisterSW.js +24 -0
- package/lib/node/generateManifest.d.ts +3 -0
- package/lib/node/generateManifest.js +12 -0
- package/lib/node/generateServiceWorker.d.ts +2 -3
- package/lib/node/generateServiceWorker.js +50 -23
- package/lib/node/getManifest.d.ts +4 -0
- package/lib/node/getManifest.js +31 -0
- package/lib/node/helper.d.ts +4 -0
- package/lib/node/helper.js +38 -0
- package/lib/node/index.d.ts +3 -4
- package/lib/node/index.js +3 -4
- package/lib/node/injectLinksToHead.d.ts +3 -0
- package/lib/node/injectLinksToHead.js +64 -0
- package/lib/node/locales.d.ts +3 -0
- package/lib/node/locales.js +263 -0
- package/lib/node/logger.d.ts +3 -0
- package/lib/node/logger.js +3 -0
- package/lib/node/options.d.ts +183 -0
- package/lib/node/options.js +1 -0
- package/lib/node/prepareConfigFile.d.ts +3 -0
- package/lib/node/prepareConfigFile.js +46 -0
- package/lib/node/pwaPlugin.d.ts +3 -17
- package/lib/node/pwaPlugin.js +50 -14
- package/lib/shared/index.d.ts +2 -0
- package/lib/shared/index.js +2 -0
- package/lib/shared/locales.d.ts +70 -0
- package/lib/shared/locales.js +1 -0
- package/lib/shared/manifest.d.ts +129 -0
- package/lib/shared/manifest.js +2 -0
- package/package.json +14 -6
- package/lib/client/composables/useSkipWaiting.d.ts +0 -4
- package/lib/client/composables/useSkipWaiting.js +0 -13
- package/lib/client/config.d.ts +0 -3
- package/lib/client/config.js +0 -50
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
@keyframes pwa-opened {
|
|
2
|
+
from {
|
|
3
|
+
opacity: 0.4;
|
|
4
|
+
transform: scale(0.8, 0.8);
|
|
5
|
+
}
|
|
6
|
+
to {
|
|
7
|
+
opacity: 1;
|
|
8
|
+
transform: scale(1, 1);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
@keyframes pwa-mobile {
|
|
12
|
+
from {
|
|
13
|
+
opacity: 0.6;
|
|
14
|
+
}
|
|
15
|
+
to {
|
|
16
|
+
opacity: 1;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
@keyframes pwa-fade-in {
|
|
20
|
+
from {
|
|
21
|
+
opacity: 0.2;
|
|
22
|
+
}
|
|
23
|
+
to {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
.modal-button {
|
|
28
|
+
position: fixed;
|
|
29
|
+
right: 1rem;
|
|
30
|
+
bottom: 1rem;
|
|
31
|
+
z-index: 50;
|
|
32
|
+
padding: 0 16px;
|
|
33
|
+
border-width: 0;
|
|
34
|
+
border-radius: 1.2rem;
|
|
35
|
+
background: var(--pwa-btn-bg-color);
|
|
36
|
+
color: var(--pwa-btn-text-color);
|
|
37
|
+
outline: none;
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
line-height: 2.2rem;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
transition: background 0.3s, color 0.3s;
|
|
42
|
+
}
|
|
43
|
+
@media (display-mode: standalone) {
|
|
44
|
+
.modal-button {
|
|
45
|
+
display: none;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
@media print {
|
|
49
|
+
.modal-button {
|
|
50
|
+
display: none;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
.modal-button:hover, .modal-button:active {
|
|
54
|
+
background: var(--pwa-btn-hover-bg-color);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#install-modal-wrapper {
|
|
58
|
+
position: fixed;
|
|
59
|
+
top: 0;
|
|
60
|
+
left: 0;
|
|
61
|
+
z-index: 997;
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: center;
|
|
65
|
+
overflow: auto;
|
|
66
|
+
width: 100vw;
|
|
67
|
+
height: 100vh;
|
|
68
|
+
}
|
|
69
|
+
@media print {
|
|
70
|
+
#install-modal-wrapper {
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
#install-modal-wrapper button {
|
|
75
|
+
border-width: 0;
|
|
76
|
+
background: transparent;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
}
|
|
79
|
+
#install-modal-wrapper .background {
|
|
80
|
+
position: fixed;
|
|
81
|
+
inset: 0;
|
|
82
|
+
z-index: 998;
|
|
83
|
+
animation: 0.25s pwa-fade-in;
|
|
84
|
+
backdrop-filter: blur(10px);
|
|
85
|
+
}
|
|
86
|
+
#install-modal-wrapper .install-modal {
|
|
87
|
+
position: absolute;
|
|
88
|
+
z-index: 999;
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-direction: column;
|
|
91
|
+
max-width: 56em;
|
|
92
|
+
border-radius: 10px;
|
|
93
|
+
background: var(--pwa-bg-color);
|
|
94
|
+
transition: background 0.3s;
|
|
95
|
+
animation: 0.15s pwa-opened;
|
|
96
|
+
}
|
|
97
|
+
@media (max-width: 1280px) {
|
|
98
|
+
#install-modal-wrapper .install-modal {
|
|
99
|
+
width: 92%;
|
|
100
|
+
animation: 0.25s pwa-mobile;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
@media (max-width: 419px) {
|
|
104
|
+
#install-modal-wrapper .install-modal {
|
|
105
|
+
overflow-y: auto;
|
|
106
|
+
max-height: 80%;
|
|
107
|
+
}
|
|
108
|
+
#install-modal-wrapper .install-modal::-webkit-scrollbar {
|
|
109
|
+
display: none;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
#install-modal-wrapper .header {
|
|
113
|
+
margin: 40px 40px 32px;
|
|
114
|
+
}
|
|
115
|
+
@media (max-width: 959px) {
|
|
116
|
+
#install-modal-wrapper .header {
|
|
117
|
+
margin-bottom: 24px;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
@media (max-width: 719px) {
|
|
121
|
+
#install-modal-wrapper .header {
|
|
122
|
+
margin: 20px;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
#install-modal-wrapper .header .close-button {
|
|
126
|
+
border-width: 0;
|
|
127
|
+
float: right;
|
|
128
|
+
background: transparent;
|
|
129
|
+
color: var(--pwa-content-color);
|
|
130
|
+
transition: color 0.3s ease;
|
|
131
|
+
cursor: pointer;
|
|
132
|
+
}
|
|
133
|
+
#install-modal-wrapper .header .close-button:hover, #install-modal-wrapper .header .close-button:focus {
|
|
134
|
+
color: var(--pwa-content-light-color);
|
|
135
|
+
}
|
|
136
|
+
#install-modal-wrapper .header .logo {
|
|
137
|
+
display: flex;
|
|
138
|
+
}
|
|
139
|
+
#install-modal-wrapper .header h1 {
|
|
140
|
+
margin-top: 0;
|
|
141
|
+
margin-bottom: 7px;
|
|
142
|
+
color: var(--pwa-content-light-color);
|
|
143
|
+
font-size: 34px;
|
|
144
|
+
}
|
|
145
|
+
@media (max-width: 959px) {
|
|
146
|
+
#install-modal-wrapper .header h1 {
|
|
147
|
+
margin-bottom: 0;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
@media (max-width: 419px) {
|
|
151
|
+
#install-modal-wrapper .header h1 {
|
|
152
|
+
font-size: 26px;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
#install-modal-wrapper .header img {
|
|
156
|
+
width: 122px;
|
|
157
|
+
height: 122px;
|
|
158
|
+
margin-inline-end: 24px;
|
|
159
|
+
padding: 12px;
|
|
160
|
+
border-radius: 24px;
|
|
161
|
+
}
|
|
162
|
+
@media (max-width: 959px) {
|
|
163
|
+
#install-modal-wrapper .header img {
|
|
164
|
+
width: 60px;
|
|
165
|
+
height: 60px;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
@media (max-width: 719px) {
|
|
169
|
+
#install-modal-wrapper .header img {
|
|
170
|
+
margin-inline-end: 12px;
|
|
171
|
+
padding: 8px;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
@media (max-width: 419px) {
|
|
175
|
+
#install-modal-wrapper .header img {
|
|
176
|
+
width: 40px;
|
|
177
|
+
height: 40px;
|
|
178
|
+
padding: 6px;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
#install-modal-wrapper .header .desc {
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
max-width: 40em;
|
|
184
|
+
color: #888;
|
|
185
|
+
font-size: 14px;
|
|
186
|
+
text-overflow: ellipsis;
|
|
187
|
+
white-space: pre-wrap;
|
|
188
|
+
}
|
|
189
|
+
@media (max-width: 959px) {
|
|
190
|
+
#install-modal-wrapper .header .desc {
|
|
191
|
+
display: none;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
#install-modal-wrapper .content {
|
|
195
|
+
flex: 1;
|
|
196
|
+
margin: 0 40px;
|
|
197
|
+
color: var(--pwa-content-color);
|
|
198
|
+
}
|
|
199
|
+
@media (max-width: 719px) {
|
|
200
|
+
#install-modal-wrapper .content {
|
|
201
|
+
margin: 0 20px;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
#install-modal-wrapper .content h3 {
|
|
205
|
+
margin-bottom: 12px;
|
|
206
|
+
font-size: 22px;
|
|
207
|
+
}
|
|
208
|
+
#install-modal-wrapper .content p {
|
|
209
|
+
font-size: 14px;
|
|
210
|
+
}
|
|
211
|
+
#install-modal-wrapper .highlight {
|
|
212
|
+
display: flex;
|
|
213
|
+
align-items: center;
|
|
214
|
+
justify-content: space-around;
|
|
215
|
+
margin-inline-end: 20px;
|
|
216
|
+
}
|
|
217
|
+
@media (max-width: 719px) {
|
|
218
|
+
#install-modal-wrapper .highlight {
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
align-items: flex-start;
|
|
221
|
+
margin-inline-end: 0;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
#install-modal-wrapper .highlight h3 {
|
|
225
|
+
margin-top: 0;
|
|
226
|
+
font-weight: 600;
|
|
227
|
+
font-size: 22px;
|
|
228
|
+
line-height: 225%;
|
|
229
|
+
}
|
|
230
|
+
@media (max-width: 419px) {
|
|
231
|
+
#install-modal-wrapper .highlight h3 {
|
|
232
|
+
margin-bottom: 0;
|
|
233
|
+
font-size: 18px;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
#install-modal-wrapper .feature-wrapper {
|
|
237
|
+
overflow: hidden;
|
|
238
|
+
padding-inline-end: 2em;
|
|
239
|
+
}
|
|
240
|
+
#install-modal-wrapper .feature-wrapper ul {
|
|
241
|
+
margin-block-start: 12px;
|
|
242
|
+
padding-inline-start: 22px;
|
|
243
|
+
}
|
|
244
|
+
@media (max-width: 419px) {
|
|
245
|
+
#install-modal-wrapper .feature-wrapper ul {
|
|
246
|
+
margin-top: 0;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
#install-modal-wrapper .feature-wrapper li {
|
|
250
|
+
color: var(--pwa-content-light-color);
|
|
251
|
+
font-weight: 600;
|
|
252
|
+
font-size: 16px;
|
|
253
|
+
line-height: 29px;
|
|
254
|
+
transition: color 0.3s;
|
|
255
|
+
}
|
|
256
|
+
#install-modal-wrapper .screenshot-wrapper {
|
|
257
|
+
display: flex;
|
|
258
|
+
max-width: 30em;
|
|
259
|
+
max-height: 220px;
|
|
260
|
+
}
|
|
261
|
+
@media (max-width: 719px) {
|
|
262
|
+
#install-modal-wrapper .screenshot-wrapper {
|
|
263
|
+
width: 100%;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
#install-modal-wrapper .screenshot-wrapper button {
|
|
267
|
+
width: 4em;
|
|
268
|
+
border-width: 0;
|
|
269
|
+
background: transparent;
|
|
270
|
+
cursor: pointer;
|
|
271
|
+
transition: background 0.3s;
|
|
272
|
+
}
|
|
273
|
+
#install-modal-wrapper .screenshot-wrapper button:hover, #install-modal-wrapper .screenshot-wrapper button:focus {
|
|
274
|
+
background: #bbb;
|
|
275
|
+
}
|
|
276
|
+
#install-modal-wrapper .screenshot-wrapper button svg {
|
|
277
|
+
width: 28px;
|
|
278
|
+
fill: #6b6969;
|
|
279
|
+
}
|
|
280
|
+
#install-modal-wrapper .screenshot {
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-flow: column wrap;
|
|
283
|
+
overflow-x: auto;
|
|
284
|
+
-webkit-overflow-scrolling: touch;
|
|
285
|
+
width: 22em;
|
|
286
|
+
max-height: 220px;
|
|
287
|
+
scroll-snap-type: x mandatory;
|
|
288
|
+
}
|
|
289
|
+
@media (max-width: 1280px) {
|
|
290
|
+
#install-modal-wrapper .screenshot {
|
|
291
|
+
justify-content: center;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
#install-modal-wrapper .screenshot::-webkit-scrollbar {
|
|
295
|
+
display: none;
|
|
296
|
+
}
|
|
297
|
+
#install-modal-wrapper .screenshot div {
|
|
298
|
+
display: flex;
|
|
299
|
+
align-items: center;
|
|
300
|
+
justify-content: center;
|
|
301
|
+
width: 100%;
|
|
302
|
+
height: 14em;
|
|
303
|
+
background: #efefef;
|
|
304
|
+
scroll-snap-align: start;
|
|
305
|
+
}
|
|
306
|
+
#install-modal-wrapper .screenshot img {
|
|
307
|
+
object-fit: contain;
|
|
308
|
+
height: 100%;
|
|
309
|
+
}
|
|
310
|
+
@media (max-width: 719px) {
|
|
311
|
+
#install-modal-wrapper .screenshot img {
|
|
312
|
+
height: 180px;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
#install-modal-wrapper .description {
|
|
316
|
+
margin-bottom: 3em;
|
|
317
|
+
}
|
|
318
|
+
#install-modal-wrapper .button-wrapper {
|
|
319
|
+
width: 100%;
|
|
320
|
+
padding: 1rem 0;
|
|
321
|
+
text-align: end;
|
|
322
|
+
}
|
|
323
|
+
@media (max-width: 719px) {
|
|
324
|
+
#install-modal-wrapper .button-wrapper {
|
|
325
|
+
text-align: center;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
#install-modal-wrapper .install-button,
|
|
329
|
+
#install-modal-wrapper .cancel-button {
|
|
330
|
+
display: inline-block;
|
|
331
|
+
flex: 0 0 auto;
|
|
332
|
+
min-width: 80px;
|
|
333
|
+
margin: 0.5rem 1rem;
|
|
334
|
+
padding: 0.5rem 1rem;
|
|
335
|
+
border: 2px solid var(--pwa-btn-bg-color);
|
|
336
|
+
border-radius: 20px;
|
|
337
|
+
background: transparent;
|
|
338
|
+
font-weight: 600;
|
|
339
|
+
font-size: 14px;
|
|
340
|
+
cursor: pointer;
|
|
341
|
+
}
|
|
342
|
+
#install-modal-wrapper .install-button {
|
|
343
|
+
background: var(--pwa-btn-bg-color);
|
|
344
|
+
color: var(--pwa-bg-color);
|
|
345
|
+
transition: color 0.3s;
|
|
346
|
+
}
|
|
347
|
+
@media (max-width: 419px) {
|
|
348
|
+
#install-modal-wrapper .install-button span {
|
|
349
|
+
display: none;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
#install-modal-wrapper .install-button:hover, #install-modal-wrapper .install-button:focus {
|
|
353
|
+
background: var(--pwa-btn-hover-bg-color);
|
|
354
|
+
}
|
|
355
|
+
#install-modal-wrapper .cancel-button {
|
|
356
|
+
background: transparent;
|
|
357
|
+
color: var(--pwa-btn-bg-color);
|
|
358
|
+
}
|
|
359
|
+
#install-modal-wrapper .cancel-button:hover, #install-modal-wrapper .cancel-button:focus {
|
|
360
|
+
background: var(--pwa-btn-hover-bg-color);
|
|
361
|
+
color: var(--pwa-bg-color);
|
|
362
|
+
}
|
|
363
|
+
#install-modal-wrapper .ios-text {
|
|
364
|
+
position: fixed;
|
|
365
|
+
bottom: 0;
|
|
366
|
+
box-sizing: border-box;
|
|
367
|
+
width: 92%;
|
|
368
|
+
margin: 2em auto;
|
|
369
|
+
padding: 0.5em 2em;
|
|
370
|
+
border-radius: 8px;
|
|
371
|
+
background: var(--pwa-bg-color);
|
|
372
|
+
box-shadow: 0 2px 12px 0 var(--pwa-shadow-color);
|
|
373
|
+
font-weight: bold;
|
|
374
|
+
font-size: 14px;
|
|
375
|
+
text-align: center;
|
|
376
|
+
transition: background 0.3s, box-shadow 0.3s;
|
|
377
|
+
}
|
|
378
|
+
#install-modal-wrapper .ios-text::after {
|
|
379
|
+
content: " ";
|
|
380
|
+
position: absolute;
|
|
381
|
+
bottom: -1em;
|
|
382
|
+
left: calc(50% - 0.8em);
|
|
383
|
+
width: 0;
|
|
384
|
+
height: 0;
|
|
385
|
+
border-top: 1em solid var(--pwa-bg-color);
|
|
386
|
+
border-right: 0.8em solid transparent;
|
|
387
|
+
border-left: 0.8em solid transparent;
|
|
388
|
+
transition: border-color 0.3s;
|
|
389
|
+
}
|
|
390
|
+
#install-modal-wrapper .ios-text p {
|
|
391
|
+
margin: 0 0 0.5em;
|
|
392
|
+
}
|
|
393
|
+
#install-modal-wrapper .ios-text .success {
|
|
394
|
+
margin-bottom: 0.5em;
|
|
395
|
+
padding: 0.5em 1em;
|
|
396
|
+
border: none;
|
|
397
|
+
border-radius: 1em;
|
|
398
|
+
background: #07c160;
|
|
399
|
+
color: var(--pwa-bg-color);
|
|
400
|
+
cursor: pointer;
|
|
401
|
+
transition: color 0.3s;
|
|
402
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
@keyframes rotate {
|
|
2
|
+
0% {
|
|
3
|
+
transform: rotate(0deg);
|
|
4
|
+
}
|
|
5
|
+
50% {
|
|
6
|
+
transform: rotate(360deg);
|
|
7
|
+
}
|
|
8
|
+
100% {
|
|
9
|
+
transform: rotate(360deg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
.popup-enter-active,
|
|
13
|
+
.popup-leave-active {
|
|
14
|
+
transition: opacity 0.3s, transform 0.3s;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.popup-enter-from,
|
|
18
|
+
.popup-leave-to {
|
|
19
|
+
opacity: 0;
|
|
20
|
+
transform: translate(0, 50%) scale(0.5);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.sw-hint-popup,
|
|
24
|
+
.sw-update-popup {
|
|
25
|
+
position: fixed;
|
|
26
|
+
bottom: 1rem;
|
|
27
|
+
inset-inline-end: 1rem;
|
|
28
|
+
z-index: var(--pwa-z-index);
|
|
29
|
+
padding: 0.5rem 0.75rem;
|
|
30
|
+
border-width: 0;
|
|
31
|
+
border-radius: 0.5rem;
|
|
32
|
+
background: var(--pwa-bg-color);
|
|
33
|
+
color: var(--pwa-color);
|
|
34
|
+
box-shadow: 0 2px 12px 0 var(--pwa-shadow-color);
|
|
35
|
+
font-size: 1rem;
|
|
36
|
+
line-height: 1.5;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
}
|
|
39
|
+
@media print {
|
|
40
|
+
.sw-hint-popup,
|
|
41
|
+
.sw-update-popup {
|
|
42
|
+
display: none;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.sw-hint-popup .icon-wrapper,
|
|
46
|
+
.sw-update-popup .icon-wrapper {
|
|
47
|
+
display: inline-block;
|
|
48
|
+
vertical-align: middle;
|
|
49
|
+
width: 1.5rem;
|
|
50
|
+
height: 1.5rem;
|
|
51
|
+
margin-inline-start: 0.4rem;
|
|
52
|
+
border-radius: 0.75rem;
|
|
53
|
+
background: var(--pwa-btn-bg-color);
|
|
54
|
+
}
|
|
55
|
+
.sw-hint-popup .icon-wrapper:hover,
|
|
56
|
+
.sw-update-popup .icon-wrapper:hover {
|
|
57
|
+
background: var(--pwa-btn-hover-bg-color);
|
|
58
|
+
}
|
|
59
|
+
.sw-hint-popup .icon-wrapper svg,
|
|
60
|
+
.sw-update-popup .icon-wrapper svg {
|
|
61
|
+
width: 1.2rem;
|
|
62
|
+
height: 1.2rem;
|
|
63
|
+
margin: 0.15rem;
|
|
64
|
+
color: var(--pwa-btn-text-color);
|
|
65
|
+
animation: rotate 3s ease infinite;
|
|
66
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--pwa-z-index: 10;
|
|
3
|
+
--pwa-color: #2c3e50;
|
|
4
|
+
--pwa-bg-color: #ffffff;
|
|
5
|
+
--pwa-border-color: #3eaf7c;
|
|
6
|
+
--pwa-shadow-color: rgb(0 0 0 / 15%);
|
|
7
|
+
--pwa-btn-text-color: #ffffff;
|
|
8
|
+
--pwa-btn-bg-color: #3eaf7c;
|
|
9
|
+
--pwa-btn-hover-bg-color: #4abf8a;
|
|
10
|
+
--pwa-content-color: #333;
|
|
11
|
+
--pwa-content-light-color: #666;
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Force update page content
|
|
3
|
+
*
|
|
4
|
+
* 强制更新页面内容
|
|
5
|
+
*/
|
|
6
|
+
export const forceUpdate = () => {
|
|
7
|
+
navigator.serviceWorker.getRegistration().then((registration) => {
|
|
8
|
+
// Check whether a valid service worker is active
|
|
9
|
+
if (registration && registration.active)
|
|
10
|
+
registration?.addEventListener('updatefound', () => {
|
|
11
|
+
// force refresh
|
|
12
|
+
// @ts-expect-error: A non-standard API
|
|
13
|
+
window.location.reload(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Hooks } from 'register-service-worker';
|
|
2
|
+
/**
|
|
3
|
+
* Register serviceWorker under `serviceWorkerPath`
|
|
4
|
+
*
|
|
5
|
+
* @param serviceWorkerPath Service Worker path
|
|
6
|
+
* @param hooks Service worker hooks
|
|
7
|
+
* @param showStatus Whether to show status in console
|
|
8
|
+
*
|
|
9
|
+
* 在 `serviceWorkerPath` 下注册 Service Worker
|
|
10
|
+
*
|
|
11
|
+
* @param serviceWorkerPath Service Worker 路径
|
|
12
|
+
* @param hooks Service Worker 钩子
|
|
13
|
+
* @param showStatus 是否在控制台显示状态
|
|
14
|
+
*/
|
|
15
|
+
export declare const registerSW: (serviceWorkerPath: string, hooks?: Hooks, showStatus?: boolean) => Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register serviceWorker under `serviceWorkerPath`
|
|
3
|
+
*
|
|
4
|
+
* @param serviceWorkerPath Service Worker path
|
|
5
|
+
* @param hooks Service worker hooks
|
|
6
|
+
* @param showStatus Whether to show status in console
|
|
7
|
+
*
|
|
8
|
+
* 在 `serviceWorkerPath` 下注册 Service Worker
|
|
9
|
+
*
|
|
10
|
+
* @param serviceWorkerPath Service Worker 路径
|
|
11
|
+
* @param hooks Service Worker 钩子
|
|
12
|
+
* @param showStatus 是否在控制台显示状态
|
|
13
|
+
*/
|
|
14
|
+
export const registerSW = async (serviceWorkerPath, hooks = {}, showStatus = true) => {
|
|
15
|
+
const { register } = await import(
|
|
16
|
+
/* webpackChunkName: "register-service-worker" */ 'register-service-worker');
|
|
17
|
+
// Register service worker
|
|
18
|
+
register(serviceWorkerPath, {
|
|
19
|
+
ready(registration) {
|
|
20
|
+
if (showStatus)
|
|
21
|
+
console.info('[Service Worker]: active');
|
|
22
|
+
hooks.ready?.(registration);
|
|
23
|
+
},
|
|
24
|
+
registered(registration) {
|
|
25
|
+
if (showStatus)
|
|
26
|
+
console.log('[Service Worker]: registered');
|
|
27
|
+
hooks.registered?.(registration);
|
|
28
|
+
},
|
|
29
|
+
cached(registration) {
|
|
30
|
+
if (showStatus)
|
|
31
|
+
console.log('[Service Worker]: cached');
|
|
32
|
+
hooks.cached?.(registration);
|
|
33
|
+
},
|
|
34
|
+
async updatefound(registration) {
|
|
35
|
+
if (await navigator.serviceWorker.getRegistration()) {
|
|
36
|
+
if (showStatus)
|
|
37
|
+
console.log('[Service Worker]: update found');
|
|
38
|
+
hooks.updatefound?.(registration);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
updated(registration) {
|
|
42
|
+
if (showStatus)
|
|
43
|
+
console.log('[Service Worker]: updated');
|
|
44
|
+
hooks.updated?.(registration);
|
|
45
|
+
},
|
|
46
|
+
offline() {
|
|
47
|
+
if (showStatus)
|
|
48
|
+
console.log('[Service Worker]: offline');
|
|
49
|
+
hooks.offline?.();
|
|
50
|
+
},
|
|
51
|
+
error(err) {
|
|
52
|
+
if (showStatus)
|
|
53
|
+
console.error('[Service Worker]: ', err);
|
|
54
|
+
hooks.error?.(err);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call `skipWaiting()` inside current waiting worker
|
|
3
|
+
*
|
|
4
|
+
* 在当前等待中的 Service Worker 中调用 `skipWaiting()`
|
|
5
|
+
*/
|
|
6
|
+
export const skipWaiting = (registration) => {
|
|
7
|
+
// Get the waiting worker
|
|
8
|
+
const worker = registration.waiting;
|
|
9
|
+
// If there is no waiting worker, return directly
|
|
10
|
+
if (!worker)
|
|
11
|
+
return;
|
|
12
|
+
// Post SKIP_WAITING message to the waiting worker
|
|
13
|
+
const channel = new MessageChannel();
|
|
14
|
+
worker.postMessage({ type: 'SKIP_WAITING' }, [channel.port2]);
|
|
15
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call `unregister()` inside current active worker
|
|
3
|
+
*
|
|
4
|
+
* @returns `true` if unregister success, `false` if unregister failed
|
|
5
|
+
*
|
|
6
|
+
* 在当前激活的 Service Worker 中调用 `unregister()`
|
|
7
|
+
*
|
|
8
|
+
* @returns `true` 表示注销成功,`false` 表示注销失败
|
|
9
|
+
*/
|
|
10
|
+
export declare const unregisterSW: () => Promise<boolean>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call `unregister()` inside current active worker
|
|
3
|
+
*
|
|
4
|
+
* @returns `true` if unregister success, `false` if unregister failed
|
|
5
|
+
*
|
|
6
|
+
* 在当前激活的 Service Worker 中调用 `unregister()`
|
|
7
|
+
*
|
|
8
|
+
* @returns `true` 表示注销成功,`false` 表示注销失败
|
|
9
|
+
*/
|
|
10
|
+
export const unregisterSW = () => navigator.serviceWorker
|
|
11
|
+
.getRegistration()
|
|
12
|
+
.then((registration) => {
|
|
13
|
+
if (registration)
|
|
14
|
+
return registration.unregister().then((found) => {
|
|
15
|
+
if (found)
|
|
16
|
+
console.log('[PWA] Current service worker unregistered');
|
|
17
|
+
return found;
|
|
18
|
+
});
|
|
19
|
+
return false;
|
|
20
|
+
})
|
|
21
|
+
.catch((error) => {
|
|
22
|
+
console.log('[PWA] Unregister current service worker failed with error:', error);
|
|
23
|
+
return false;
|
|
24
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { colors, fs, path } from 'vuepress/utils';
|
|
2
|
+
import { getManifest } from './getManifest.js';
|
|
3
|
+
import { logger } from './logger.js';
|
|
4
|
+
export const generateManifest = async (app, options) => {
|
|
5
|
+
const { succeed } = logger.load('Generating manifest.webmanifest');
|
|
6
|
+
const manifest = await getManifest(app, options);
|
|
7
|
+
const manifestPath = app.dir.dest('manifest.webmanifest');
|
|
8
|
+
await fs.writeJSON(manifestPath, manifest, {
|
|
9
|
+
flag: 'w',
|
|
10
|
+
});
|
|
11
|
+
succeed(`Manifest generated and saved to ${colors.cyan(path.relative(process.cwd(), manifestPath))}!`);
|
|
12
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { App } from 'vuepress/core';
|
|
2
|
-
import type {
|
|
3
|
-
export
|
|
4
|
-
export declare const generateServiceWorker: (app: App, serviceWorkerFilename: string, generateSWConfig: GenerateSWConfig) => Promise<void>;
|
|
2
|
+
import type { PwaPluginOptions } from './options.js';
|
|
3
|
+
export declare const generateServiceWorker: (app: App, options: PwaPluginOptions) => Promise<void>;
|