@waline/client 2.7.0 → 2.8.1

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.
Files changed (43) hide show
  1. package/LICENSE +339 -0
  2. package/dist/component.esm.js +1 -1
  3. package/dist/component.esm.js.map +1 -1
  4. package/dist/component.js +1 -1
  5. package/dist/component.js.map +1 -1
  6. package/dist/legacy.js +1 -1
  7. package/dist/legacy.js.map +1 -1
  8. package/dist/pageview.cjs.js +1 -1
  9. package/dist/pageview.cjs.js.map +1 -1
  10. package/dist/pageview.esm.js +1 -1
  11. package/dist/pageview.esm.js.map +1 -1
  12. package/dist/pageview.js +1 -1
  13. package/dist/pageview.js.map +1 -1
  14. package/dist/shim.d.ts +5 -0
  15. package/dist/shim.esm.d.ts +5 -0
  16. package/dist/shim.esm.js +1 -1
  17. package/dist/shim.esm.js.map +1 -1
  18. package/dist/shim.js +1 -1
  19. package/dist/shim.js.map +1 -1
  20. package/dist/waline-meta.css +1 -0
  21. package/dist/waline-meta.css.map +1 -0
  22. package/dist/waline.cjs.d.ts +5 -0
  23. package/dist/waline.cjs.js +1 -1
  24. package/dist/waline.cjs.js.map +1 -1
  25. package/dist/waline.css +1 -1
  26. package/dist/waline.css.map +1 -1
  27. package/dist/waline.d.ts +5 -0
  28. package/dist/waline.esm.d.ts +5 -0
  29. package/dist/waline.esm.js +1 -1
  30. package/dist/waline.esm.js.map +1 -1
  31. package/dist/waline.js +1 -1
  32. package/dist/waline.js.map +1 -1
  33. package/package.json +46 -21
  34. package/src/components/CommentBox.vue +19 -4
  35. package/src/components/CommentCard.vue +71 -10
  36. package/src/components/Icons.ts +10 -0
  37. package/src/components/Waline.vue +14 -2
  38. package/src/styles/card.scss +2 -5
  39. package/src/styles/helpers/_svg.scss +51 -0
  40. package/src/styles/layout.scss +7 -6
  41. package/src/styles/meta.scss +86 -0
  42. package/src/typings/comment.ts +6 -0
  43. package/src/utils/fetch.ts +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/client",
3
- "version": "2.7.0",
3
+ "version": "2.8.1",
4
4
  "description": "client for waline comment system",
5
5
  "keywords": [
6
6
  "valine",
@@ -20,11 +20,32 @@
20
20
  },
21
21
  "exports": {
22
22
  ".": {
23
+ "types": "./dist/shim.d.ts",
23
24
  "import": "./dist/shim.esm.js",
24
25
  "require": "./dist/shim.js",
25
26
  "default": "./dist/shim.js"
26
27
  },
28
+ "./component": {
29
+ "import": "./dist/component.esm.js",
30
+ "require": "./dist/component.js",
31
+ "default": "./dist/component.esm.js"
32
+ },
33
+ "./full": {
34
+ "types": "./dist/waline.d.ts",
35
+ "import": "./dist/waline.esm.js",
36
+ "require": "./dist/waline.cjs.js",
37
+ "default": "./dist/waline.js"
38
+ },
39
+ "./pageview": {
40
+ "types": "./dist/pageview.d.ts",
41
+ "import": "./dist/pageview.esm.js",
42
+ "require": "./dist/pageview.cjs.js",
43
+ "default": "./dist/pageview.js"
44
+ },
45
+ "./waline.css": "./dist/waline.css",
46
+ "./waline-meta.css": "./dist/waline-meta.css",
27
47
  "./dist": {
48
+ "types": "./dist/shim.d.ts",
28
49
  "import": "./dist/shim.esm.js",
29
50
  "require": "./dist/shim.js",
30
51
  "default": "./dist/shim.js"
@@ -35,16 +56,19 @@
35
56
  "default": "./dist/component.esm.js"
36
57
  },
37
58
  "./dist/pageview": {
59
+ "types": "./dist/pageview.d.ts",
38
60
  "import": "./dist/pageview.esm.js",
39
61
  "require": "./dist/pageview.cjs.js",
40
62
  "default": "./dist/pageview.js"
41
63
  },
42
64
  "./dist/waline": {
65
+ "types": "./dist/waline.d.ts",
43
66
  "import": "./dist/waline.esm.js",
44
67
  "require": "./dist/waline.cjs.js",
45
68
  "default": "./dist/waline.js"
46
69
  },
47
70
  "./dist/waline.css": "./dist/waline.css",
71
+ "./dist/waline-meta.css": "./dist/waline-meta.css",
48
72
  "./dist/*": "./dist/*",
49
73
  "./src/*": "./src/*",
50
74
  "./package.json": "./package.json"
@@ -56,15 +80,6 @@
56
80
  "dist",
57
81
  "src"
58
82
  ],
59
- "scripts": {
60
- "build": "pnpm rollup && pnpm style",
61
- "clean": "rimraf ./dist",
62
- "dev": "vite -c config/vite.config.js",
63
- "lint": "eslint --ext .ts,.vue .",
64
- "prepublishOnly": "pnpm clean && pnpm build",
65
- "rollup": "rollup -c ./config/rollup.config.js",
66
- "style": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed"
67
- },
68
83
  "browserslist": {
69
84
  "production": [
70
85
  ">0.5%",
@@ -80,31 +95,41 @@
80
95
  ]
81
96
  },
