pywebexec 1.2.7__py3-none-any.whl → 1.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywebexec/static/css/style.css +8 -2
- pywebexec/static/js/commands.js +106 -74
- pywebexec/static/js/script.js +3 -1
- pywebexec/templates/index.html +1 -1
- pywebexec/version.py +2 -2
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/METADATA +1 -1
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/RECORD +11 -11
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/LICENSE +0 -0
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/WHEEL +0 -0
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/entry_points.txt +0 -0
- {pywebexec-1.2.7.dist-info → pywebexec-1.2.9.dist-info}/top_level.txt +0 -0
pywebexec/static/css/style.css
CHANGED
@@ -31,9 +31,15 @@ th {
|
|
31
31
|
width: 100%;
|
32
32
|
}
|
33
33
|
select { /* Safari bug */
|
34
|
+
-webkit-appearance: none;
|
35
|
+
-webkit-border-radius: none;
|
36
|
+
appearance: none;
|
37
|
+
outline: none;
|
34
38
|
font-size: 15px;
|
35
39
|
border: #aaa solid 1px;
|
36
40
|
border-radius: 5px;
|
41
|
+
padding: 0px 5px 5px 0px;
|
42
|
+
min-width: 150px;
|
37
43
|
}
|
38
44
|
.output {
|
39
45
|
white-space: pre-wrap;
|
@@ -178,7 +184,7 @@ form {
|
|
178
184
|
border: 1px solid #aaa;
|
179
185
|
border-radius: 5px;
|
180
186
|
padding: 0px 5px 0px 5px;
|
181
|
-
|
187
|
+
margin-top: 2px;
|
182
188
|
overflow-y: auto;
|
183
189
|
z-index: 1000;
|
184
190
|
}
|
@@ -188,7 +194,7 @@ form {
|
|
188
194
|
cursor: pointer;
|
189
195
|
}
|
190
196
|
|
191
|
-
.command-item:hover {
|
197
|
+
.command-item:hover, .command-item.highlighted {
|
192
198
|
background-color: #eee;
|
193
199
|
}
|
194
200
|
|
pywebexec/static/js/commands.js
CHANGED
@@ -1,43 +1,42 @@
|
|
1
1
|
// commands.js
|
2
2
|
let commandInput = document.getElementById('commandName');
|
3
3
|
let paramsInput = document.getElementById('params');
|
4
|
-
let
|
4
|
+
let commandListSelect = document.getElementById('commandList');
|
5
5
|
let showCommandListButton = document.getElementById('showCommandListButton');
|
6
|
+
let isHandlingKeydown = false;
|
6
7
|
|
7
8
|
function unfilterCommands() {
|
8
|
-
const
|
9
|
-
|
10
|
-
|
11
|
-
}
|
12
|
-
|
9
|
+
const options = commandListSelect.options;
|
10
|
+
for (let i = 0; i < options.length; i++) {
|
11
|
+
options[i].style.display = 'block';
|
12
|
+
}
|
13
|
+
commandListSelect.size = Math.min(20, commandListSelect.options.length);
|
13
14
|
}
|
14
15
|
|
15
16
|
function filterCommands() {
|
16
|
-
const value = commandInput.value;
|
17
|
-
const
|
18
|
-
let
|
19
|
-
|
20
|
-
if (
|
21
|
-
|
22
|
-
|
17
|
+
const value = commandInput.value.slice(0, commandInput.selectionStart);
|
18
|
+
const options = commandListSelect.options;
|
19
|
+
let nbVisibleItems = 0;
|
20
|
+
for (let i = 0; i < options.length; i++) {
|
21
|
+
if (options[i].text.startsWith(value)) {
|
22
|
+
options[i].style.display = 'block';
|
23
|
+
nbVisibleItems += 1;
|
23
24
|
} else {
|
24
|
-
|
25
|
+
options[i].style.display = 'none';
|
25
26
|
}
|
26
|
-
}
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
}
|
28
|
+
if (nbVisibleItems>1) {
|
29
|
+
commandListSelect.size = Math.min(20, nbVisibleItems);
|
30
|
+
commandListSelect.style.display = 'block';
|
30
31
|
} else {
|
31
|
-
|
32
|
+
commandListSelect.style.display = 'none';
|
32
33
|
}
|
33
|
-
adjustCommandListWidth(); // Adjust width after filtering commands
|
34
34
|
}
|
35
35
|
|
36
36
|
function setCommandListPosition() {
|
37
37
|
const rect = commandInput.getBoundingClientRect();
|
38
|
-
|
39
|
-
|
40
|
-
commandListDiv.style.minWidth = `${rect.width}px`;
|
38
|
+
commandListSelect.style.left = `${rect.left}px`;
|
39
|
+
commandListSelect.style.top = `${rect.bottom}px`;
|
41
40
|
}
|
42
41
|
|
43
42
|
function adjustInputWidth(input) {
|
@@ -45,20 +44,6 @@ function adjustInputWidth(input) {
|
|
45
44
|
input.style.width = `${input.scrollWidth}px`;
|
46
45
|
}
|
47
46
|
|
48
|
-
function adjustCommandListWidth() {
|
49
|
-
commandListDiv.style.width = 'auto'; // Reset width before recalculating
|
50
|
-
const items = Array.from(commandListDiv.getElementsByClassName('command-item'));
|
51
|
-
let maxWidth = 0;
|
52
|
-
items.forEach(item => {
|
53
|
-
if (item.style.display !== 'none') {
|
54
|
-
const itemWidth = item.scrollWidth;
|
55
|
-
if (itemWidth > maxWidth) {
|
56
|
-
maxWidth = itemWidth;
|
57
|
-
}
|
58
|
-
}
|
59
|
-
});
|
60
|
-
commandListDiv.style.width = `${maxWidth}px`;
|
61
|
-
}
|
62
47
|
|
63
48
|
paramsInput.addEventListener('input', () => adjustInputWidth(paramsInput));
|
64
49
|
commandInput.addEventListener('input', () => {
|
@@ -83,12 +68,12 @@ commandInput.addEventListener('input', (event) => {
|
|
83
68
|
commandInput.setSelectionRange(newValue.length, newValue.length);
|
84
69
|
}
|
85
70
|
const value = commandInput.value;
|
86
|
-
const
|
71
|
+
const options = commandListSelect.options;
|
87
72
|
if (value) {
|
88
|
-
const match =
|
73
|
+
const match = Array.from(options).find(option => option.text.startsWith(value));
|
89
74
|
if (match) {
|
90
|
-
commandInput.value = match.
|
91
|
-
commandInput.setSelectionRange(value.length, match.
|
75
|
+
commandInput.value = match.text;
|
76
|
+
commandInput.setSelectionRange(value.length, match.text.length);
|
92
77
|
} else {
|
93
78
|
commandInput.value = value.slice(0, -1);
|
94
79
|
}
|
@@ -97,47 +82,101 @@ commandInput.addEventListener('input', (event) => {
|
|
97
82
|
adjustInputWidth(commandInput); // Adjust width on input
|
98
83
|
});
|
99
84
|
|
100
|
-
commandInput.addEventListener('click', () => {
|
101
|
-
setCommandListPosition();
|
102
|
-
commandListDiv.style.display = 'block';
|
103
|
-
filterCommands();
|
104
|
-
});
|
105
|
-
|
106
85
|
commandInput.addEventListener('keydown', (event) => {
|
107
|
-
if (event.key === '
|
108
|
-
|
109
|
-
|
86
|
+
if (event.key === ' ' || event.key === 'ArrowRight') {
|
87
|
+
event.preventDefault();
|
88
|
+
paramsInput.focus();
|
89
|
+
paramsInput.setSelectionRange(0, paramsInput.value.length);
|
90
|
+
} else if (event.key === 'ArrowDown') {
|
91
|
+
/*setCommandListPosition();*/
|
110
92
|
unfilterCommands();
|
93
|
+
commandListSelect.style.display = 'block';
|
94
|
+
commandListSelect.focus();
|
95
|
+
commandListSelect.selectedIndex = 0;
|
96
|
+
event.preventDefault();
|
97
|
+
}
|
98
|
+
});
|
99
|
+
|
100
|
+
paramsInput.addEventListener('keydown', (event) => {
|
101
|
+
if (paramsInput.selectionStart > 0) return;
|
102
|
+
if (event.key === 'ArrowLeft') {
|
103
|
+
commandInput.focus();
|
104
|
+
commandInput.setSelectionRange(0, commandInput.value.length);
|
105
|
+
event.preventDefault();
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
if (event.key === 'Backspace') {
|
109
|
+
val = paramsInput.value
|
110
|
+
paramsInput.value = val.slice(0, paramsInput.selectionStart) + val.slice(paramsInput.selectionEnd)
|
111
|
+
commandInput.focus();
|
112
|
+
commandInput.setSelectionRange(0, commandInput.value.length);
|
113
|
+
event.preventDefault();
|
114
|
+
}
|
115
|
+
});
|
116
|
+
|
117
|
+
commandListSelect.addEventListener('keydown', (event) => {
|
118
|
+
if (event.key === 'Enter') {
|
119
|
+
event.preventDefault(); // Prevent form submission
|
120
|
+
const selectedOption = commandListSelect.options[commandListSelect.selectedIndex];
|
121
|
+
commandInput.value = selectedOption.text;
|
122
|
+
commandListSelect.style.display = 'none';
|
123
|
+
adjustInputWidth(commandInput);
|
124
|
+
paramsInput.focus();
|
125
|
+
return;
|
126
|
+
}
|
127
|
+
if (event.key === 'ArrowUp' && commandListSelect.selectedIndex == 0) {
|
128
|
+
commandInput.focus();
|
129
|
+
commandListSelect.style.display = 'none'
|
111
130
|
}
|
112
131
|
});
|
113
132
|
|
133
|
+
commandListSelect.addEventListener('click', (event) => {
|
134
|
+
event.preventDefault(); // Prevent form submission
|
135
|
+
const selectedOption = commandListSelect.options[commandListSelect.selectedIndex];
|
136
|
+
commandInput.value = selectedOption.text;
|
137
|
+
commandListSelect.style.display = 'none';
|
138
|
+
adjustInputWidth(commandInput);
|
139
|
+
paramsInput.focus();
|
140
|
+
});
|
141
|
+
|
142
|
+
|
143
|
+
commandInput.addEventListener('click', () => {
|
144
|
+
setCommandListPosition();
|
145
|
+
if (commandListSelect.style.display == 'none')
|
146
|
+
commandListSelect.style.display = 'block';
|
147
|
+
else
|
148
|
+
commandListSelect.style.display = 'none';
|
149
|
+
filterCommands();
|
150
|
+
});
|
151
|
+
|
114
152
|
commandInput.addEventListener('blur', (event) => {
|
115
|
-
if (event.relatedTarget === showCommandListButton) {
|
153
|
+
if (event.relatedTarget === showCommandListButton || event.relatedTarget === commandListSelect) {
|
116
154
|
event.preventDefault();
|
117
155
|
return;
|
118
156
|
}
|
119
|
-
|
120
|
-
commandListDiv.classList.remove('show');
|
157
|
+
commandListSelect.style.display = 'none';
|
121
158
|
adjustInputWidth(commandInput);
|
122
159
|
});
|
123
160
|
|
124
|
-
showCommandListButton.addEventListener('
|
161
|
+
showCommandListButton.addEventListener('click', (event) => {
|
125
162
|
event.preventDefault();
|
126
163
|
setCommandListPosition();
|
127
|
-
|
164
|
+
if (commandListSelect.style.display == 'none')
|
165
|
+
commandListSelect.style.display = 'block';
|
166
|
+
else
|
167
|
+
commandListSelect.style.display = 'none';
|
128
168
|
unfilterCommands();
|
129
169
|
});
|
130
170
|
|
131
171
|
window.addEventListener('click', (event) => {
|
132
|
-
if (!commandInput.contains(event.target) && !
|
133
|
-
|
134
|
-
commandListDiv.classList.remove('show');
|
135
|
-
adjustInputWidth(commandInput);
|
172
|
+
if (!commandInput.contains(event.target) && !commandListSelect.contains(event.target) && !showCommandListButton.contains(event.target)) {
|
173
|
+
commandListSelect.style.display = 'none';
|
136
174
|
}
|
137
175
|
});
|
138
176
|
|
139
177
|
window.addEventListener('keydown', (event) => {
|
140
|
-
if (document.activeElement
|
178
|
+
if ([commandInput, paramsInput, commandListSelect].includes(document.activeElement)) return;
|
179
|
+
if (event.code === `Key${event.key.toUpperCase()}`) {
|
141
180
|
commandInput.focus();
|
142
181
|
commandInput.dispatchEvent(new KeyboardEvent('keydown', event));
|
143
182
|
}
|
@@ -161,23 +200,16 @@ async function fetchExecutables() {
|
|
161
200
|
throw new Error('Failed to fetch command status');
|
162
201
|
}
|
163
202
|
const executables = await response.json();
|
164
|
-
|
203
|
+
commandListSelect.innerHTML = '';
|
165
204
|
executables.forEach(executable => {
|
166
|
-
const
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
commandInput.value = executable;
|
171
|
-
commandListDiv.style.display = 'none';
|
172
|
-
commandListDiv.classList.remove('show');
|
173
|
-
adjustInputWidth(commandInput);
|
174
|
-
paramsInput.focus();
|
175
|
-
});
|
176
|
-
commandListDiv.appendChild(div);
|
205
|
+
const option = document.createElement('option');
|
206
|
+
option.className = 'command-item';
|
207
|
+
option.text = executable;
|
208
|
+
commandListSelect.appendChild(option);
|
177
209
|
});
|
178
|
-
// Ensure the elements are rendered before measuring their widths
|
179
|
-
requestAnimationFrame(adjustCommandListWidth);
|
180
210
|
} catch (error) {
|
181
211
|
alert("Failed to fetch executables");
|
182
212
|
}
|
213
|
+
commandListSelect.size = Math.min(20, commandListSelect.options.length)
|
214
|
+
|
183
215
|
}
|
pywebexec/static/js/script.js
CHANGED
@@ -53,9 +53,11 @@ document.getElementById('launchForm').addEventListener('submit', async (event) =
|
|
53
53
|
throw new Error('Failed to launch command');
|
54
54
|
}
|
55
55
|
const data = await response.json();
|
56
|
-
await new Promise(r => setTimeout(r,
|
56
|
+
await new Promise(r => setTimeout(r, 300));
|
57
57
|
fetchCommands();
|
58
58
|
viewOutput(data.command_id);
|
59
|
+
commandInput.focus()
|
60
|
+
commandInput.setSelectionRange(0, commandInput.value.length)
|
59
61
|
} catch (error) {
|
60
62
|
console.log('Error running command:', error);
|
61
63
|
}
|
pywebexec/templates/index.html
CHANGED
@@ -19,11 +19,11 @@
|
|
19
19
|
<div id="showCommandListButton" class="show-command-list-button">
|
20
20
|
<span class="arrow">▼</span>
|
21
21
|
</div>
|
22
|
+
<select id="commandList" class="command-list" size="20"></select>
|
22
23
|
<input type="text" id="params" name="params" oninput="this.style.width = ((this.value.length + 1) * 8) + 'px';">
|
23
24
|
</div>
|
24
25
|
<button type="submit">Run</button>
|
25
26
|
</form>
|
26
|
-
<div id="commandList" class="command-list"></div>
|
27
27
|
<div class="table-container" id="tableContainer">
|
28
28
|
<table>
|
29
29
|
<thead>
|
pywebexec/version.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
|
2
2
|
pywebexec/pywebexec.py,sha256=LRKJ2KgklZsHawd97mSKodBpH5gLm3oMza30hcLcekc,22735
|
3
|
-
pywebexec/version.py,sha256=
|
4
|
-
pywebexec/static/css/style.css,sha256=
|
3
|
+
pywebexec/version.py,sha256=zd_kt_wsJmqzo58jY4byL9Q3ywofrUGUVUN0VUMtx8w,411
|
4
|
+
pywebexec/static/css/style.css,sha256=nuJodEFojt_kCLPqbDBQAaBtWcRZ6uLjfI52mSf3EJA,5302
|
5
5
|
pywebexec/static/css/xterm.css,sha256=gy8_LGA7Q61DUf8ElwFQzHqHMBQnbbEmpgZcbdgeSHI,5383
|
6
6
|
pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
|
7
7
|
pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
|
@@ -11,17 +11,17 @@ pywebexec/static/images/failed.svg,sha256=ADZ7IKrUyOXtqpivnz3VcH0-Wru-I5MOi3OJAk
|
|
11
11
|
pywebexec/static/images/favicon.svg,sha256=ti80IfuDZwIvQcmJxkOeUaB1iMsiyOPmQmVO-h0y1IU,1126
|
12
12
|
pywebexec/static/images/running.gif,sha256=iYuzQGkMxrakSIwt6gPieKCImGZoSAHmU5MUNZa7cpw,25696
|
13
13
|
pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
|
14
|
-
pywebexec/static/js/commands.js,sha256=
|
15
|
-
pywebexec/static/js/script.js,sha256
|
14
|
+
pywebexec/static/js/commands.js,sha256=4noexrtU-nTNV1L-qp6QpoGxokELKOdYDxGChYELb0w,7347
|
15
|
+
pywebexec/static/js/script.js,sha256=-MAcmmeRqH4b0xcbHZWiOkJaIa9C6boZ-QOHuXXbMpc,9775
|
16
16
|
pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
|
17
17
|
pywebexec/static/js/xterm/ansi_up.min.js,sha256=KNGV0vEr30hNqKQimTAvGVy-icD5A1JqMQTtvYtKR2Y,13203
|
18
18
|
pywebexec/static/js/xterm/xterm-addon-fit.js,sha256=Pprm9pZe4SadVXS5Bc8b9VnC9Ex4QlWwA0pxOH53Gck,1460
|
19
19
|
pywebexec/static/js/xterm/xterm.js,sha256=Bzka76jZwEhVt_LlS0e0qMw7ryGa1p5qfxFyeohphBo,283371
|
20
20
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
pywebexec/templates/index.html,sha256=
|
22
|
-
pywebexec-1.2.
|
23
|
-
pywebexec-1.2.
|
24
|
-
pywebexec-1.2.
|
25
|
-
pywebexec-1.2.
|
26
|
-
pywebexec-1.2.
|
27
|
-
pywebexec-1.2.
|
21
|
+
pywebexec/templates/index.html,sha256=M-9JUAR5vrk-19oF8CpxkWJvyWJkZIa71AI-1jpsMWE,2116
|
22
|
+
pywebexec-1.2.9.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
23
|
+
pywebexec-1.2.9.dist-info/METADATA,sha256=nvOnY9AFUD_7E79MhEIg_fhniAxF1HRB5CcuUt5I4jQ,6936
|
24
|
+
pywebexec-1.2.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
25
|
+
pywebexec-1.2.9.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
26
|
+
pywebexec-1.2.9.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
27
|
+
pywebexec-1.2.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|