Skip to content

Commit 0910164

Browse files
committed
feat: init
0 parents  commit 0910164

27 files changed

Lines changed: 7832 additions & 0 deletions

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
.output
12+
stats.html
13+
stats-*.json
14+
.wxt
15+
web-ext.config.ts
16+
17+
# Editor directories and files
18+
.vscode/*
19+
!.vscode/extensions.json
20+
!.vscode/settings.json
21+
.idea
22+
.DS_Store
23+
*.suo
24+
*.ntvs*
25+
*.njsproj
26+
*.sln
27+
*.sw?

.vscode/extensions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"recommendations": ["Vue.volar"]
3+
}

.vscode/settings.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
// Disable the default formatter, use eslint instead
3+
"prettier.enable": false,
4+
"editor.formatOnSave": false,
5+
6+
// Auto fix
7+
"editor.codeActionsOnSave": {
8+
"source.fixAll.eslint": "explicit",
9+
"source.organizeImports": "never"
10+
},
11+
12+
// Silent the stylistic rules in you IDE, but still auto fix them
13+
"eslint.rules.customizations": [
14+
{ "rule": "style/*", "severity": "off", "fixable": true },
15+
{ "rule": "format/*", "severity": "off", "fixable": true },
16+
{ "rule": "*-indent", "severity": "off", "fixable": true },
17+
{ "rule": "*-spacing", "severity": "off", "fixable": true },
18+
{ "rule": "*-spaces", "severity": "off", "fixable": true },
19+
{ "rule": "*-order", "severity": "off", "fixable": true },
20+
{ "rule": "*-dangle", "severity": "off", "fixable": true },
21+
{ "rule": "*-newline", "severity": "off", "fixable": true },
22+
{ "rule": "*quotes", "severity": "off", "fixable": true },
23+
{ "rule": "*semi", "severity": "off", "fixable": true }
24+
],
25+
26+
// Enable eslint for all supported languages
27+
"eslint.validate": [
28+
"javascript",
29+
"javascriptreact",
30+
"typescript",
31+
"typescriptreact",
32+
"vue",
33+
"html",
34+
"markdown",
35+
"json",
36+
"jsonc",
37+
"yaml",
38+
"toml",
39+
"xml",
40+
"gql",
41+
"graphql",
42+
"astro",
43+
"svelte",
44+
"css",
45+
"less",
46+
"scss",
47+
"pcss",
48+
"postcss"
49+
]
50+
}

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# WXT + Vue 3
2+
3+
This template should help get you started developing with Vue 3 in WXT.
4+
5+
## Recommended IDE Setup
6+
7+
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar).

assets/main.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
body {
6+
padding: 16px;
7+
overflow-x: hidden;
8+
overflow-y: scroll;
9+
}
10+
11+
.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell{
12+
background-color: inherit !important;
13+
}

assets/vue.svg

Lines changed: 1 addition & 0 deletions
Loading

components/HelloWorld.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script lang="ts" setup>
2+
import { ref } from 'vue';
3+
4+
defineProps({
5+
msg: String,
6+
});
7+
8+
const count = ref(0);
9+
</script>
10+
11+
<template>
12+
<h1>{{ msg }}</h1>
13+
</template>
14+
15+
<style scoped>
16+
.read-the-docs {
17+
color: #888;
18+
}
19+
</style>
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<script setup lang="ts">
2+
import { ElBacktop, ElButton, ElCheckbox, ElIcon, ElOption, ElSelect, ElTable, ElTableColumn, ElText, ElTooltip } from 'element-plus'
3+
import { computed, onMounted, reactive, ref } from 'vue'
4+
import { formatStyle, type FormatStyleValue } from './formatStyle'
5+
6+
type SelectedElType = {
7+
valueType: 'left' | 'right'
8+
} & FormatStyleValue
9+
10+
interface CssDiffsType {
11+
property: string
12+
left: string
13+
right: string
14+
isDiff: boolean
15+
}
16+
17+
const selectedEl: Array<SelectedElType> = reactive([])
18+
const cssDiffs: Array<CssDiffsType> = reactive([])
19+
20+
const isAllProperty = ref(false)
21+
const isLoadComplete = ref(false)
22+
23+
onMounted(() => {
24+
chrome.devtools.panels.elements.onSelectionChanged.addListener(() => {
25+
chrome.devtools.inspectedWindow.eval(
26+
`(() => document.readyState)($0)`,
27+
(readyState: Document['readyState']) => {
28+
if (readyState === 'complete') {
29+
isLoadComplete.value = true
30+
}
31+
else {
32+
isLoadComplete.value = false
33+
}
34+
},
35+
)
36+
37+
chrome.devtools.inspectedWindow.eval(
38+
`(${formatStyle.toString()})($0)`,
39+
(result: FormatStyleValue, isException) => {
40+
if (!isException && result != null && isLoadComplete.value) {
41+
saveSelectedEl(result)
42+
}
43+
},
44+
)
45+
})
46+
})
47+
48+
function saveSelectedEl(result: FormatStyleValue) {
49+
if (selectedEl.length === 2)
50+
return
51+
52+
const valueType = !selectedEl.length ? 'left' : 'right'
53+
selectedEl.push({ ...result, valueType })
54+
55+
if (selectedEl.length === 2) {
56+
compareSelectedEl()
57+
}
58+
}
59+
60+
function clearSelection() {
61+
selectedEl.length = 0
62+
cssDiffs.length = 0
63+
}
64+
65+
function compareSelectedEl() {
66+
const [{ style: styles1 = {} }, { style: styles2 = {} }] = selectedEl
67+
68+
const diffs: Array<CssDiffsType> = []
69+
70+
const allProperties = new Set([
71+
...Object.keys(styles1),
72+
...Object.keys(styles2),
73+
])
74+
75+
allProperties.forEach((property) => {
76+
const left = styles1[property] || '未定义'
77+
const right = styles2[property] || '未定义'
78+
79+
diffs.push({
80+
property,
81+
left,
82+
right,
83+
isDiff: left !== right,
84+
})
85+
})
86+
87+
cssDiffs.push(...diffs)
88+
}
89+
90+
const renderCssDiffs = computed(() => {
91+
return isAllProperty.value
92+
? cssDiffs
93+
: cssDiffs.filter(css => css.isDiff)
94+
})
95+
96+
function tableCellClassName({ columnIndex }: { columnIndex: number }) {
97+
if (!columnIndex) {
98+
return 'text-[var(--el-table-text-color)]'
99+
}
100+
}
101+
102+
function tableRowClassName({ row }: { row: CssDiffsType }) {
103+
if (row.isDiff) {
104+
return '!bg-[#ffe6e6] text-[red]'
105+
}
106+
else {
107+
return '!bg-[#e6ffe6] text-[green]'
108+
}
109+
}
110+
111+
function filterJoin(...arg: Array<any>) {
112+
return arg.filter(Boolean).join(' $$ ')
113+
}
114+
</script>
115+
116+
<template>
117+
<div class="relative">
118+
<h2 class="font-bold text-center text-lg">
119+
DOM Diff
120+
</h2>
121+
122+
<ElSelect v-model="$i18n.locale" class="!w-[100px] !absolute !right-0 !top-0" size="small">
123+
<ElOption v-for="locale in $i18n.availableLocales" :key="`locale-${locale}`" :value="locale">
124+
{{ locale }}
125+
</ElOption>
126+
</ElSelect>
127+
128+
<ElText class="block" type="primary">
129+
{{ $t('info') }}
130+
</ElText>
131+
132+
<ElButton class="mt-[10px]" type="warning" plain @click="clearSelection">
133+
{{ $t('removeBtn') }}
134+
</ElButton>
135+
136+
<ElText v-if="!renderCssDiffs.length" class="block !mt-[10px]" type="danger">
137+
{{ $t('selectedInfo') }}
138+
</ElText>
139+
140+
<div class="flex justify-end">
141+
<ElCheckbox v-model="isAllProperty" :label="$t('isAllProperty')" />
142+
</div>
143+
<ElTable
144+
class="w-full"
145+
border
146+
:data="renderCssDiffs"
147+
:cell-class-name="tableCellClassName"
148+
:row-class-name="tableRowClassName"
149+
>
150+
<ElTableColumn prop="property" :label="$t('property')" />
151+
<template v-for="(el) in selectedEl" :key="el.valueType">
152+
<ElTableColumn :prop="el.valueType">
153+
<template #header>
154+
<span class="align-middle">{{ filterJoin(el.tag, el.id, el.class) }}</span>
155+
156+
<ElTooltip :content="$t('tableColumnInfo')" trigger="click">
157+
<ElIcon class="align-middle ml-[4px]">
158+
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><path fill="currentColor" d="M512 64a448 448 0 1 1 0 896a448 448 0 0 1 0-896m0 832a384 384 0 0 0 0-768a384 384 0 0 0 0 768m48-176a48 48 0 1 1-96 0a48 48 0 0 1 96 0m-48-464a32 32 0 0 1 32 32v288a32 32 0 0 1-64 0V288a32 32 0 0 1 32-32" /></svg>
159+
</ElIcon>
160+
</ElTooltip>
161+
</template>
162+
</ElTableColumn>
163+
</template>
164+
</ElTable>
165+
166+
<ElBacktop :right="20" :bottom="30" />
167+
</div>
168+
</template>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export interface FormatStyleValue {
2+
tag: string
3+
id?: string
4+
class?: string
5+
style?: Record<string, any>
6+
}
7+
8+
export function formatStyle(element: Element): FormatStyleValue | null {
9+
if (!element) {
10+
return null
11+
}
12+
13+
const styles = (element as Node)?.ownerDocument?.defaultView?.getComputedStyle(element)
14+
const outValue: Record<string, any> = {}
15+
16+
if (styles) {
17+
for (let i = 0; i <= styles.length; i++) {
18+
const StyleKey = styles[i]
19+
const StyleValue = styles.getPropertyValue(StyleKey)
20+
outValue[StyleKey] = StyleValue
21+
}
22+
}
23+
24+
const id = (element.attributes?.getNamedItem('id')) ? element.attributes?.getNamedItem('id')!.value : undefined
25+
const _class = (element.attributes?.getNamedItem('class')) ? element.attributes?.getNamedItem('class')!.value : undefined
26+
27+
return {
28+
tag: element.tagName,
29+
id,
30+
class: _class,
31+
style: outValue,
32+
}
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>devtools-panel</title>
7+
<link href="~/assets/main.css" rel="stylesheet" />
8+
9+
</head>
10+
<body>
11+
<div id="app"></div>
12+
<script type="module" src="./main.ts"></script>
13+
</body>
14+
</html>

0 commit comments

Comments
 (0)