Add button to CLI for loading commands from file (#1230)
Add button to CLI for loading commands from file10.7.0-preview
commit
0c6d6c1001
|
@ -2289,6 +2289,18 @@
|
||||||
"cliCopySuccessful": {
|
"cliCopySuccessful": {
|
||||||
"message": "Copied!"
|
"message": "Copied!"
|
||||||
},
|
},
|
||||||
|
"cliLoadFromFileBtn": {
|
||||||
|
"message": "Load from file"
|
||||||
|
},
|
||||||
|
"cliConfirmSnippetDialogTitle": {
|
||||||
|
"message": "Review loaded commands"
|
||||||
|
},
|
||||||
|
"cliConfirmSnippetNote": {
|
||||||
|
"message": "<strong>Note</strong>: You can review and edit commands before execution."
|
||||||
|
},
|
||||||
|
"cliConfirmSnippetBtn": {
|
||||||
|
"message": "Execute"
|
||||||
|
},
|
||||||
|
|
||||||
"loggingNote": {
|
"loggingNote": {
|
||||||
"message": "Data will be logged in this tab <span class=\"message-negative\">only</span>, leaving the tab will <span class=\"message-negative\">cancel</span> logging and application will return to its normal <strong>\"configurator\"</strong> state.<br /> You are free to select the global update period, data will be written into the log file every <strong>1</strong> second for performance reasons."
|
"message": "Data will be logged in this tab <span class=\"message-negative\">only</span>, leaving the tab will <span class=\"message-negative\">cancel</span> logging and application will return to its normal <strong>\"configurator\"</strong> state.<br /> You are free to select the global update period, data will be written into the log file every <strong>1</strong> second for performance reasons."
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-cli textarea {
|
.tab-cli textarea[name='commands'] {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
@ -53,6 +53,18 @@
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jBox-container textarea#preview {
|
||||||
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
width: 100%;
|
||||||
|
resize: none;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-family: monospace;
|
||||||
|
color: white;
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-cli #content-watermark {
|
.tab-cli #content-watermark {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,10 @@ TABS.cli = {
|
||||||
lineDelayMs: 15,
|
lineDelayMs: 15,
|
||||||
profileSwitchDelayMs: 100,
|
profileSwitchDelayMs: 100,
|
||||||
outputHistory: "",
|
outputHistory: "",
|
||||||
cliBuffer: ""
|
cliBuffer: "",
|
||||||
|
GUI: {
|
||||||
|
snippetPreviewWindow: null,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function removePromptHash(promptText) {
|
function removePromptHash(promptText) {
|
||||||
|
@ -95,6 +98,31 @@ TABS.cli.initialize = function (callback, nwGui) {
|
||||||
|
|
||||||
// nwGui variable is set in main.js
|
// nwGui variable is set in main.js
|
||||||
const clipboardCopySupport = !(nwGui == null && !navigator.clipboard);
|
const clipboardCopySupport = !(nwGui == null && !navigator.clipboard);
|
||||||
|
const enterKeyCode = 13;
|
||||||
|
|
||||||
|
function executeCommands(out_string) {
|
||||||
|
self.history.add(out_string.trim());
|
||||||
|
|
||||||
|
var outputArray = out_string.split("\n");
|
||||||
|
Promise.reduce(outputArray, function(delay, line, index) {
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
GUI.timeout_add('CLI_send_slowly', function () {
|
||||||
|
var processingDelay = self.lineDelayMs;
|
||||||
|
line = line.trim();
|
||||||
|
if (line.toLowerCase().startsWith('profile')) {
|
||||||
|
processingDelay = self.profileSwitchDelayMs;
|
||||||
|
}
|
||||||
|
const isLastCommand = outputArray.length === index + 1;
|
||||||
|
if (isLastCommand && self.cliBuffer) {
|
||||||
|
line = getCliCommand(line, self.cliBuffer);
|
||||||
|
}
|
||||||
|
self.sendLine(line, function () {
|
||||||
|
resolve(processingDelay);
|
||||||
|
});
|
||||||
|
}, delay)
|
||||||
|
})
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
$('#content').load("./tabs/cli.html", function () {
|
$('#content').load("./tabs/cli.html", function () {
|
||||||
// translate to user-selected language
|
// translate to user-selected language
|
||||||
|
@ -102,7 +130,7 @@ TABS.cli.initialize = function (callback, nwGui) {
|
||||||
|
|
||||||
CONFIGURATOR.cliActive = true;
|
CONFIGURATOR.cliActive = true;
|
||||||
|
|
||||||
var textarea = $('.tab-cli textarea');
|
var textarea = $('.tab-cli textarea[name="commands"]');
|
||||||
|
|
||||||
CliAutoComplete.initialize(textarea, self.sendLine.bind(self), writeToOutput);
|
CliAutoComplete.initialize(textarea, self.sendLine.bind(self), writeToOutput);
|
||||||
$(CliAutoComplete).on('build:start', function() {
|
$(CliAutoComplete).on('build:start', function() {
|
||||||
|
@ -173,6 +201,64 @@ TABS.cli.initialize = function (callback, nwGui) {
|
||||||
} else {
|
} else {
|
||||||
$('.tab-cli .copy').hide();
|
$('.tab-cli .copy').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.tab-cli .load').click(function() {
|
||||||
|
var accepts = [
|
||||||
|
{
|
||||||
|
description: 'Config files', extensions: ["txt", "config"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: 'All files',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(entry) {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
console.error(chrome.runtime.lastError.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
console.log('No file selected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let previewArea = $("#snippetpreviewcontent textarea#preview");
|
||||||
|
|
||||||
|
function executeSnippet() {
|
||||||
|
const commands = previewArea.val();
|
||||||
|
executeCommands(commands);
|
||||||
|
self.GUI.snippetPreviewWindow.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function previewCommands(result) {
|
||||||
|
if (!self.GUI.snippetPreviewWindow) {
|
||||||
|
self.GUI.snippetPreviewWindow = new jBox("Modal", {
|
||||||
|
id: "snippetPreviewWindow",
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
closeButton: 'title',
|
||||||
|
animation: false,
|
||||||
|
title: i18n.getMessage("cliConfirmSnippetDialogTitle"),
|
||||||
|
content: $('#snippetpreviewcontent'),
|
||||||
|
onCreated: () =>
|
||||||
|
$("#snippetpreviewcontent a.confirm").click(() => executeSnippet())
|
||||||
|
,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
previewArea.val(result);
|
||||||
|
self.GUI.snippetPreviewWindow.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.file((file) => {
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.onload =
|
||||||
|
() => previewCommands(reader.result);
|
||||||
|
reader.onerror = () => console.error(reader.error);
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Tab key detection must be on keydown,
|
// Tab key detection must be on keydown,
|
||||||
// `keypress`/`keyup` happens too late, as `textarea` will have already lost focus.
|
// `keypress`/`keyup` happens too late, as `textarea` will have already lost focus.
|
||||||
|
@ -200,7 +286,6 @@ TABS.cli.initialize = function (callback, nwGui) {
|
||||||
});
|
});
|
||||||
|
|
||||||
textarea.keypress(function (event) {
|
textarea.keypress(function (event) {
|
||||||
const enterKeyCode = 13;
|
|
||||||
if (event.which == enterKeyCode) {
|
if (event.which == enterKeyCode) {
|
||||||
event.preventDefault(); // prevent the adding of new line
|
event.preventDefault(); // prevent the adding of new line
|
||||||
|
|
||||||
|
@ -209,28 +294,7 @@ TABS.cli.initialize = function (callback, nwGui) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out_string = textarea.val();
|
var out_string = textarea.val();
|
||||||
self.history.add(out_string.trim());
|
executeCommands(out_string);
|
||||||
|
|
||||||
var outputArray = out_string.split("\n");
|
|
||||||
Promise.reduce(outputArray, function(delay, line, index) {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
GUI.timeout_add('CLI_send_slowly', function () {
|
|
||||||
var processingDelay = self.lineDelayMs;
|
|
||||||
line = line.trim();
|
|
||||||
if (line.toLowerCase().startsWith('profile')) {
|
|
||||||
processingDelay = self.profileSwitchDelayMs;
|
|
||||||
}
|
|
||||||
const isLastCommand = outputArray.length === index + 1;
|
|
||||||
if (isLastCommand && self.cliBuffer) {
|
|
||||||
line = getCliCommand(line, self.cliBuffer);
|
|
||||||
}
|
|
||||||
self.sendLine(line, function () {
|
|
||||||
resolve(processingDelay);
|
|
||||||
});
|
|
||||||
}, delay)
|
|
||||||
})
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
textarea.val('');
|
textarea.val('');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -433,6 +497,10 @@ TABS.cli.send = function (line, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
TABS.cli.cleanup = function (callback) {
|
TABS.cli.cleanup = function (callback) {
|
||||||
|
if (TABS.cli.GUI.snippetPreviewWindow) {
|
||||||
|
TABS.cli.GUI.snippetPreviewWindow.destroy();
|
||||||
|
TABS.cli.GUI.snippetPreviewWindow = null;
|
||||||
|
}
|
||||||
if (!(CONFIGURATOR.connectionValid && CONFIGURATOR.cliValid && CONFIGURATOR.cliActive)) {
|
if (!(CONFIGURATOR.connectionValid && CONFIGURATOR.cliValid && CONFIGURATOR.cliActive)) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
|
|
|
@ -16,8 +16,22 @@
|
||||||
<div class="content_toolbar">
|
<div class="content_toolbar">
|
||||||
<div class="btn save_btn pull-right">
|
<div class="btn save_btn pull-right">
|
||||||
<a class="save" href="#" i18n="cliSaveToFileBtn"></a>
|
<a class="save" href="#" i18n="cliSaveToFileBtn"></a>
|
||||||
|
<a class="load" href="#" i18n="cliLoadFromFileBtn"></a>
|
||||||
<a class="clear" href="#" i18n="cliClearOutputHistoryBtn"></a>
|
<a class="clear" href="#" i18n="cliClearOutputHistoryBtn"></a>
|
||||||
<a class="copy" href="#" i18n="cliCopyToClipboardBtn"></a>
|
<a class="copy" href="#" i18n="cliCopyToClipboardBtn"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Snippet preview dialog -->
|
||||||
|
<div id="snippetpreviewcontent" style="display: none">
|
||||||
|
<div class="note">
|
||||||
|
<div class="note_spacer">
|
||||||
|
<p i18n="cliConfirmSnippetNote"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<textarea id="preview" cols="120" rows="20"></textarea>
|
||||||
|
<div class="default_btn">
|
||||||
|
<a class="confirm" href="#" i18n="cliConfirmSnippetBtn"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -14,7 +14,7 @@ describe('TABS.cli', () => {
|
||||||
describe('output', () => {
|
describe('output', () => {
|
||||||
const cliTab = $('<div>').addClass('tab-cli');
|
const cliTab = $('<div>').addClass('tab-cli');
|
||||||
const cliOutput = $('<div>').addClass('wrapper')
|
const cliOutput = $('<div>').addClass('wrapper')
|
||||||
const cliPrompt = $('<textarea>');
|
const cliPrompt = $('<textarea name="commands">');
|
||||||
|
|
||||||
cliTab.append($('<div>').addClass('window').append(cliOutput));
|
cliTab.append($('<div>').addClass('window').append(cliOutput));
|
||||||
cliTab.append(cliPrompt);
|
cliTab.append(cliPrompt);
|
||||||
|
@ -101,7 +101,7 @@ describe('TABS.cli', () => {
|
||||||
describe('input', () => {
|
describe('input', () => {
|
||||||
const content = $('<div>').attr('id', 'content');
|
const content = $('<div>').attr('id', 'content');
|
||||||
const cliTab = $('<div>').addClass('tab-cli');
|
const cliTab = $('<div>').addClass('tab-cli');
|
||||||
const cliPrompt = $('<textarea>');
|
const cliPrompt = $('<textarea name="commands">');
|
||||||
cliTab.append(cliPrompt);
|
cliTab.append(cliPrompt);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
Loading…
Reference in New Issue