Skip to content

Commit 26f9263

Browse files
committed
feat: 技术 chip 换成 skillicons.dev 圆角卡片风格
简单图标的 google 域名国内访问不到、且 simpleicons 是单色色板视觉单调,换成 skillicons.dev 的圆角卡片彩色 SVG;slug 用「小写 + 去掉所有非字母数字」+ 一份手动 alias 表(vue.js → vue / tailwindcss → tailwind / aspnet → dotnet / javascript → js / typescript → ts 等)兜常见命名差异;Skill Icons 未收录会返回 0 宽空 SVG,onLoad 里通过 naturalWidth 判 0 回落本地色块。 将版本号提升到 1.3.67。
1 parent 0dd3760 commit 26f9263

3 files changed

Lines changed: 44 additions & 13 deletions

File tree

PRIVACY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ StackPrism / 栈棱镜(以下简称「本扩展」)是一款基于 Chrome / Edge
4242
- 没有遥测、没有广告 SDK、没有第三方分析、没有错误上报到云端
4343
- 扩展只发起两类网络请求,**均不**携带您的任何身份信息或浏览数据:
4444
1. 异步抓取**您当前访问页面自身已经加载的**少量 JS 文件首段(走浏览器缓存,不增加额外网络流量),用于在本地扫描该 JS 中的版权注释和 OAuth 入口 URL
45-
2.`cdn.simpleicons.org` 拉取技术品牌图标(请求体只包含一个公开技术名 slug,例如 react / vuedotjs / docker,不含您正在访问的页面 URL、识别结果或任何个人信息);图标如果 2 秒内未加载成功,扩展会自动回落到本地生成的首字母色块,绝不阻塞识别流程
45+
2.`skillicons.dev` 拉取技术品牌图标(请求只包含一个公开技术名 slug,例如 react / vue / docker,不含您正在访问的页面 URL、识别结果或任何个人信息);图标如果 2 秒内未加载成功或对方未收录,扩展会自动回落到本地生成的首字母色块,绝不阻塞识别流程
4646

4747
## 第三方共享
4848

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "stackprism",
33
"private": true,
4-
"version": "1.3.66",
4+
"version": "1.3.67",
55
"type": "module",
66
"description": "StackPrism 用于检测网页前端、后端、CDN、SaaS、广告营销、统计、登录、支付、网站程序和主题模板线索。",
77
"scripts": {

src/ui/components/TechChip.vue

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,48 @@
4646
return (letter || raw.charAt(0)).toUpperCase()
4747
})
4848
49-
// 走 cdn.simpleicons.org/<slug> 拉 SVG 图标。
50-
// SimpleIcons slug 规则:小写、空格/特殊字符删掉、`.` → `dot`、`+` → `plus`、`&` → `and`。
51-
// 没收录的(中文名 / 站点自家脚本 / 兜底「疑似前端库」)slug 为空或 404,2s 超时回落文字色块
49+
// Skill Icons(skillicons.dev)圆角卡片风格的技术 logo。slug 规则简单:小写、去掉所有非字母数字。
50+
// 几个 Skill Icons 与常见 tech.name 之间命名差异手动 alias 一下;命中不到的 slug 会拿到 0 宽空 SVG,
51+
// 我们在 onLoad 里通过 naturalWidth 判 0 回落文字色块。
52+
const SKILL_ALIASES: Record<string, string> = {
53+
vue: 'vue',
54+
vuejs: 'vue',
55+
vue3: 'vue',
56+
tailwindcss: 'tailwind',
57+
aspnet: 'dotnet',
58+
aspnetcore: 'dotnet',
59+
aspnetmvc: 'dotnet',
60+
cnet: 'dotnet',
61+
springboot: 'spring',
62+
springmvc: 'spring',
63+
springbootspringmvc: 'spring',
64+
expressjs: 'expressjs',
65+
express: 'expressjs',
66+
javascript: 'js',
67+
typescript: 'ts',
68+
csharp: 'cs',
69+
cpp: 'cpp',
70+
objectivec: 'c',
71+
angularjs: 'angular',
72+
angularangularjs: 'angular',
73+
github: 'github',
74+
githubcom: 'github',
75+
githubpages: 'github',
76+
githubassets: 'github',
77+
githubrawcontent: 'github'
78+
}
79+
5280
const toSlug = (raw: string): string => {
5381
const baseName = raw.split('/')[0].trim()
54-
return baseName
55-
.toLowerCase()
56-
.replace(/\./g, 'dot')
57-
.replace(/\+/g, 'plus')
58-
.replace(/&/g, 'and')
59-
.replace(/[^a-z0-9]/g, '')
82+
const normalized = baseName.toLowerCase().replace(/[^a-z0-9]/g, '')
83+
if (!normalized) return ''
84+
return SKILL_ALIASES[normalized] || normalized
6085
}
6186
6287
const iconUrl = computed(() => {
6388
const slug = toSlug(String(props.name || ''))
6489
if (!slug) return ''
65-
return `https://cdn.simpleicons.org/${slug}`
90+
return `https://skillicons.dev/icons?i=${slug}`
6691
})
6792
6893
const iconState = ref<'pending' | 'loaded' | 'failed'>(iconUrl.value ? 'pending' : 'failed')
@@ -76,8 +101,14 @@
76101
}
77102
}
78103
79-
const onLoad = () => {
104+
const onLoad = (event: Event) => {
80105
clearTimer()
106+
// Skill Icons 对没收录的 slug 会返回 0 宽 SVG,这里识破后回落色块
107+
const img = event.target as HTMLImageElement
108+
if (img && (img.naturalWidth === 0 || img.naturalHeight === 0)) {
109+
iconState.value = 'failed'
110+
return
111+
}
81112
iconState.value = 'loaded'
82113
}
83114

0 commit comments

Comments
 (0)