Spaces:
Sleeping
Sleeping
Commit ·
7b84ccf
1
Parent(s): 8bc4ec7
feat: enhance functionality, fix sidepanel bug, and switch to local static assets
Browse files- app.py +10 -3
- extension_templates/sidepanel.html +29 -0
- static/js/tailwindcss.js +0 -0
- static/js/vue.global.js +0 -0
- templates/index.html +18 -10
app.py
CHANGED
|
@@ -78,8 +78,12 @@ def generate():
|
|
| 78 |
# 6. Content Script
|
| 79 |
if context['include_content_script']:
|
| 80 |
write_template('content-script.js', 'content-script.js')
|
| 81 |
-
|
| 82 |
-
# 7.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
zf.writestr('images/icon16.png', generate_icon(16))
|
| 84 |
zf.writestr('images/icon48.png', generate_icon(48))
|
| 85 |
zf.writestr('images/icon128.png', generate_icon(128))
|
|
@@ -93,7 +97,10 @@ def generate():
|
|
| 93 |
)
|
| 94 |
|
| 95 |
except Exception as e:
|
|
|
|
|
|
|
| 96 |
return jsonify({'error': str(e)}), 500
|
| 97 |
|
| 98 |
if __name__ == '__main__':
|
| 99 |
-
|
|
|
|
|
|
| 78 |
# 6. Content Script
|
| 79 |
if context['include_content_script']:
|
| 80 |
write_template('content-script.js', 'content-script.js')
|
| 81 |
+
|
| 82 |
+
# 7. Side Panel
|
| 83 |
+
if context['include_side_panel']:
|
| 84 |
+
write_template('sidepanel.html', 'sidepanel.html')
|
| 85 |
+
|
| 86 |
+
# 8. Icons (Generated)
|
| 87 |
zf.writestr('images/icon16.png', generate_icon(16))
|
| 88 |
zf.writestr('images/icon48.png', generate_icon(48))
|
| 89 |
zf.writestr('images/icon128.png', generate_icon(128))
|
|
|
|
| 97 |
)
|
| 98 |
|
| 99 |
except Exception as e:
|
| 100 |
+
import traceback
|
| 101 |
+
traceback.print_exc()
|
| 102 |
return jsonify({'error': str(e)}), 500
|
| 103 |
|
| 104 |
if __name__ == '__main__':
|
| 105 |
+
port = int(os.environ.get('PORT', 7860))
|
| 106 |
+
app.run(host='0.0.0.0', port=port)
|
extension_templates/sidepanel.html
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
<head>
|
| 4 |
+
<title>Side Panel</title>
|
| 5 |
+
<style>
|
| 6 |
+
body {
|
| 7 |
+
width: 100%;
|
| 8 |
+
height: 100vh;
|
| 9 |
+
margin: 0;
|
| 10 |
+
padding: 10px;
|
| 11 |
+
font-family: sans-serif;
|
| 12 |
+
box-sizing: border-box;
|
| 13 |
+
}
|
| 14 |
+
h1 {
|
| 15 |
+
font-size: 16px;
|
| 16 |
+
margin-top: 0;
|
| 17 |
+
}
|
| 18 |
+
p {
|
| 19 |
+
font-size: 14px;
|
| 20 |
+
color: #555;
|
| 21 |
+
}
|
| 22 |
+
</style>
|
| 23 |
+
</head>
|
| 24 |
+
<body>
|
| 25 |
+
<h1>Side Panel</h1>
|
| 26 |
+
<p>This is your extension's side panel.</p>
|
| 27 |
+
<p>You can add more content here.</p>
|
| 28 |
+
</body>
|
| 29 |
+
</html>
|
static/js/tailwindcss.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/js/vue.global.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
templates/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>Chrome 插件工坊 (Chrome Extension Studio)</title>
|
| 7 |
-
<script src="
|
| 8 |
-
<script src="
|
| 9 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
| 10 |
<style>
|
| 11 |
body { background-color: #f3f4f6; }
|
|
@@ -29,9 +29,9 @@
|
|
| 29 |
<p class="text-xs text-gray-500">Chrome Extension Studio</p>
|
| 30 |
</div>
|
| 31 |
</div>
|
| 32 |
-
<button @click="generateZip" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition flex items-center gap-2 shadow-lg shadow-blue-200">
|
| 33 |
-
<i class="fa-solid fa-download"></i>
|
| 34 |
-
下载源码 (ZIP)
|
| 35 |
</button>
|
| 36 |
</header>
|
| 37 |
|
|
@@ -200,6 +200,7 @@
|
|
| 200 |
];
|
| 201 |
|
| 202 |
const newHostPerm = ref('');
|
|
|
|
| 203 |
|
| 204 |
const addHostPerm = () => {
|
| 205 |
if(newHostPerm.value && !form.value.host_permissions.includes(newHostPerm.value)) {
|
|
@@ -253,14 +254,17 @@
|
|
| 253 |
}
|
| 254 |
if (form.value.include_side_panel) {
|
| 255 |
manifest.side_panel = { default_path: "sidepanel.html" };
|
| 256 |
-
|
| 257 |
-
|
|
|
|
| 258 |
}
|
| 259 |
|
| 260 |
return JSON.stringify(manifest, null, 2);
|
| 261 |
});
|
| 262 |
|
| 263 |
const generateZip = async () => {
|
|
|
|
|
|
|
| 264 |
try {
|
| 265 |
const response = await fetch('/generate', {
|
| 266 |
method: 'POST',
|
|
@@ -279,11 +283,14 @@
|
|
| 279 |
window.URL.revokeObjectURL(url);
|
| 280 |
document.body.removeChild(a);
|
| 281 |
} else {
|
| 282 |
-
|
|
|
|
| 283 |
}
|
| 284 |
} catch (e) {
|
| 285 |
console.error(e);
|
| 286 |
-
alert('Error generating zip');
|
|
|
|
|
|
|
| 287 |
}
|
| 288 |
};
|
| 289 |
|
|
@@ -294,7 +301,8 @@
|
|
| 294 |
newHostPerm,
|
| 295 |
addHostPerm,
|
| 296 |
manifestJson,
|
| 297 |
-
generateZip
|
|
|
|
| 298 |
};
|
| 299 |
}
|
| 300 |
}).mount('#app');
|
|
|
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>Chrome 插件工坊 (Chrome Extension Studio)</title>
|
| 7 |
+
<script src="/static/js/tailwindcss.js"></script>
|
| 8 |
+
<script src="/static/js/vue.global.js"></script>
|
| 9 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
| 10 |
<style>
|
| 11 |
body { background-color: #f3f4f6; }
|
|
|
|
| 29 |
<p class="text-xs text-gray-500">Chrome Extension Studio</p>
|
| 30 |
</div>
|
| 31 |
</div>
|
| 32 |
+
<button @click="generateZip" :disabled="isGenerating" class="bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white px-6 py-2 rounded-lg font-medium transition flex items-center gap-2 shadow-lg shadow-blue-200">
|
| 33 |
+
<i class="fa-solid" :class="isGenerating ? 'fa-spinner fa-spin' : 'fa-download'"></i>
|
| 34 |
+
{{ isGenerating ? '正在生成...' : '下载源码 (ZIP)' }}
|
| 35 |
</button>
|
| 36 |
</header>
|
| 37 |
|
|
|
|
| 200 |
];
|
| 201 |
|
| 202 |
const newHostPerm = ref('');
|
| 203 |
+
const isGenerating = ref(false);
|
| 204 |
|
| 205 |
const addHostPerm = () => {
|
| 206 |
if(newHostPerm.value && !form.value.host_permissions.includes(newHostPerm.value)) {
|
|
|
|
| 254 |
}
|
| 255 |
if (form.value.include_side_panel) {
|
| 256 |
manifest.side_panel = { default_path: "sidepanel.html" };
|
| 257 |
+
if (!manifest.permissions.includes('sidePanel')) {
|
| 258 |
+
manifest.permissions.push('sidePanel');
|
| 259 |
+
}
|
| 260 |
}
|
| 261 |
|
| 262 |
return JSON.stringify(manifest, null, 2);
|
| 263 |
});
|
| 264 |
|
| 265 |
const generateZip = async () => {
|
| 266 |
+
if (isGenerating.value) return;
|
| 267 |
+
isGenerating.value = true;
|
| 268 |
try {
|
| 269 |
const response = await fetch('/generate', {
|
| 270 |
method: 'POST',
|
|
|
|
| 283 |
window.URL.revokeObjectURL(url);
|
| 284 |
document.body.removeChild(a);
|
| 285 |
} else {
|
| 286 |
+
const errorData = await response.json();
|
| 287 |
+
alert('Generate failed: ' + (errorData.error || 'Unknown error'));
|
| 288 |
}
|
| 289 |
} catch (e) {
|
| 290 |
console.error(e);
|
| 291 |
+
alert('Error generating zip: ' + e.message);
|
| 292 |
+
} finally {
|
| 293 |
+
isGenerating.value = false;
|
| 294 |
}
|
| 295 |
};
|
| 296 |
|
|
|
|
| 301 |
newHostPerm,
|
| 302 |
addHostPerm,
|
| 303 |
manifestJson,
|
| 304 |
+
generateZip,
|
| 305 |
+
isGenerating
|
| 306 |
};
|
| 307 |
}
|
| 308 |
}).mount('#app');
|