82
97
  "dependencies": {
83
- "@vueuse/core": "^9.1.1",
98
+ "@vueuse/core": "^9.2.0",
84
99
  "autosize": "^5.0.1",
85
100
  "marked": "^4.1.0",
86
- "vue": "^3.2.38"
101
+ "vue": "^3.2.39"
87
102
  },
88
103
  "devDependencies": {
89
- "@babel/core": "7.18.13",
90
- "@babel/preset-env": "7.18.10",
104
+ "@babel/core": "7.19.0",
105
+ "@babel/preset-env": "7.19.0",
91
106
  "@rollup/plugin-babel": "5.3.1",
92
107
  "@rollup/plugin-commonjs": "22.0.2",
93
- "@rollup/plugin-node-resolve": "13.3.0",
108
+ "@rollup/plugin-node-resolve": "14.0.1",
94
109
  "@rollup/plugin-replace": "4.0.0",
95
110
  "@types/autosize": "4.0.1",
96
- "@types/marked": "4.0.6",
97
- "@types/node": "18.7.14",
98
- "@vitejs/plugin-vue": "3.0.3",
111
+ "@types/marked": "4.0.7",
112
+ "@types/node": "18.7.16",
113
+ "@vitejs/plugin-vue": "3.1.0",
99
114
  "rimraf": "3.0.2",
100
115
  "rollup": "2.79.0",
101
116
  "rollup-plugin-dts": "4.2.2",
102
117
  "rollup-plugin-terser": "7.0.2",
103
118
  "rollup-plugin-ts": "3.0.2",
104
- "typescript": "4.8.2",
105
- "vite": "3.0.9"
119
+ "typescript": "4.8.3",
120
+ "vite": "3.1.0"
106
121
  },
107
122
  "engines": {
108
123
  "node": ">=14"
124
+ },
125
+ "scripts": {
126
+ "build": "pnpm rollup && pnpm style",
127
+ "clean": "rimraf ./dist",
128
+ "dev": "vite -c config/vite.config.js",
129
+ "lint": "eslint --ext .ts,.vue .",
130
+ "rollup": "rollup -c ./config/rollup.config.js",
131
+ "style": "pnpm style:main && pnpm style:meta",
132
+ "style:main": "sass ./src/styles/index.scss ./dist/waline.css --style=compressed",
133
+ "style:meta": "sass ./src/styles/meta.scss ./dist/waline-meta.css --style=compressed"
109
134
  }
110
- }
135
+ }
@@ -1,6 +1,9 @@
1
1
  <template>
2
2
  <div class="wl-comment">
3
- <div v-if="config.login !== 'disable' && isLogin" class="wl-login-info">
3
+ <div
4
+ v-if="config.login !== 'disable' && isLogin && !edit?.objectId"
5
+ class="wl-login-info"
6
+ >
4
7
  <div class="wl-avatar">
5
8
  <button class="wl-logout-btn" :title="locale.logout" @click="onLogout">
6
9
  <CloseIcon :size="14" />
@@ -248,10 +251,10 @@
248
251
  </div>
249
252
 
250
253
  <button
251
- v-if="replyId"
254
+ v-if="replyId || edit?.objectId"
252
255
  class="wl-close"
253
256
  :title="locale.cancelReply"
254
- @click="$emit('cancel-reply')"
257
+ @click="$emit(replyId ? 'cancel-reply' : 'cancel-edit')"
255
258
  >
256
259
  <CloseIcon :size="24" />
257
260
  </button>
