Add button to CLI for loading commands from file (#1230)

Add button to CLI for loading commands from file
10.7.0-preview
Michael Keller 2019-04-30 23:02:57 +12:00 committed by GitHub
commit 0c6d6c1001
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 135 additions and 29 deletions

View File

@ -2289,6 +2289,18 @@
"cliCopySuccessful": {
"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": {
"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."

View File

@ -42,7 +42,7 @@
float: left;
}
.tab-cli textarea {
.tab-cli textarea[name='commands'] {
-webkit-box-sizing: border-box;
width: 100%;
margin-top: 8px;
@ -53,6 +53,18 @@
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 {
z-index: 0;
}

View File

@ -4,7 +4,10 @@ TABS.cli = {
lineDelayMs: 15,
profileSwitchDelayMs: 100,
outputHistory: "",
cliBuffer: ""
cliBuffer: "",
GUI: {
snippetPreviewWindow: null,
},
};
function removePromptHash(promptText) {
@ -95,6 +98,31 @@ TABS.cli.initialize = function (callback, nwGui) {
// nwGui variable is set in main.js
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 () {
// translate to user-selected language
@ -102,7 +130,7 @@ TABS.cli.initialize = function (callback, nwGui) {
CONFIGURATOR.cliActive = true;
var textarea = $('.tab-cli textarea');
var textarea = $('.tab-cli textarea[name="commands"]');
CliAutoComplete.initialize(textarea, self.sendLine.bind(self), writeToOutput);
$(CliAutoComplete).on('build:start', function() {
@ -173,6 +201,64 @@ TABS.cli.initialize = function (callback, nwGui) {
} else {
$('.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,
// `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) {
const enterKeyCode = 13;
if (event.which == enterKeyCode) {
event.preventDefault(); // prevent the adding of new line
@ -209,28 +294,7 @@ TABS.cli.initialize = function (callback, nwGui) {
}
var out_string = textarea.val();
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);
executeCommands(out_string);
textarea.val('');
}
});
@ -433,6 +497,10 @@ TABS.cli.send = function (line, 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 (callback) {
callback();

View File

@ -16,8 +16,22 @@
<div class="content_toolbar">
<div class="btn save_btn pull-right">
<a class="save" href="#" i18n="cliSaveToFileBtn"></a>
<a class="load" href="#" i18n="cliLoadFromFileBtn"></a>
<a class="clear" href="#" i18n="cliClearOutputHistoryBtn"></a>
<a class="copy" href="#" i18n="cliCopyToClipboardBtn"></a>
</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>

View File

@ -14,7 +14,7 @@ describe('TABS.cli', () => {
describe('output', () => {
const cliTab = $('<div>').addClass('tab-cli');
const cliOutput = $('<div>').addClass('wrapper')
const cliPrompt = $('<textarea>');
const cliPrompt = $('<textarea name="commands">');
cliTab.append($('<div>').addClass('window').append(cliOutput));
cliTab.append(cliPrompt);
@ -101,7 +101,7 @@ describe('TABS.cli', () => {
describe('input', () => {
const content = $('<div>').attr('id', 'content');
const cliTab = $('<div>').addClass('tab-cli');
const cliPrompt = $('<textarea>');
const cliPrompt = $('<textarea name="commands">');
cliTab.append(cliPrompt);
beforeEach(() => {