mirror of
https://gitcode.com/Zengtudor/EnvEditorWebview.git
synced 2025-07-03 11:47:40 +00:00
update
This commit is contained in:
parent
51c5428a61
commit
37cc168d96
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(eew CXX)
|
project(eew CXX)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
find_package(webview REQUIRED)
|
find_package(webview REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
195
src/index.html
195
src/index.html
@ -1,61 +1,81 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-cn">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Environment Variables Table</title>
|
<title>Environment Variables Viewer</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body { font-family: system-ui, -apple-system, sans-serif; margin: 0; background: #f5f7fa; }
|
||||||
font-family: Arial, sans-serif;
|
.container { max-width: 1200px; margin: 0 auto; padding: 0 16px; }
|
||||||
margin: 20px;
|
header { background: white; padding: 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
|
||||||
}
|
h1 { color: #165DFF; margin: 0; }
|
||||||
table {
|
main { padding: 24px 0; }
|
||||||
width: 100%;
|
.card { background: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); padding: 16px; }
|
||||||
border-collapse: collapse;
|
table { width: 100%; border-collapse: collapse; }
|
||||||
margin: 20px 0;
|
th { text-align: left; padding: 12px 16px; background: #f9fafb; color: #6b7280; font-size: 12px; text-transform: uppercase; }
|
||||||
font-size: 18px;
|
td { padding: 12px 16px; border-bottom: 1px solid #e5e7eb; }
|
||||||
text-align: left;
|
tr:last-child td { border-bottom: none; }
|
||||||
}
|
tr:nth-child(even) { background: #f9fafb; }
|
||||||
th, td {
|
tr:hover { background: #f3f4f6; }
|
||||||
padding: 12px;
|
footer { background: #1d2129; color: white; text-align: center; padding: 20px 0; }
|
||||||
border: 1px solid #ddd;
|
.loading { text-align: center; color: #9ca3af; padding: 20px 0; }
|
||||||
}
|
.error { text-align: center; color: #ef4444; padding: 20px 0; }
|
||||||
th {
|
a { color: #165DFF; text-decoration: none; }
|
||||||
background-color: #f4f4f4;
|
a:hover { text-decoration: underline; }
|
||||||
}
|
.btn {
|
||||||
tr:nth-child(even) {
|
background-color: #165DFF;
|
||||||
background-color: #f9f9f9;
|
color: white;
|
||||||
}
|
|
||||||
tr:hover {
|
|
||||||
background-color: #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: none;
|
||||||
border-bottom: 1px solid #ddd;
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
td::before {
|
.btn:hover {
|
||||||
content: attr(data-label);
|
background-color: #0E42CC;
|
||||||
float: left;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
.btn:active {
|
||||||
|
background-color: #0A3199;
|
||||||
|
}
|
||||||
|
.scrollable {
|
||||||
|
max-height: 80px;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-width: 300px;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #f9fafb;
|
||||||
|
}
|
||||||
|
/* 自定义滚动条样式 */
|
||||||
|
.scrollable::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
.scrollable::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
.scrollable::-webkit-scrollbar-thumb {
|
||||||
|
background: #c5c5c5;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.scrollable::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #a8a8a8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Environment Variables</h1>
|
<header>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Environment Variables Viewer</h1>
|
||||||
|
<p>Real-time system environment configuration</p>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="container">
|
||||||
|
<button id="refreshBtn" class="btn">
|
||||||
|
<i class="fa fa-refresh mr-1"></i> Refresh
|
||||||
|
</button>
|
||||||
|
<div class="card">
|
||||||
<table id="envTable">
|
<table id="envTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -63,42 +83,77 @@
|
|||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody id="envTableBody">
|
||||||
<!-- Rows will be dynamically inserted here -->
|
<tr>
|
||||||
|
<td colspan="2" class="loading">Loading environment variables...</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
<script script type="module">
|
<footer>
|
||||||
// TODO: async getEnvString() will be implemented elsewhere
|
<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>
|
||||||
|
|
||||||
|
<script>
|
||||||
async function refreshEnvTable() {
|
async function refreshEnvTable() {
|
||||||
|
const tableBody = document.getElementById('envTableBody');
|
||||||
|
tableBody.innerHTML = '<tr><td colspan="2" class="loading">Refreshing environment variables...</td></tr>';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用 getEnvString 函数并解析返回值
|
|
||||||
const env = await window.getEnvString();
|
const env = await window.getEnvString();
|
||||||
console.log("Environment String:", env);
|
tableBody.innerHTML = '';
|
||||||
|
|
||||||
// 清空表格内容
|
if (!env || Object.keys(env).length === 0) {
|
||||||
const tableBody = document.querySelector("#envTable tbody");
|
tableBody.innerHTML = '<tr><td colspan="2" class="loading">No environment variables found</td></tr>';
|
||||||
tableBody.innerHTML = "";
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 填充表格
|
Object.entries(env).forEach(([key, value]) => {
|
||||||
for (const [key, value] of Object.entries(env)) {
|
const row = document.createElement('tr');
|
||||||
const row = document.createElement("tr");
|
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td data-label="Key">${key}</td>
|
<td>${key}</td>
|
||||||
<td data-label="Value">${value}</td>
|
<td><div class="scrollable" title="${value}">${value}</div></td>
|
||||||
`;
|
`;
|
||||||
tableBody.appendChild(row);
|
tableBody.appendChild(row);
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to refresh environment table:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
|
||||||
await refreshEnvTable();
|
|
||||||
});
|
});
|
||||||
// 页面加载时刷新表格
|
} catch (error) {
|
||||||
// document.addEventListener("DOMContentLoaded", refreshEnvTable);
|
tableBody.innerHTML = `
|
||||||
</script>
|
<tr>
|
||||||
|
<td colspan="2" class="error">Failed to load: ${error.message}</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
37
src/main.cpp
37
src/main.cpp
@ -8,6 +8,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <webview/backends.hh>
|
#include <webview/backends.hh>
|
||||||
@ -49,20 +51,41 @@ std::ostream&operator<<(std::ostream &os,const std::vector<T> &v){
|
|||||||
return os;
|
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[]){
|
int main(const int argc,char *argv[],char *env[]){
|
||||||
try {
|
try {
|
||||||
std::cout<<getEnvKv()<<'\n';
|
|
||||||
webview::webview wv(true,nullptr);
|
webview::webview wv(true,nullptr);
|
||||||
wv.set_html(html);
|
|
||||||
wv.bind("getEnvString",
|
wv.bind("getEnvString",
|
||||||
[](const std::string &req)->std::string {
|
[](const std::string &req)->std::string {
|
||||||
std::stringstream oss;
|
std::cout<<envKvToJsonString(getEnvKv())<<'\n';
|
||||||
oss<<getEnvKv();
|
return envKvToJsonString(getEnvKv());
|
||||||
std::cout<<std::format("{{env:\"{}\"}}",getEnvKv()[0].first)<<'\n';
|
|
||||||
return std::format("{{\"env\":\"{}\"}}",getEnvKv()[0].first);
|
|
||||||
});
|
});
|
||||||
|
wv.set_html(html);
|
||||||
wv.run();
|
wv.run();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr<<e.what()<<'\n';
|
std::cerr<<e.what()<<'\n';
|
||||||
|
Loading…
Reference in New Issue
Block a user