-
Notifications
You must be signed in to change notification settings - Fork 0
/
custom-index.html
385 lines (335 loc) · 17.6 KB
/
custom-index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/prism.css">
<link rel="stylesheet" href="./css/styles.css">
<script src="./js/prism.js" defer></script>
<script src="./custom-index.js" type="module"></script>
<script src="./js/zip.js"></script>
<title>定義書RustコードコンバータWASM</title>
<meta name="description" content="システム定義書からRustの構造体を自動生成するサイトです。このページではご自身の任意のCSVフォーマットから定義書を作成することgできます。" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Google tag (gtag.js) -->
<meta name="google-site-verification" content="flysVjQiakJuvdDqcnNSuTyz0whOo4ILWFb7fO0EPU4" />
<script async src="https://www.googletagmanager.com/gtag/js?id=G-3EFFRMQQN7"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-3EFFRMQQN7');
</script>
<meta name="google-adsense-account" content="ca-pub-3637968081702806">
</head>
<body>
<header>
<h1>定義書RustコードコンバータWASM</h1>
<a href="https://github.com/sotanengel/class-creator-rust-wasm" target="_blank" style="position: absolute; top: 50%; right: 20px; transform: translateY(-50%);">
<img src="img/github-mark.png" alt="GitHub" style="width: 40px; height: 40px;">
</a>
</header>
<main>
<!-- タブメニュー -->
<div class="tabs">
<div class="tab active" data-tab="sample" data-url="index.html">サンプルCSV変換</div>
<div class="tab" data-url="custom-index.html">カスタムCSV変換</div>
</div>
<!-- サンプルCSV変換タブ内容 -->
<div id="sample" class="tab-content active">
<div id="fukidashi" style="display:none; position: relative;">
このURLをブックマークすると次回以降開始位置の入力が省略できます👀
</div>
<!-- テーブルの追加 -->
<table>
<thead>
<tr>
<th>開始セル位置</th>
<th>行(半角数字)</th>
<th>列(半角数字)</th>
</tr>
</thead>
<tbody>
<tr>
<td>構造体名*</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
<tr>
<td>構造体詳細</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
<tr>
<td>論理名*</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
<tr>
<td>物理名*</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
<tr>
<td>型情報*</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
<tr>
<td>詳細情報</td>
<td><input type="number" min="1" placeholder="行番号" class="cell-input"></td>
<td><input type="number" min="1" placeholder="列番号" class="cell-input"></td>
</tr>
</tbody>
</table>
<div id="param-message" style="display:none; color: red; text-align: center;">
構造体名・論理名・物理名・型のセルの位置を記載してください
</div>
<div id="fukidashi" style="display:none; position: relative;">
今、URLをお気に入りすると次回以降セル情報の省略できます👀
</div>
<div id="drop-zone" class="drop-zone" style="display: none;">
<div id="csv-message" style="display: none; text-align: center;">
CSVファイルをドロップするか、下のボタンから選択してください
</div>
<input type="file" id="file-input" accept=".csv">
</div>
<div id="radio-buttons-container">
<label><input type="radio" name="impl-option" value="include" checked> 構造体 + コンストラクタ</label>
<label><input type="radio" name="impl-option" value="struct-only"> 構造体のみ</label>
<button id="re-output-btn">再出力</button>
</div>
<pre id="code-block"><code id="output" class="language-rust"></code></pre>
<a id="download-btn" href="#" download="struct_output.txt">生成コードのダウンロード!</a>
</div>
<!-- 使い方の折りたたみメニュー -->
<button class="collapsible">使い方</button>
<div class="content">
<p>1. ご自身で定義書CSVを用意します。(※構造体名・論理名・物理名・型は必ず用意してください。)</p><img src="img/example-custom-csv.png" width="600">
<p>2. 開始位置を以下の例を参考に記載します。(※全て記入した状態でブックマークすると設定が保存できます!)</p><img src="img/example-custom-csv-mapping.png" width="600"><br><img src="img/example-custom-csv-input.png" width="1000">
<p>3. ファイルを選択ボタンから書き換えたファイルを選択します。</p>
<p>4. 「生成コードのダウンロード」ボタンを押して、構造体コードを保存します。(構造体のみで良い場合には「構造体のみ」を選択し、再出力ボタンを押してください)</p>
<img src="img/example-custom-converted-page-image.png" width="600">
</div>
</div>
</main>
<div id="footer-placeholder"></div>
<script>
const tabs = document.querySelectorAll('.tab');
const dropZone = document.getElementById('drop-zone');
const fileInput = document.getElementById('file-input');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
if (tab.dataset.url) {
// URLが設定されている場合は、そのURLにリダイレクト
window.location.href = tab.dataset.url;
} else {
// 通常のタブ切り替え処理
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
const activeContent = document.getElementById(tab.dataset.tab);
activeContent.classList.add('active');
}
});
});
// 入力欄の値をURLパラメータに追加する関数
function updateUrlParameters() {
const params = new URLSearchParams();
const rows = document.querySelectorAll('tbody tr');
let hasRequiredParams = true;
rows.forEach((row, index) => {
const inputs = row.querySelectorAll('input[type="number"]');
if (inputs.length === 2) {
const rowNumber = inputs[0].value;
const columnNumber = inputs[1].value;
const paramName = [
'struct_name_position',
'struct_detail_position',
'logical_name_position',
'physical_name_position',
'type_position',
'detail_position'
][index];
// 必須パラメータがすべて入力されているかチェック
if (['struct_name_position', 'logical_name_position', 'physical_name_position', 'type_position'].includes(paramName) && (!rowNumber || !columnNumber)) {
hasRequiredParams = false;
}
if (rowNumber && columnNumber) {
params.set(paramName, `${rowNumber}-${columnNumber}`);
}
}
});
// URLを更新
window.history.replaceState({}, '', `${location.pathname}?${params.toString()}`);
// ファイル選択ボタンの表示制御
const fileInput = document.getElementById('file-input');
const message = document.getElementById('param-message');
const favoriteMessage = document.getElementById('fukidashi');
const inputmessage = document.getElementById('csv-message');
if (hasRequiredParams) {
fileInput.style.display = 'block';
message.style.display = 'none';
favoriteMessage.style.display = 'block'; // 吹き出しメッセージを表示
inputmessage.style.display = 'block'; // CSVメッセージを表示
document.getElementById('drop-zone').style.display = 'block';
document.getElementById('drop-zone').addEventListener('dragover', (event) => {
event.preventDefault(); // デフォルトの動作を無効化
});
} else {
fileInput.style.display = 'none';
message.style.display = 'block';
favoriteMessage.style.display = 'none'; // 吹き出しメッセージを非表示
inputmessage.style.display = 'none'; // CSVメッセージを隠す
document.getElementById('drop-zone').style.display = 'none';
document.getElementById('drop-zone').removeEventListener('drop', handleDrop); // ドロップイベントを削除
}
}
// 入力欄の変更イベントリスナーを追加
const numberInputs = document.querySelectorAll('input[type="number"]');
numberInputs.forEach(input => {
input.addEventListener('input', (event) => {
updateUrlParameters();
syncRowNumbers(event.target); // 同時に他の行番号を同期
});
});
// 特定の入力が変更されたときに他の行番号を同期する関数
function syncRowNumbers(changedInput) {
const rows = document.querySelectorAll('tbody tr');
const changedRowIndex = Array.from(rows).findIndex(row => row.querySelector('input[type="number"]') === changedInput);
// 論理名、物理名、型情報の開始位置の行インデックス
const syncedIndices = [2, 3, 4]; // 論理名、物理名、型情報の行番号
// 変更された行が論理名、物理名、型情報のいずれかの場合のみ処理
if (syncedIndices.includes(changedRowIndex)) {
const newValue = changedInput.value; // 変更された新しい値
// 同期が必要な行を更新
syncedIndices.forEach(index => {
const row = rows[index];
const inputs = row.querySelectorAll('input[type="number"]');
inputs[0].value = newValue; // 行番号を更新
});
}
}
// ページ読み込み時にURLパラメータから入力欄を設定する関数
function setInputValuesFromUrl() {
const params = new URLSearchParams(window.location.search);
const rowInputs = document.querySelectorAll('tbody tr');
let hasRequiredParams = true;
rowInputs.forEach((row, index) => {
const inputs = row.querySelectorAll('input[type="number"]');
const paramName = [
'struct_name_position',
'struct_detail_position',
'logical_name_position',
'physical_name_position',
'type_position',
'detail_position'
][index];
if (params.has(paramName)) {
const value = params.get(paramName);
const [rowNumber, columnNumber] = value.split('-');
if (inputs.length === 2) {
inputs[0].value = rowNumber; // 行番号
inputs[1].value = columnNumber; // 列番号
}
// 必須パラメータのチェック
if (['struct_name_position', 'logical_name_position', 'physical_name_position', 'type_position'].includes(paramName) && (!rowNumber || !columnNumber)) {
hasRequiredParams = false;
}
}
});
// ファイル選択ボタンの表示制御
const fileInput = document.getElementById('file-input');
const message = document.getElementById('param-message');
const favoriteMessage = document.getElementById('fukidashi');
const inputmessage = document.getElementById('csv-message');
if (hasRequiredParams) {
fileInput.style.display = 'block';
message.style.display = 'none';
favoriteMessage.style.display = 'block'; // 吹き出しメッセージを表示
inputmessage.style.display = 'block'; // CSVメッセージを表示
document.getElementById('drop-zone').style.display = 'block';
document.getElementById('drop-zone').addEventListener('dragover', (event) => {
event.preventDefault(); // デフォルトの動作を無効化
});
} else {
fileInput.style.display = 'none';
message.style.display = 'block';
favoriteMessage.style.display = 'none'; // 吹き出しメッセージを非表示
inputmessage.style.display = 'none'; // CSVメッセージを隠す
document.getElementById('drop-zone').style.display = 'none';
document.getElementById('drop-zone').removeEventListener('drop', handleDrop); // ドロップイベントを削除
}
// URLを更新
updateUrlParameters();
}
// ページが読み込まれたときに入力欄を設定
document.addEventListener('DOMContentLoaded', () => {
setInputValuesFromUrl();
});
// フッターを読み込む関数
function loadFooter() {
fetch('footer.html')
.then(response => response.text())
.then(data => {
document.getElementById('footer-placeholder').innerHTML = data;
})
.catch(error => console.error('Error loading footer:', error));
}
// ページが読み込まれたときにフッターを読み込む
document.addEventListener('DOMContentLoaded', () => {
loadFooter();
});
// 折りたたみメニューの動作
const collapsibles = document.querySelectorAll('.collapsible');
collapsibles.forEach(collapsible => {
collapsible.addEventListener('click', function() {
this.classList.toggle('active');
const content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
});
// ドラッグオーバー時のスタイル変更
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
// ファイルがドロップされた時の処理
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files.length) {
const file = files[0];
if (file.type === 'text/csv') {
// ファイルをfileInputに反映させる
fileInput.files = e.dataTransfer.files;
// fileInputのchangeイベントをトリガーする
const changeEvent = new Event('change');
fileInput.dispatchEvent(changeEvent);
} else {
alert('CSVファイルをドロップしてください');
}
}
});
// ファイル選択ボタンから選択された時の処理
fileInput.addEventListener('change', async function() {
const reader = new FileReader();
reader.onload = async function(e) {
csvContent = e.target.result;
await generateStruct(); // 構造体生成関数を呼び出す
};
reader.readAsText(this.files[0]);
});
</script>
</body>
</html>