mirror of
https://gitcode.com/Zengtudor/EnvEditorWebview.git
synced 2025-07-03 03:37:39 +00:00
update
This commit is contained in:
parent
51c5428a61
commit
37cc168d96
@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(eew CXX)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
find_package(webview REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
|
217
src/index.html
217
src/index.html
@ -1,104 +1,159 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Environment Variables Table</title>
|
||||
<title>Environment Variables Viewer</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 20px;
|
||||
body { font-family: system-ui, -apple-system, sans-serif; margin: 0; background: #f5f7fa; }
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 0 16px; }
|
||||
header { background: white; padding: 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
|
||||
h1 { color: #165DFF; margin: 0; }
|
||||
main { padding: 24px 0; }
|
||||
.card { background: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); padding: 16px; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th { text-align: left; padding: 12px 16px; background: #f9fafb; color: #6b7280; font-size: 12px; text-transform: uppercase; }
|
||||
td { padding: 12px 16px; border-bottom: 1px solid #e5e7eb; }
|
||||
tr:last-child td { border-bottom: none; }
|
||||
tr:nth-child(even) { background: #f9fafb; }
|
||||
tr:hover { background: #f3f4f6; }
|
||||
footer { background: #1d2129; color: white; text-align: center; padding: 20px 0; }
|
||||
.loading { text-align: center; color: #9ca3af; padding: 20px 0; }
|
||||
.error { text-align: center; color: #ef4444; padding: 20px 0; }
|
||||
a { color: #165DFF; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
.btn {
|
||||
background-color: #165DFF;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
font-size: 18px;
|
||||
text-align: left;
|
||||
.btn:hover {
|
||||
background-color: #0E42CC;
|
||||
}
|
||||
th, td {
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
.btn:active {
|
||||
background-color: #0A3199;
|
||||
}
|
||||
th {
|
||||
background-color: #f4f4f4;
|
||||
.scrollable {
|
||||
max-height: 80px;
|
||||
overflow-y: auto;
|
||||
max-width: 300px;
|
||||
border: 1px solid #e5e7eb;
|
||||
padding: 4px;
|
||||
border-radius: 2px;
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #f9f9f9;
|
||||
/* 自定义滚动条样式 */
|
||||
.scrollable::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
tr:hover {
|
||||
background-color: #f1f1f1;
|
||||
.scrollable::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
table, thead, tbody, th, td, tr {
|
||||
display: block;
|
||||
}
|
||||
th, td {
|
||||
text-align: right;
|
||||
padding: 10px;
|
||||
}
|
||||
th {
|
||||
background-color: #f4f4f4;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
td {
|
||||
border: none;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
td::before {
|
||||
content: attr(data-label);
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
.scrollable::-webkit-scrollbar-thumb {
|
||||
background: #c5c5c5;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.scrollable::-webkit-scrollbar-thumb:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Environment Variables</h1>
|
||||
<table id="envTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Rows will be dynamically inserted here -->
|
||||
</tbody>
|
||||
</table>
|
||||
<header>
|
||||
<div class="container">
|
||||
<h1>Environment Variables Viewer</h1>
|
||||
<p>Real-time system environment configuration</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<script script type="module">
|
||||
// TODO: async getEnvString() will be implemented elsewhere
|
||||
<main class="container">
|
||||
<button id="refreshBtn" class="btn">
|
||||
<i class="fa fa-refresh mr-1"></i> Refresh
|
||||
</button>
|
||||
<div class="card">
|
||||
<table id="envTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="envTableBody">
|
||||
<tr>
|
||||
<td colspan="2" class="loading">Loading environment variables...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
async function refreshEnvTable() {
|
||||
try {
|
||||
// 调用 getEnvString 函数并解析返回值
|
||||
const env = await window.getEnvString();
|
||||
console.log("Environment String:", env);
|
||||
<footer>
|
||||
<div class="container">
|
||||
<p>© 2025 Environment Variables Viewer | Author: Tudor 曾子愚</p>
|
||||
<p>
|
||||
<a href="https://blog.zziyu.cn" target="_blank">Blog</a> |
|
||||
<a href="https://gitcode.com/Zengtudor" target="_blank">GitCode</a> |
|
||||
<a href="mailto:Zengtudor@outlook.com" target="_blank">Email</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
// 清空表格内容
|
||||
const tableBody = document.querySelector("#envTable tbody");
|
||||
tableBody.innerHTML = "";
|
||||
<script>
|
||||
async function refreshEnvTable() {
|
||||
const tableBody = document.getElementById('envTableBody');
|
||||
tableBody.innerHTML = '<tr><td colspan="2" class="loading">Refreshing environment variables...</td></tr>';
|
||||
|
||||
try {
|
||||
const env = await window.getEnvString();
|
||||
tableBody.innerHTML = '';
|
||||
|
||||
// 填充表格
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
const row = document.createElement("tr");
|
||||
row.innerHTML = `
|
||||
<td data-label="Key">${key}</td>
|
||||
<td data-label="Value">${value}</td>
|
||||
if (!env || Object.keys(env).length === 0) {
|
||||
tableBody.innerHTML = '<tr><td colspan="2" class="loading">No environment variables found</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries(env).forEach(([key, value]) => {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${key}</td>
|
||||
<td><div class="scrollable" title="${value}">${value}</div></td>
|
||||
`;
|
||||
tableBody.appendChild(row);
|
||||
});
|
||||
} catch (error) {
|
||||
tableBody.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="2" class="error">Failed to load: ${error.message}</td>
|
||||
</tr>
|
||||
`;
|
||||
tableBody.appendChild(row);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to refresh environment table:", error);
|
||||
}
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
await refreshEnvTable();
|
||||
});
|
||||
// 页面加载时刷新表格
|
||||
// document.addEventListener("DOMContentLoaded", refreshEnvTable);
|
||||
</script>
|
||||
|
||||
document.addEventListener('DOMContentLoaded', refreshEnvTable);
|
||||
document.getElementById('refreshBtn').addEventListener('click', refreshEnvTable);
|
||||
|
||||
// Mock data for demonstration
|
||||
if (!window.getEnvString) {
|
||||
window.getEnvString = async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
return {
|
||||
NODE_ENV: 'development',
|
||||
PORT: '3000',
|
||||
DB_HOST: 'localhost',
|
||||
DB_USER: 'root',
|
||||
DB_PASSWORD: '********',
|
||||
API_KEY: 'sk-********************************',
|
||||
DEBUG_MODE: 'true',
|
||||
LONG_TEXT_VARIABLE: 'This is a very long text value that exceeds the normal display area. It should be scrollable within the container so users can view the entire content without truncation. This provides a better user experience when dealing with large environment variable values.'
|
||||
};
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
37
src/main.cpp
37
src/main.cpp
@ -8,6 +8,8 @@
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <webview/backends.hh>
|
||||
@ -49,20 +51,41 @@ std::ostream&operator<<(std::ostream &os,const std::vector<T> &v){
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::string envKvToJsonString(const vpss_t &v){
|
||||
std::stringstream ss;
|
||||
const auto toJsonString = [](const std::string_view &str)->std::string{
|
||||
std::stringstream ss;
|
||||
for(size_t i=0;i<str.size();i++){
|
||||
const std::unordered_set<char> set={'\\','\"'};
|
||||
if(set.find(str[i])!=set.end()){
|
||||
ss<<"\\";
|
||||
}
|
||||
ss<<str[i];
|
||||
}
|
||||
return ss.str();
|
||||
};
|
||||
if(v.size()==0)return "{}";
|
||||
ss<<"{";
|
||||
if(v.size()==1){
|
||||
ss<<"\""<<toJsonString(v[0].first)<<"\":\""<<toJsonString(v[0].second)<<"\"}";
|
||||
return ss.str();
|
||||
}
|
||||
for(size_t i = 0;i<v.size()-1;i++){
|
||||
ss<<"\""<<toJsonString(v[i].first)<<"\":\""<<toJsonString(v[i].second)<<"\",";
|
||||
}
|
||||
ss<<"\""<<toJsonString(v[v.size()-1].first)<<"\":\""<<toJsonString(v[v.size()-1].second)<<"\"}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int main(const int argc,char *argv[],char *env[]){
|
||||
try {
|
||||
std::cout<<getEnvKv()<<'\n';
|
||||
webview::webview wv(true,nullptr);
|
||||
wv.set_html(html);
|
||||
wv.bind("getEnvString",
|
||||
[](const std::string &req)->std::string {
|
||||
std::stringstream oss;
|
||||
oss<<getEnvKv();
|
||||
std::cout<<std::format("{{env:\"{}\"}}",getEnvKv()[0].first)<<'\n';
|
||||
return std::format("{{\"env\":\"{}\"}}",getEnvKv()[0].first);
|
||||
std::cout<<envKvToJsonString(getEnvKv())<<'\n';
|
||||
return envKvToJsonString(getEnvKv());
|
||||
});
|
||||
wv.set_html(html);
|
||||
wv.run();
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr<<e.what()<<'\n';
|
||||
|
Loading…
Reference in New Issue
Block a user