@@ -267,6 +270,7 @@ import {
267
270
  inject,
268
271
  onMounted,
269
272
  onUnmounted,
273
+ PropType,
270
274
  reactive,
271
275
  ref,
272
276
  watch,
@@ -294,6 +298,7 @@ import {
294
298
 
295
299
  import type { ComputedRef, DeepReadonly } from 'vue';
296
300
  import type {
301
+ WalineComment,
297
302
  WalineCommentData,
298
303
  WalineImageUploader,
299
304
  WalineSearchOptions,
@@ -328,9 +333,13 @@ export default defineComponent({
328
333
  type: String,
329
334
  default: '',
330
335
  },
336
+ edit: {
337
+ type: Object as PropType<WalineComment | null>,
338
+ default: null,
339
+ },
331
340
  },
332
341
 
333
- emits: ['submit', 'cancel-reply'],
342
+ emits: ['submit', 'cancel-reply', 'cancel-edit'],
334
343
 
335
344
  setup(props, { emit }) {
336
345
  const config = inject<ComputedRef<WalineConfig>>(
@@ -510,6 +519,8 @@ export default defineComponent({
510
519
  comment.pid = props.replyId;
511
520
  comment.rid = props.rootId;
512
521
  comment.at = props.replyUser;
522
+ } else if (props.edit) {
523
+ comment.eid = props.edit.objectId;
513
524
  }
514
525
 
515
526
  isSubmitting.value = true;
@@ -532,6 +543,7 @@ export default defineComponent({
532
543
  previewText.value = '';
533
544
 
534
545
  if (props.replyId) emit('cancel-reply');
546
+ if (props.edit?.objectId) emit('cancel-edit');
535
547
  })
536
548
  .catch((err: TypeError) => {
537
549
  isSubmitting.value = false;
@@ -701,6 +713,9 @@ export default defineComponent({
701
713
  onMounted(() => {
702
714
  document.body.addEventListener('click', popupHandler);
703
715
  window.addEventListener('message', onMessageRecive);
716
+ if (props.edit?.objectId) {
717
+ editor.value = props.edit.orig;
718
+ }
704
719
 
705
720
  // watch editor
706
721
  watch(
@@ -32,6 +32,14 @@
32
32
  <span class="wl-time" v-text="time" />
33
33
 
34
34
  <div class="wl-comment-actions">
35
+ <button
36
+ v-if="isAdmin || isOwner"
37
+ class="wl-edit"
38
+ @click="$emit('edit', comment)"
39
+ >
40
+ <EditIcon />
41
+ </button>
42
+
35
43
  <button
36
44
  v-if="isAdmin || isOwner"
37
45
  class="wl-delete"
@@ -60,14 +68,34 @@
60
68
  </div>
61
69
  </div>
62
70
  <div class="wl-meta" aria-hidden="true">
63
- <span v-if="comment.addr" v-text="comment.addr" />
64
- <span v-if="comment.browser" v-text="comment.browser" />
65
- <span v-if="comment.os" v-text="comment.os" />
71
+ <span
72
+ v-if="comment.addr"
73
+ class="wl-addr"
74
+ :data-value="comment.addr"
75
+ v-text="comment.addr"
76
+ />
77
+ <span
78
+ v-if="comment.browser"
79
+ class="wl-browser"
80
+ :data-value="comment.browser"
81
+ v-text="comment.browser"
82
+ />
83
+ <span
84
+ v-if="comment.os"
85
+ class="wl-os"
86
+ :data-value="comment.os"
87
+ v-text="comment.os"
88
+ />
66
89
  </div>
67
- <!-- eslint-disable-next-line vue/no-v-html -->
68
- <div class="wl-content" v-html="comment.comment" />
90
+ <!-- eslint-disable vue/no-v-html -->
91
+ <div
92
+ v-if="!isEditingCurrent"
93
+ class="wl-content"
94
+ v-html="comment.comment"
95
+ />
96
+ <!-- eslint-enable vue/no-v-html -->
69
97
 
70
- <div v-if="isAdmin" class="wl-admin-actions">
98
+ <div v-if="isAdmin && !isEditingCurrent" class="wl-admin-actions">
71
99
  <span class="wl-comment-status">
72
100
  <button
73
101
  v-for="status in commentStatus"
@@ -88,13 +116,21 @@
88
116
  </button>
89
117
  </div>
90
118
 
91
- <div v-if="isReplyingCurrent" class="wl-reply-wrapper">
119
+ <div
120
+ v-if="isReplyingCurrent || isEditingCurrent"
121
+ :class="{
122
+ 'wl-reply-wrapper': isReplyingCurrent,
123
+ 'wl-edit-wrapper': isEditingCurrent,
124
+ }"
125
+ >
92
126
  <CommentBox
93
- :reply-id="comment.objectId"
127
+ :edit="edit"
128
+ :reply-id="reply?.objectId"
94
129
  :reply-user="comment.nick"
95
130
  :root-id="rootId"
96
131
  @submit="$emit('submit', $event)"
97
132
  @cancel-reply="$emit('reply', null)"
133
+ @cancel-edit="$emit('edit', null)"
98
134
  />
99
135
  </div>
100
136
  <div v-if="comment.children" class="wl-quote">
@@ -103,10 +139,12 @@
103
139
  :key="child.objectId"
104
140
  :comment="child"
105
141
  :reply="reply"
142
+ :edit="edit"
106
143
  :root-id="rootId"
107
144
  @reply="$emit('reply', $event)"
108
145
  @submit="$emit('submit', $event)"
109
146
  @like="$emit('like', $event)"
147
+ @edit="$emit('edit', $event)"
110
148
  @delete="$emit('delete', $event)"
111
149
  @status="$emit('status', $event)"
112
150
  @sticky="$emit('sticky', $event)"
@@ -119,7 +157,13 @@
119
157
  <script lang="ts">
120
158
  import { computed, defineComponent, inject } from 'vue';
121
159
  import CommentBox from './CommentBox.vue';
122
- import { DeleteIcon, LikeIcon, ReplyIcon, VerifiedIcon } from './Icons';
160
+ import {
161
+ DeleteIcon,
162
+ LikeIcon,
163
+ ReplyIcon,
164
+ EditIcon,
165
+ VerifiedIcon,
166
+ } from './Icons';
123
167
  import { isLinkHttp } from '../utils';
124
168
  import { useTimeAgo, useLikeStorage, useUserInfo } from '../composables';
125
169
 
@@ -135,6 +179,7 @@ export default defineComponent({
135
179
  DeleteIcon,
136
180
  LikeIcon,
137
181
  ReplyIcon,
182
+ EditIcon,
138
183
  VerifiedIcon,
139
184
  },
140
185
 
@@ -151,9 +196,13 @@ export default defineComponent({
151
196
  type: Object as PropType<WalineComment | null>,
152
197
  default: null,
153
198
  },
199
+ edit: {
200
+ type: Object as PropType<WalineComment | null>,
201
+ default: null,
202
+ },
154
203
  },
155
204
 
156
- emits: ['submit', 'reply', 'like', 'delete', 'status', 'sticky'],
205
+ emits: ['submit', 'reply', 'like', 'delete', 'status', 'sticky', 'edit'],
157
206
 
158
207
  setup(props) {
159
208
  const config = inject<ComputedRef<WalineConfig>>(
@@ -182,15 +231,27 @@ export default defineComponent({
182
231
  userInfo.value.objectId === props.comment.user_id
183
232
  );
184
233
 
234
+ console.log(
235
+ 'lizheming:',
236
+ props.comment.user_id,
237
+ userInfo.value.objectId,
238
+ isOwner.value
239
+ );
240
+
185
241
  const isReplyingCurrent = computed(
186
242
  () => props.comment.objectId === props.reply?.objectId
187
243
  );
188
244
 
245
+ const isEditingCurrent = computed(
246
+ () => props.comment.objectId === props.edit?.objectId
247
+ );
248
+
189
249
  return {
190
250
  config,
191
251
  locale,
192
252
 
193
253
  isReplyingCurrent,
254
+ isEditingCurrent,
194
255
  link,
195
256
  like,
196
257
  time,
@@ -102,6 +102,16 @@ export const ReplyIcon: FunctionalComponent = () =>
102
102
  })
103
103
  );
104
104
 
105
+ export const EditIcon: FunctionalComponent = () =>
106
+ h(
107
+ 'svg',
108
+ { viewBox: '0 0 1024 1024', width: '24', height: '24' },
109
+ h('path', {
110
+ d: 'M813.039 318.772L480.53 651.278H360.718V531.463L693.227 198.961C697.904 194.284 704.027 192 710.157 192C716.302 192 722.436 194.284 727.114 198.961L813.039 284.88C817.72 289.561 820 295.684 820 301.825C820 307.95 817.72 314.093 813.039 318.772ZM710.172 261.888L420.624 551.431V591.376H460.561L750.109 301.825L710.172 261.888ZM490.517 291.845H240.906V771.09H720.156V521.479C720.156 504.947 733.559 491.529 750.109 491.529C766.653 491.529 780.063 504.947 780.063 521.479V791.059C780.063 813.118 762.18 831 740.125 831H220.937C198.882 831 181 813.118 181 791.059V271.872C181 249.817 198.882 231.935 220.937 231.935H490.517C507.06 231.935 520.47 245.352 520.47 261.888C520.47 278.424 507.06 291.845 490.517 291.845Z',
111
+ fill: 'currentColor',
112
+ })
113
+ );
114
+
105
115
  export const VerifiedIcon: FunctionalComponent = () =>
106
116
  h(
107
117
  'svg',
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div data-waline>
3
3
  <CommentBox v-if="!reply" @submit="onSubmit" />
4
- <div class="wl-head">
4
+ <div class="wl-meta-head">
5
5
  <div class="wl-count">
6
6
  <span v-if="count" class="wl-num" v-text="count" />
7
7
  {{ i18n.comment }}
@@ -25,7 +25,9 @@
25
25
  :root-id="comment.objectId"
26
26
  :comment="comment"
27
27
  :reply="reply"
28
+ :edit="edit"
28
29
  @reply="onReply"
30
+ @edit="onEdit"
29
31
  @submit="onSubmit"
30
32
  @status="onStatusChange"
31
33
  @delete="onDelete"
@@ -263,6 +265,7 @@ export default defineComponent({
263
265
 
264
266
  const data = ref<WalineComment[]>([]);
265
267
  const reply = ref<WalineComment | null>(null);
268
+ const edit = ref<WalineComment | null>(null);
266
269
 
267
270
  const darkmodeStyle = computed(() => getDarkStyle(config.value.dark));
268
271
 
@@ -326,8 +329,15 @@ export default defineComponent({
326
329
  reply.value = comment;
327
330
  };
328
331
 
332
+ const onEdit = (comment: WalineComment | null): void => {
333
+ edit.value = comment;
334
+ };
335
+
329
336
  const onSubmit = (comment: WalineComment): void => {
330
- if (comment.rid) {
337
+ if (edit.value) {
338
+ edit.value.comment = comment.comment;
339
+ edit.value.orig = comment.orig;
340
+ } else if (comment.rid) {
331
341
  const repliedComment = data.value.find(
332
342
  ({ objectId }) => objectId === comment.rid
333
343
  );
@@ -456,6 +466,7 @@ export default defineComponent({
456
466
  sortByItems,
457
467
  data,
458
468
  reply,
469
+ edit,
459
470
 
460
471
  loadMore,
461
472
  refresh,
@@ -466,6 +477,7 @@ export default defineComponent({
466
477
  onDelete,
467
478
  onSticky,
468
479
  onLike,
480
+ onEdit,
469
481
 
470
482
  version: VERSION,
471
483
  };
@@ -118,10 +118,6 @@
118
118
  font-size: var(--waline-info-font-size);
119
119
  line-height: 1.5;
120
120
 
121
- @media (max-width: 520px) {
122
- display: none;
123
- }
124
-
125
121
  &:empty {
126
122
  display: none;
127
123
  }
@@ -134,7 +130,8 @@
134
130
 
135
131
  .wl-delete,
136
132
  .wl-like,
137
- .wl-reply {
133
+ .wl-reply,
134
+ .wl-edit {
138
135
  display: inline-flex;
139
136
  align-items: center;
140
137
 
@@ -0,0 +1,51 @@
1
+ @use "sass:math";
2
+ @use "sass:string";
3
+
4
+ /* stylelint-disable scss/operator-no-newline-after */
5
+
6
+ @function string-replace($string, $search, $replace: "") {
7
+ $index: string.index($string, $search);
8
+ @return if(
9
+ $index,
10
+ str-slice($string, 1, $index - 1) + $replace +
11
+ string-replace(
12
+ str-slice($string, $index + str-length($search)),
13
+ $search,
14
+ $replace
15
+ ),
16
+ $string
17
+ );
18
+ }
19
+
20
+ @function svg-url($svg) {
21
+ $encoded: "";
22
+ $slice: 2000;
23
+ $index: 0;
24
+ $loops: math.ceil(math.div(string.length($svg), $slice));
25
+
26
+ @if not str-index($svg, xmlns) {
27
+ $svg: string-replace(
28
+ $svg,
29
+ "<svg",
30
+ '<svg xmlns="http://www.w3.org/2000/svg"'
31
+ );
32
+ }
33
+
34
+ @for $i from 1 through $loops {
35
+ $chunk: string.slice($svg, $index, $index + $slice - 1);
36
+ $chunk: string-replace($chunk, '"', "'");
37
+ $chunk: string-replace($chunk, "%", "%25");
38
+ $chunk: string-replace($chunk, "#", "%23");
39
+ $chunk: string-replace($chunk, "{", "%7B");
40
+ $chunk: string-replace($chunk, "}", "%7D");
41
+ $chunk: string-replace($chunk, "<", "%3C");
42
+ $chunk: string-replace($chunk, ">", "%3E");
43
+ $encoded: #{$encoded}#{$chunk};
44
+ $index: $index + $slice;
45
+ }
46
+ @return url("data:image/svg+xml,#{$encoded}");
47
+ }
48
+
49
+ @mixin background-svg($svg) {
50
+ background-image: svg-url($svg);
51
+ }
@@ -50,10 +50,9 @@
50
50
  }
51
51
 
52
52
  .wl-count {
53
- padding: 0.375em;
53
+ flex: 1;
54
54
  font-weight: bold;
55
55
  font-size: 1.25em;
56
- flex: 1;
57
56
  }
58
57
 
59
58
  .wl-empty {
@@ -78,20 +77,22 @@
78
77
  text-align: right;
79
78
  }
80
79
 
81
- .wl-head {
80
+ .wl-meta-head {
82
81
  display: flex;
83
82
  flex-direction: row;
84
83
  align-items: center;
84
+ padding: 0.375em;
85
85
  }
86
86
 
87
- .wl-sort.ul {
87
+ ul.wl-sort {
88
+ margin: 0;
88
89
  list-style-type: none;
89
90
  }
90
91
 
91
92
  .wl-sort li {
92
93
  display: inline-block;
93
- font-size: 0.75em;
94
94
  color: var(--waline-info-color);
95
+ font-size: 0.75em;
95
96
  cursor: pointer;
96
97
  }
97
98
 
@@ -101,4 +102,4 @@
101
102
 
102
103
  .wl-sort li.active {
103
104
  color: var(--waline-theme-color);
104
- }
105
+ }
@@ -0,0 +1,86 @@
1
+ @use 'helpers/svg';
2
+
3
+ $address-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M444.52 3.52 28.74 195.42c-47.97 22.39-31.98 92.75 19.19 92.75h175.91v175.91c0 51.17 70.36 67.17 92.75 19.19l191.9-415.78c15.99-38.39-25.59-79.97-63.97-63.97z"/></svg>';
4
+
5
+ $default-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"/></svg>';
6
+
7
+ $apple-icon: '<svg viewBox="0 0 384 512" fill="#999"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>';
8
+
9
+ $android-icon: '<svg viewBox="0 0 576 512" fill="#999"><path d="M420.55 301.93a24 24 0 1 1 24-24 24 24 0 0 1-24 24m-265.1 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24m273.7-144.48 47.94-83a10 10 0 1 0-17.27-10l-48.54 84.07a301.25 301.25 0 0 0-246.56 0l-48.54-84.07a10 10 0 1 0-17.27 10l47.94 83C64.53 202.22 8.24 285.55 0 384h576c-8.24-98.45-64.54-181.78-146.85-226.55"/></svg>';
10
+
11
+ $linux-icon: '<svg viewBox="0 0 448 512" fill="#999"><path d="M220.8 123.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm-21.9 1.7c1.2 0 2-1.2 3-1.7 1.1-.6 3.1-.4 3.5-1.6.2-.4-.2-.9-.6-1.1-1.6-.9-3.8-.6-5.5.1-1.3.6-3.4 1.5-3.2 2.9.1 1 1.8 1.5 2.8 1.4zM420 403.8c-3.6-4-5.3-11.6-7.2-19.7-1.8-8.1-3.9-16.8-10.5-22.4-1.3-1.1-2.6-2.1-4-2.9-1.3-.8-2.7-1.5-4.1-2 9.2-27.3 5.6-54.5-3.7-79.1-11.4-30.1-31.3-56.4-46.5-74.4-17.1-21.5-33.7-41.9-33.4-72C311.1 85.4 315.7.1 234.8 0 132.4-.2 158 103.4 156.9 135.2c-1.7 23.4-6.4 41.8-22.5 64.7-18.9 22.5-45.5 58.8-58.1 96.7-6 17.9-8.8 36.1-6.2 53.3-6.5 5.8-11.4 14.7-16.6 20.2-4.2 4.3-10.3 5.9-17 8.3s-14 6-18.5 14.5c-2.1 3.9-2.8 8.1-2.8 12.4 0 3.9.6 7.9 1.2 11.8 1.2 8.1 2.5 15.7.8 20.8-5.2 14.4-5.9 24.4-2.2 31.7 3.8 7.3 11.4 10.5 20.1 12.3 17.3 3.6 40.8 2.7 59.3 12.5 19.8 10.4 39.9 14.1 55.9 10.4 11.6-2.6 21.1-9.6 25.9-20.2 12.5-.1 26.3-5.4 48.3-6.6 14.9-1.2 33.6 5.3 55.1 4.1.6 2.3 1.4 4.6 2.5 6.7v.1c8.3 16.7 23.8 24.3 40.3 23 16.6-1.3 34.1-11 48.3-27.9 13.6-16.4 36-23.2 50.9-32.2 7.4-4.5 13.4-10.1 13.9-18.3.4-8.2-4.4-17.3-15.5-29.7zM223.7 87.3c9.8-22.2 34.2-21.8 44-.4 6.5 14.2 3.6 30.9-4.3 40.4-1.6-.8-5.9-2.6-12.6-4.9 1.1-1.2 3.1-2.7 3.9-4.6 4.8-11.8-.2-27-9.1-27.3-7.3-.5-13.9 10.8-11.8 23-4.1-2-9.4-3.5-13-4.4-1-6.9-.3-14.6 2.9-21.8zM183 75.8c10.1 0 20.8 14.2 19.1 33.5-3.5 1-7.1 2.5-10.2 4.6 1.2-8.9-3.3-20.1-9.6-19.6-8.4.7-9.8 21.2-1.8 28.1 1 .8 1.9-.2-5.9 5.5-15.6-14.6-10.5-52.1 8.4-52.1zm-13.6 60.7c6.2-4.6 13.6-10 14.1-10.5 4.7-4.4 13.5-14.2 27.9-14.2 7.1 0 15.6 2.3 25.9 8.9 6.3 4.1 11.3 4.4 22.6 9.3 8.4 3.5 13.7 9.7 10.5 18.2-2.6 7.1-11 14.4-22.7 18.1-11.1 3.6-19.8 16-38.2 14.9-3.9-.2-7-1-9.6-2.1-8-3.5-12.2-10.4-20-15-8.6-4.8-13.2-10.4-14.7-15.3-1.4-4.9 0-9 4.2-12.3zm3.3 334c-2.7 35.1-43.9 34.4-75.3 18-29.9-15.8-68.6-6.5-76.5-21.9-2.4-4.7-2.4-12.7 2.6-26.4v-.2c2.4-7.6.6-16-.6-23.9-1.2-7.8-1.8-15 .9-20 3.5-6.7 8.5-9.1 14.8-11.3 10.3-3.7 11.8-3.4 19.6-9.9 5.5-5.7 9.5-12.9 14.3-18 5.1-5.5 10-8.1 17.7-6.9 8.1 1.2 15.1 6.8 21.9 16l19.6 35.6c9.5 19.9 43.1 48.4 41 68.9zm-1.4-25.9c-4.1-6.6-9.6-13.6-14.4-19.6 7.1 0 14.2-2.2 16.7-8.9 2.3-6.2 0-14.9-7.4-24.9-13.5-18.2-38.3-32.5-38.3-32.5-13.5-8.4-21.1-18.7-24.6-29.9s-3-23.3-.3-35.2c5.2-22.9 18.6-45.2 27.2-59.2 2.3-1.7.8 3.2-8.7 20.8-8.5 16.1-24.4 53.3-2.6 82.4.6-20.7 5.5-41.8 13.8-61.5 12-27.4 37.3-74.9 39.3-112.7 1.1.8 4.6 3.2 6.2 4.1 4.6 2.7 8.1 6.7 12.6 10.3 12.4 10 28.5 9.2 42.4 1.2 6.2-3.5 11.2-7.5 15.9-9 9.9-3.1 17.8-8.6 22.3-15 7.7 30.4 25.7 74.3 37.2 95.7 6.1 11.4 18.3 35.5 23.6 64.6 3.3-.1 7 .4 10.9 1.4 13.8-35.7-11.7-74.2-23.3-84.9-4.7-4.6-4.9-6.6-2.6-6.5 12.6 11.2 29.2 33.7 35.2 59 2.8 11.6 3.3 23.7.4 35.7 16.4 6.8 35.9 17.9 30.7 34.8-2.2-.1-3.2 0-4.2 0 3.2-10.1-3.9-17.6-22.8-26.1-19.6-8.6-36-8.6-38.3 12.5-12.1 4.2-18.3 14.7-21.4 27.3-2.8 11.2-3.6 24.7-4.4 39.9-.5 7.7-3.6 18-6.8 29-32.1 22.9-76.7 32.9-114.3 7.2zm257.4-11.5c-.9 16.8-41.2 19.9-63.2 46.5-13.2 15.7-29.4 24.4-43.6 25.5s-26.5-4.8-33.7-19.3c-4.7-11.1-2.4-23.1 1.1-36.3 3.7-14.2 9.2-28.8 9.9-40.6.8-15.2 1.7-28.5 4.2-38.7 2.6-10.3 6.6-17.2 13.7-21.1.3-.2.7-.3 1-.5.8 13.2 7.3 26.6 18.8 29.5 12.6 3.3 30.7-7.5 38.4-16.3 9-.3 15.7-.9 22.6 5.1 9.9 8.5 7.1 30.3 17.1 41.6 10.6 11.6 14 19.5 13.7 24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4s5.9-6.3 3.1-6.6-2.6 2.6-6 5.1c-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2s-18.7-4.8-24.9-9.7c-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"/></svg>';
12
+
13
+ $ubuntu-icon: '<svg viewBox="0 0 496 512" fill="#999"><path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm52.7 93c8.8-15.2 28.3-20.5 43.5-11.7 15.3 8.8 20.5 28.3 11.7 43.6-8.8 15.2-28.3 20.5-43.5 11.7-15.3-8.9-20.5-28.4-11.7-43.6zM87.4 287.9c-17.6 0-31.9-14.3-31.9-31.9 0-17.6 14.3-31.9 31.9-31.9 17.6 0 31.9 14.3 31.9 31.9 0 17.6-14.3 31.9-31.9 31.9zm28.1 3.1c22.3-17.9 22.4-51.9 0-69.9 8.6-32.8 29.1-60.7 56.5-79.1l23.7 39.6c-51.5 36.3-51.5 112.5 0 148.8L172 370c-27.4-18.3-47.8-46.3-56.5-79zm228.7 131.7c-15.3 8.8-34.7 3.6-43.5-11.7-8.8-15.3-3.6-34.8 11.7-43.6 15.2-8.8 34.7-3.6 43.5 11.7 8.8 15.3 3.6 34.8-11.7 43.6zm.3-69.5c-26.7-10.3-56.1 6.6-60.5 35-5.2 1.4-48.9 14.3-96.7-9.4l22.5-40.3c57 26.5 123.4-11.7 128.9-74.4l46.1.7c-2.3 34.5-17.3 65.5-40.3 88.4zm-5.9-105.3c-5.4-62-71.3-101.2-128.9-74.4l-22.5-40.3c47.9-23.7 91.5-10.8 96.7-9.4 4.4 28.3 33.8 45.3 60.5 35 23.1 22.9 38 53.9 40.2 88.5l-46 .6z"/></svg>';
14
+
15
+ $window-icon: '<svg viewBox="0 0 448 512" fill="#999"><path d="m0 93.7 183.6-25.3v177.4H0V93.7zm0 324.6 183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"/></svg>';
16
+
17
+ $chrome-icon: '<svg viewBox="0 0 496 512" fill="#999"><path d="M131.5 217.5 55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6 40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"/></svg>';
18
+
19
+ $edge-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M481.92 134.48C440.87 54.18 352.26 8 255.91 8 137.05 8 37.51 91.68 13.47 203.66c26-46.49 86.22-79.14 149.46-79.14 79.27 0 121.09 48.93 122.25 50.18 22 23.8 33 50.39 33 83.1 0 10.4-5.31 25.82-15.11 38.57-1.57 2-6.39 4.84-6.39 11 0 5.06 3.29 9.92 9.14 14 27.86 19.37 80.37 16.81 80.51 16.81A115.39 115.39 0 0 0 444.94 322a118.92 118.92 0 0 0 58.95-102.44c.5-43.43-15.5-72.3-21.97-85.08ZM212.77 475.67a154.88 154.88 0 0 1-46.64-45c-32.94-47.42-34.24-95.6-20.1-136A155.5 155.5 0 0 1 203 215.75c59-45.2 94.84-5.65 99.06-1a80 80 0 0 0-4.89-10.14c-9.24-15.93-24-36.41-56.56-53.51-33.72-17.69-70.59-18.59-77.64-18.59-38.71 0-77.9 13-107.53 35.69C35.68 183.3 12.77 208.72 8.6 243c-1.08 12.31-2.75 62.8 23 118.27a248 248 0 0 0 248.3 141.61c-38.12-6.62-65.85-26.64-67.13-27.21Zm250.72-98.33a7.76 7.76 0 0 0-7.92-.23 181.66 181.66 0 0 1-20.41 9.12 197.54 197.54 0 0 1-69.55 12.52c-91.67 0-171.52-63.06-171.52-144a61.12 61.12 0 0 1 6.52-26.75 168.72 168.72 0 0 0-38.76 50c-14.92 29.37-33 88.13 13.33 151.66 6.51 8.91 23 30 56 47.67 23.57 12.65 49 19.61 71.7 19.61 35.14 0 115.43-33.44 163-108.87a7.75 7.75 0 0 0-2.39-10.73Z"/></svg>';
20
+
21
+ $firefox-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M189.37 152.86Zm-58.74-29.37c.16.01.08.01 0 0Zm351.42 45.35c-10.61-25.5-32.08-53-48.94-61.73 13.72 26.89 21.67 53.88 24.7 74 0 0 0 .14.05.41-27.58-68.75-74.35-96.47-112.55-156.83-1.93-3.05-3.86-6.11-5.74-9.33-1-1.65-1.86-3.34-2.69-5.05a44.88 44.88 0 0 1-3.64-9.62.63.63 0 0 0-.55-.66.9.9 0 0 0-.46 0l-.12.07-.18.1.1-.14c-54.23 31.77-76.72 87.38-82.5 122.78a130 130 0 0 0-48.33 12.33 6.25 6.25 0 0 0-3.09 7.75 6.13 6.13 0 0 0 7.79 3.79l.52-.21a117.84 117.84 0 0 1 42.11-11l1.42-.1c2-.12 4-.2 6-.22A122.61 122.61 0 0 1 291 140c.67.2 1.32.42 2 .63 1.89.57 3.76 1.2 5.62 1.87 1.36.5 2.71 1 4.05 1.58 1.09.44 2.18.88 3.25 1.35q2.52 1.13 5 2.35c.75.37 1.5.74 2.25 1.13q2.4 1.26 4.74 2.63 1.51.87 3 1.8a124.89 124.89 0 0 1 42.66 44.13c-13-9.15-36.35-18.19-58.82-14.28 87.74 43.86 64.18 194.9-57.39 189.2a108.43 108.43 0 0 1-31.74-6.12 139.5 139.5 0 0 1-7.16-2.93c-1.38-.63-2.76-1.27-4.12-2-29.84-15.34-54.44-44.42-57.51-79.75 0 0 11.25-41.95 80.62-41.95 7.5 0 28.93-20.92 29.33-27-.09-2-42.54-18.87-59.09-35.18-8.85-8.71-13.05-12.91-16.77-16.06a69.58 69.58 0 0 0-6.31-4.77 113.05 113.05 0 0 1-.69-59.63c-25.06 11.41-44.55 29.45-58.71 45.37h-.12c-9.67-12.25-9-52.65-8.43-61.08-.12-.53-7.22 3.68-8.15 4.31a178.54 178.54 0 0 0-23.84 20.43 214 214 0 0 0-22.77 27.33 205.84 205.84 0 0 0-32.73 73.9c-.06.27-2.33 10.21-4 22.48q-.42 2.87-.78 5.74c-.57 3.69-1 7.71-1.44 14 0 .24 0 .48-.05.72-.18 2.71-.34 5.41-.49 8.12v1.24c0 134.7 109.21 243.89 243.92 243.89 120.64 0 220.82-87.58 240.43-202.62.41-3.12.74-6.26 1.11-9.41 4.85-41.83-.54-85.79-15.82-122.55Z"/></svg>';
22
+
23
+ $ie-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"/></svg>';
24
+
25
+ $safari-icon: '<svg viewBox="0 0 512 512" fill="#999"><path d="m274.69 274.69-37.38-37.38L166 346ZM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8Zm155.85 174.79 14.78-6.13a8 8 0 0 1 10.45 4.34 8 8 0 0 1-4.33 10.46L418 197.57a8 8 0 0 1-10.45-4.33 8 8 0 0 1 4.3-10.45ZM314.43 94l6.12-14.78a8 8 0 0 1 10.45-4.3 8 8 0 0 1 4.33 10.45l-6.13 14.78a8 8 0 0 1-10.45 4.33A8 8 0 0 1 314.43 94ZM256 60a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8 8 8 0 0 1-8-8V68a8 8 0 0 1 8-8Zm-75 14.92a8 8 0 0 1 10.46 4.33L197.57 94a8 8 0 1 1-14.78 6.12l-6.13-14.78A8 8 0 0 1 181 74.92Zm-63.58 42.49a8 8 0 0 1 11.31 0L140 128.72a8 8 0 0 1 0 11.28 8 8 0 0 1-11.31 0l-11.31-11.31a8 8 0 0 1 .03-11.28ZM60 256a8 8 0 0 1 8-8h16a8 8 0 0 1 8 8 8 8 0 0 1-8 8H68a8 8 0 0 1-8-8Zm40.15 73.21-14.78 6.13A8 8 0 0 1 74.92 331a8 8 0 0 1 4.33-10.46L94 314.43a8 8 0 0 1 10.45 4.33 8 8 0 0 1-4.3 10.45Zm4.33-136A8 8 0 0 1 94 197.57l-14.78-6.12a8 8 0 0 1-4.3-10.45 8 8 0 0 1 10.45-4.33l14.78 6.13a8 8 0 0 1 4.33 10.44ZM197.57 418l-6.12 14.78a8 8 0 0 1-14.79-6.12l6.13-14.78a8 8 0 1 1 14.78 6.12ZM264 444a8 8 0 0 1-8 8 8 8 0 0 1-8-8v-16a8 8 0 0 1 8-8 8 8 0 0 1 8 8Zm67-6.92a8 8 0 0 1-10.46-4.33L314.43 418a8 8 0 0 1 4.33-10.45 8 8 0 0 1 10.45 4.33l6.13 14.78a8 8 0 0 1-4.34 10.42Zm63.58-42.49a8 8 0 0 1-11.31 0L372 383.28a8 8 0 0 1 0-11.28 8 8 0 0 1 11.31 0l11.31 11.31a8 8 0 0 1-.03 11.28ZM286.25 286.25 110.34 401.66l115.41-175.91 175.91-115.41ZM437.08 331a8 8 0 0 1-10.45 4.33l-14.78-6.13a8 8 0 0 1-4.33-10.45 8 8 0 0 1 10.48-4.32l14.78 6.12a8 8 0 0 1 4.3 10.45Zm6.92-67h-16a8 8 0 0 1-8-8 8 8 0 0 1 8-8h16a8 8 0 0 1 8 8 8 8 0 0 1-8 8Z"/></svg>';
26
+
27
+ .wl-meta > {
28
+ span::before {
29
+ content: '';
30
+ width: 1em;
31
+ height: 1em;
32
+ display: inline-block;
33
+ background-repeat: no-repeat;
34
+ background-position: center center;
35
+ margin-right: 2px;
36
+ }
37
+
38
+ .wl-addr::before {
39
+ @include svg.background-svg($address-icon);
40
+ }
41
+
42
+ .wl-os::before,
43
+ .wl-browser::before {
44
+ @include svg.background-svg($default-icon);
45
+ }
46
+
47
+ .wl-os[data-value^='windows' i]::before {
48
+ @include svg.background-svg($window-icon);
49
+ }
50
+ .wl-os[data-value^='mac' i]::before,
51
+ .wl-os[data-value^='ios' i]::before,
52
+ .wl-os[data-value^='iphone' i]::before,
53
+ .wl-os[data-value^='ipad' i]::before {
54
+ @include svg.background-svg($apple-icon);
55
+ }
56
+
57
+ .wl-os[data-value^='linux' i]::before {
58
+ @include svg.background-svg($linux-icon);
59
+ }
60
+
61
+ .wl-os[data-value^='ubuntu' i]::before {
62
+ @include svg.background-svg($ubuntu-icon);
63
+ }
64
+ .wl-os[data-value^='android' i]::before {
65
+ @include svg.background-svg($android-icon);
66
+ }
67
+
68
+ .wl-browser[data-value^='chrome' i]::before {
69
+ @include svg.background-svg($chrome-icon);
70
+ }
71
+
72
+ .wl-browser[data-value^='edge' i]::before {
73
+ @include svg.background-svg($edge-icon);
74
+ }
75
+
76
+ .wl-browser[data-value^='firefox' i]::before {
77
+ @include svg.background-svg($firefox-icon);
78
+ }
79
+ .wl-browser[data-value^='safari' i]::before {
80
+ @include svg.background-svg($safari-icon);
81
+ }
82
+ .wl-browser[data-value^='ie' i]::before,
83
+ .wl-browser[data-value^='explorer' i]::before {
84
+ @include svg.background-svg($ie-icon);
85
+ }
86
+ }