Initial commit

This commit is contained in:
Ward Truyen
2024-09-21 16:23:13 +02:00
commit 7246af80e1
24 changed files with 2596 additions and 0 deletions

103
src/termext/ext-cookies.js Normal file
View File

@@ -0,0 +1,103 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: Cookie data managing
*/
if (WTerminal) {
const initTerminalCookieCommands = function() {
//getcookie
WTerminal.terminalAddCommand("getcookie", (term, argLine) => {
function getCookie(name, defaultValue = undefined) {
if (name === null || name === undefined || typeof name != "string" || name == '') {
console.log('error: cookie needs a name');
return;
}
let pair = document.cookie.split(/; */).find((row) => row.startsWith(name + '='))
//console.log("cookie pair: ", pair);
if (pair === undefined)
return defaultValue;
else
return pair.split('=')[1];
}
return getCookie(...WTerminal.splitToArguments(argLine));
});
//setcookie
WTerminal.terminalAddCommand("setcookie", (term, argLine) => {
function setCookie(name, value = 1, days = 7) {
let date = new Date();
date.setDate(date.getDate() + days); // add x days to date
document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; SameSite=strict; Secure";
}
return setCookie(...WTerminal.splitToArguments(argLine));
});
//removecookies
WTerminal.terminalAddCommand("removecookies", function(term) {
function removeCookie(name) {
document.cookie = name + "=0; max-age=-1" + "; SameSite=strict; Secure";
}
if (document.cookie == '') {
term.printError("No cookies found.");
return;
}
const cookies = document.cookie.split(/; */);
term.printLn("Cookies found: " + cookies.length);
cookies.forEach(c => {
const name = c.split('=')[0];
term.printLn("removing: " + name);
removeCookie(name);
});
});
//cookies
WTerminal.terminalAddCommand("cookies",
function(term, argLine) {
if (document.cookie === '') {
if (!argLine.includes("-s")) term.printError("No cookies found.")
} else {
term.printList(document.cookie.split(/; */), false);
}
},
function(term) {
term.printLn("Usage:");
term.printLn(" cookies //Prints all cookies.");
term.printLn(" cookies -s //(silent)Prints only cookies, no error.");
});
//doCookiesWork
WTerminal.terminalAddCommand("docookieswork", (term) => {
function getCookie(name, defaultValue = undefined) {
if (name === null || name === undefined || typeof name != "string" || name == '') {
console.log('error: cookie needs a name');
return;
}
let pair = document.cookie.split(/; */).find((row) => row.startsWith(name + '='))
//console.log("cookie pair: ", pair);
if (pair === undefined)
return defaultValue;
else
return pair.split('=')[1];
}
function setCookie(name, value = 1, days = 7) {
let date = new Date();
date.setDate(date.getDate() + days); // add x days to date
document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; SameSite=strict; Secure";
}
function removeCookie(name) {
document.cookie = name + "=0; max-age=-1" + "; SameSite=strict; Secure";
}
const name = "testCookie";
setCookie(name);
let itWorks = getCookie(name) !== undefined;
if (itWorks) {
removeCookie(name);
}
term.printLn(itWorks);
return itWorks;
});
}
//init
if (document.body) {
initTerminalCookieCommands();
} else {
window.addEventListener("load", initTerminalCookieCommands);
}
}

32
src/termext/ext-eval.js Normal file
View File

@@ -0,0 +1,32 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the eval command to the terminal.
*/
{
const evalHelp = function(term) {
term.printLn("Uses the function eval(string) on the argLine");
}
const evalRun = function(term, argLine) {
try {
const result = eval(argLine);
term.printVar(result, '`' + argLine + '`');
return result;
} catch (error) {
term.printError(`Eval error: \`${argLine}\` -> ${error.message}`);
}
};
const initTerminalEvalCommand = function() {
if (WTerminal === undefined) { //is WTerminal not available?
console.error("WTerminal is missing!");
return;
}
WTerminal.terminalAddCommand("eval", evalRun, evalHelp);
};
//init
if (document.body) {
initTerminalEvalCommand();
} else {
window.addEventListener("load", initTerminalEvalCommand);
}
}

View File

@@ -0,0 +1,42 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the test command to the terminal.
* current test is to get local variables
*/
{
const help = function(term) {
term.printLn("Runs a test (nothing).");
}
const run = function(term) {
term.printLn("Feature test warning: Under construction, can have unexpected results, errors and crashes.");
// todo: add test ... like throw errors and stuff
// throw {name : "NotImplementedError", message : "too lazy to implement"};
// throw new Error("too lazy to implement", "some name perhaps?");
// class TerminalError extends Error{
// constructor(msg, name="TerminalError"){
// super(msg);
// this.name = name;
// }
// }
// throw new TerminalError("my message", "MyName");
let num = 1;
num.toPrecision(500);
};
const addExtention = function() {
if (WTerminal === undefined) { //is WTerminal not available?
console.error("AddExtention Error: WTerminal is missing!");
return;
}
WTerminal.terminalAddCommand("featuretest", run, help);
//add alias
WTerminal.terminalAddAlias("ft", "featuretest");
};
//init
if (document.body) {
addExtention();
} else {
window.addEventListener("load", addExtention);
}
}

96
src/termext/ext-passw.js Normal file
View File

@@ -0,0 +1,96 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds a password generatiing- and testing function
*/
{
const generatePasswordHelp = function(term) {
term.printLn("Generates a new password and prints it out. But also copies it for you.");
}
const generatePassword = function(term, argLine) {
const UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
const NUMBERS = "1234567890";
const SPECIAL_CHARACTERS = "!@#$%^&*()_-+=,./<>\\|[]{}";
const ALL_CHARACTERS = UPPERCASE_LETTERS + LOWERCASE_LETTERS + NUMBERS + SPECIAL_CHARACTERS;
let passwd = "";
let length = 15;
for (let i = 0; i < length; i++) {
passwd += ALL_CHARACTERS.charAt(Math.floor(Math.random() * ALL_CHARACTERS.length));
}
const el = document.createElement('span');
el.innerText = passwd;
// el.style.fontSize = 'x-large';
el.style.paddingLeft = '1em';
term.printLn("Generated password(length=" + length + "):", el);
navigator.clipboard.writeText(passwd);
};
const isPasswordSafeHelp = function(term) {
term.printLn("Checks if a password is posted as breached by pwnedpasswords.com");
};
const isPasswordSafe = function(term, argLine) {
const sha1 = function(string) {
const buffer = new TextEncoder("utf-8").encode(string);
return crypto.subtle.digest("SHA-1", buffer).then(function(buffer) {
// Get the hex code
let hexCodes = [];
const padding = '00000000'
const view = new DataView(buffer);
for (let i = 0; i < view.byteLength; i += 4) {
// Using getUint32 reduces the number of iterations needed (we process 4 bytes each time)
const value = view.getUint32(i)
// toString(16) will give the hex representation of the number without padding
const stringValue = value.toString(16)
// We use concatenation and slice for padding
const paddedValue = (padding + stringValue).slice(-padding.length)
hexCodes.push(paddedValue);
}
// Join all the hex strings into one
return hexCodes.join("");
});
};
const password = argLine;
term.printLn("Checking password, please wait...");
sha1(password).then((hash) => {
fetch("https://api.pwnedpasswords.com/range/" + hash.substr(0, 5)).then((response) => response.text()).then((response) => {
const respLines = response.split('\n');
const hashSub = hash.slice(5).toUpperCase();
let isSafe = true;
// console.log('hash: ' + hashSub);
for (let i in respLines) {
// console.log(i+': '+respLines[i])
if (respLines[i].substring(0, hashSub.length) == hashSub) {
isSafe = false;
break;
}
}
if (isSafe) {
term.printLn("Password is safe.");
} else {
term.printLn("Password has been breached.");
}
}).catch((err) => {
outputSafe.innerText = "Could not check if password is safe: " + err;
});
});
};
const initTerminalPasswCommands = function() {
if (WTerminal === undefined) { //is WTerminal not available?
console.error("WTerminal is missing!");
return;
}
WTerminal.terminalAddCommand("generatepassword", generatePassword, generatePasswordHelp);
WTerminal.terminalAddCommand("ispasswordsafe", isPasswordSafe, isPasswordSafeHelp);
};
//init
if (document.body) {
initTerminalPasswCommands();
} else {
window.addEventListener("load", initTerminalPasswCommands);
}
}

164
src/termext/ext-popvar.js Normal file
View File

@@ -0,0 +1,164 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the test command to the terminal.
* current test is to get local variables
*/
{// this code block hides the variables below from other scripts.
const runPopVar = function(term, argLine) {
const PAUSE_SYMBOL = "&#9724;";
const INTERVAL_TIME = "1000"; // 1000 == 1second
class PopUpWindow {
static popupCounter = 0;
constructor(variableName, term) {
this.variableName = variableName;
this.printVar = term.printVar;
this._getObjType = term._getObjType;
this._printObject = term._printObject;
this.printLn = term.printLn;
this.options = {};
let o = this.options;
let to = term.options;
o.printToConsoleLog = false;
o.tpo_unknownObjectPrint = to.tpo_unknownObjectPrint;
o.tpo_objectPrefix = to.tpo_objectPrefix;
o.tpo_specialPrefix = to.tpo_specialPrefix;
o.tpo_maxDepth = to.tpo_maxDepth;
o.tpo_innerMaxLength = to.tpo_innerMaxLength;
this.createPopup();
this.printVariable();
this.intervalId = setInterval(() => this.printVariable(), INTERVAL_TIME);
}
createPopup() {
const t = 2 + PopUpWindow.popupCounter++;
let containerStyle = 'border: 1px solid black; z-index: 9990; position: absolute; background: #ffffffa0; border-radius: 2px; backdrop-filter: blur(3px); box-shadow: 3px 3px 3px #00000066;';
containerStyle += ` top: ${t}em; left: ${t}em;`;
this.container = WTerminal.createElement('div', { style: containerStyle, title: this.variableName });
const outputStyle = 'margin: 2px; font-family: Monospace, Incosolata, Courier; font-size: 12px; line-height: 1.05;';// overflow-y: scroll; max-height: ' + (window.innerHeight-80) +'px;';
this.outputEl = WTerminal.createElement('pre', { style: outputStyle });
this.btnPauseContinue = WTerminal.createElement('button', { title: "pause" });
this.btnPauseContinue.innerHTML = PAUSE_SYMBOL;
this.btnPauseContinue.addEventListener("click", () => this.onPausePlay());
let btnRefresh = WTerminal.createElement('button', { title: "refresh" });
btnRefresh.innerHTML = '&#8635;';
btnRefresh.addEventListener("click", () => this.printVariable());
let btnClose = WTerminal.createElement('button', { title: 'close' });
btnClose.addEventListener("click", () => this.closePopup());
btnClose.innerHTML = "&#10006;";
let headerDiv = WTerminal.createElement('div', { style: "border-bottom: 1px solid black; padding: 2px; background: #00000060" });
headerDiv.appendChild(btnRefresh);
headerDiv.appendChild(this.btnPauseContinue);
headerDiv.appendChild(document.createTextNode(" Popvar " + PopUpWindow.popupCounter));
let spanForClose = WTerminal.createElement('span', { style: "float: right;" }, btnClose);
headerDiv.appendChild(spanForClose);
this.container.appendChild(headerDiv);
this.container.appendChild(this.outputEl);
document.body.appendChild(this.container);
headerDiv.onmousedown = (e) => this.startDrag(e);
}
onPausePlay() {
if (this.intervalId === 0) {
this.intervalId = setInterval(() => this.printVariable(), INTERVAL_TIME);
this.printVariable();
this.btnPauseContinue.innerHTML = PAUSE_SYMBOL;
this.btnPauseContinue.title = "pause";
} else {
clearInterval(this.intervalId);
this.intervalId = 0;
this.btnPauseContinue.innerHTML = "&#9658;";
this.btnPauseContinue.title = "play";
}
}
printVariable() {
const oldOutput = this.outputEl;
const outputStyle = 'margin: 2px; font-family: Monospace, Incosolata, Courier; font-size: 12px; line-height: 1.05;';// overflow-y: scroll; max-height: ' + (window.innerHeight-80) +'px;';
this.outputEl = WTerminal.createElement('pre', { style: outputStyle });
this.printVar(WTerminal.getGlobalVariable(this.variableName), this.variableName);
oldOutput.replaceWith(this.outputEl);
}
closePopup() {
document.body.removeChild(this.container);
}
startDrag(e) {
if (e.button !== 0) return;
e.preventDefault();
this.pos3 = e.clientX;
this.pos4 = e.clientY;
document.onmouseup = () => this.endDrag();
document.onmousemove = (e) => this.dragPopup(e);
}
dragPopup(e) {
// e = e || window.event;
e.preventDefault();
this.pos1 = this.pos3 - e.clientX;
this.pos2 = this.pos4 - e.clientY;
this.pos3 = e.clientX;
this.pos4 = e.clientY;
this.container.style.top = (this.container.offsetTop - this.pos2) + "px";
this.container.style.left = (this.container.offsetLeft - this.pos1) + "px";
}
endDrag() {
document.onmouseup = null;
document.onmousemove = null;
}
};//class PopUpWindow
if (globalThis === undefined) {
term.printError("Popvar error: Missing globalThis");
} else if (argLine == '') {
term.printError("Popvar error: No name");
} else {
// return new PopUpWindow(argLine, term);
new PopUpWindow(argLine, term);
}
}// runPopvar
const initTerminalVariableCommands = function() {
const ext = {
popvar: {
run: runPopVar,
help: function(term) {
term.printLn("Creates a popup window with (refreshable) the given variable contents.");
term.printBold("Usage:");
term.printLn("popvar VARIABLE_NAME //shows VARIABLE_NAME contents in a popup");
term.printBold("Samples:");
term.printLn("popvar terminal //Shows the terminal variable contents in a popup");
}
},
};
const aliases = {
pop: "popvar",
pt: "popvar terminal",
};
if (WTerminal === undefined) { //is WTerminal not available?
console.error("WTerminal is missing!");
return;
}
//add commands in ext
for (let c of Object.keys(ext)) {
WTerminal.terminalAddCommand(c, ext[c].run, ext[c].help);
}
//add aliases
for (let c of Object.keys(aliases)) {
WTerminal.terminalAddAlias(c, aliases[c]);
}
};
//init
if (document.body) {
initTerminalVariableCommands();
} else {
window.addEventListener("load", initTerminalVariableCommands);
}
}

View File

@@ -0,0 +1,40 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the test command to the terminal.
* current test is to get local variables
*/
{// this code block hides the variables below from other scripts.
const initTerminalStressTestCommand = function() {
const help = function(term) {
term.printLn("Runs a stress test on the terminal.");
};
const run = function(term, argLine) {
const testArgLine = function(str) {
term.printVar(WTerminal.splitToArguments(str), '`' + argLine + '`.<b>splitToArguments()</b>');
};
if (argLine != '') testArgLine(argLine);
term.terminalCommand("? && alias && const && option && date && time && uptime && starttime && echo OK", true);
term.terminalCommand("? help && help alias && ? const && ? option && ? date && ? time && ? uptime", true);
term.terminalCommand("thisterminal && gg", true);
term.terminalCommand('gdb && result .2 && result .children.0 && result .innerHTML', true);
term.terminalCommand('eval 10000+4*(1+4*10) + Math.PI', true);
term.terminalCommand('dovar alert "finished stresstest"', true);
// term.terminalCommand('dovar document.getElementById ' + TERMINAL_OUTPUT_ID + ' && result .innerHTML', true);
return term.lastResult;
};
//add command
if (WTerminal === undefined) {
console.error("WTerminal is missing!");
return;
}
WTerminal.terminalAddCommand("stresstest", run, help);
};
//init
if (document.body) {
initTerminalStressTestCommand();
} else {
window.addEventListener("load", initTerminalStressTestCommand);
}
}

View File

@@ -0,0 +1,45 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the test command to the terminal.
* current test is to get local variables
*/
{
const addExtention = function() {
const help = function(term) {
term.printLn("Installs a logger at setTimeout and setInterval.");
}
const run = function(term) {
//capture setTimeout
const oldSetTimeout = setTimeout;
setTimeout = function() {
const e = new Error('Just for stack trace');
const result = oldSetTimeout.apply(this, arguments);
if (term) term.printLn(`New timeout ${result} registered.\n from: ${e.stack}`);
else console.log(`New timeout ${result} registered from: ${e.stack}`);
return result;
};
//capture setInterval
const oldSetInterval = setInterval;
setInterval = function() {
const e = new Error('Just for stack trace');
const result = oldSetInterval.apply(this, arguments);
if (term) term.printLn(`New interval ${result} registered.\n from: ${e.stack}`);
else console.log(`New interval ${result} registered from: ${e.stack}`);
return result;
}
term.printLn("activated");
}
if (WTerminal === undefined) { //is WTerminal not available?
console.error("WTerminal is missing!");
return;
}
WTerminal.terminalAddCommand("timerdebug", run, help);
};
//init
if (document.body) {
addExtention();
} else {
window.addEventListener("load", addExtention);
}
}

View File

@@ -0,0 +1,88 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This allows the terminal to transfer from add-on to page level, by using the extemtopm command 'transfer'.
* THIS SCRIPT ONLY WORKS FOR A BROWSER-ADDON/EXTENTION!
*/
{// this code block hides the variables below from other scripts.
const TRANSFER_COMMAND_NAME = "transfer";
const TRANSFER_SCRIPT_ID = "terminal-transfer-script";
const initTerminalTransferCommand = function() {
const help = function(term) {
term.printLn("Transfers all the terminal functions and variables, from the addon-scope to the document/page-scope");
}
const run = function(term) {
term.printLn("Transfer warning: Expect difficulties debugging errors.");
term.print("When, after transfer, the new (transfered) terminal does not open check the console,");
term.printLn("if the error points to document.body.appendChild(scriptNode); then the generated script has a bug."); //generated script == tempScript
try {
//addon-terminal todo: try adding terminalPrint functions to the page!
let scriptNode = document.getElementById(TRANSFER_SCRIPT_ID);
if (scriptNode === null) {
scriptNode = document.createElement("script");
scriptNode.id = TRANSFER_SCRIPT_ID;
scriptNode.type = "text/javascript";
} else {
while (scriptNode.firstChild) {
scriptNode.removeChild(scriptNode.lastChild);
}
}
//create script
let tempScript = `{
console.log("loading ${TRANSFER_SCRIPT_ID}");
`;
tempScript += `
${WTerminal};
`;
tempScript += `
//Relaunch
const relaunchWTerminal = function(){
try{
let terminal = new WTerminal("dropdown", null, null);
terminal.terminalOpen();
terminal.printLn("This Terminal was transfered.");
terminal.commandListExtension = {`;
for (let el in term.commandListExtension) {
if (el == "transfer") continue;
tempScript += `${el}: { run: ${term.commandListExtension[el].run}, help: ${term.commandListExtension[el].help} },`
}
tempScript += `
};
terminal.aliasExtensionList = ${JSON.stringify(term.aliasExtensionList)};
terminal.printLn("Extentions transfered.");
terminal.printLn("Press '"+terminal.options.keyOpen + ((!terminal.options.keyOpenCtrl)?'" + CTRL':'"')+" to open the other terminal.");
} catch(e){
console.log("failed to transfer terminal");
console.error(e);
}
};
relaunchWTerminal();
}`;
/* tempScript = `console.log("ik werk wel!");`;*/
scriptNode.appendChild(document.createTextNode(tempScript));
// scriptNode.innerHTML = tempScript;
if (document.getElementById(TRANSFER_SCRIPT_ID) === null) {
document.body.appendChild(scriptNode);
}
term.printLn("Transfer done");
term.options.keyOpenCtrl = !term.options.keyOpenCtrl;
term.printLn(`Press '${term.options.keyOpen + ((!term.options.keyOpenCtrl) ? '" + CTRL' : '"')} to open the other terminal.`);
term.terminalClose();
} catch (e) {
term.printVar("Transfer error: ", e);
return e;
}
};
WTerminal.terminalAddCommand(TRANSFER_COMMAND_NAME, run, help);
};
if (document.body) {
initTerminalTransferCommand();
} else {
window.addEventListener("load", initTerminalTransferCommand);
}
}

View File

@@ -0,0 +1,348 @@
/* Author: Ward Truyen
* Version: 1.0.0
* About: This adds the test command to the terminal.
* current test is to get local variables
*/
{// this code block hides the variables below from other scripts.
const initTerminalVariableCommands = function() {
const ext =
{
dovar: {
run: function(term, argLine) {
function _doFunction(gVar, functionKey, args) {
if (typeof gVar === "object" && typeof gVar[functionKey] === "function") {
// term.printVar(args, "do args");
return gVar[functionKey](...args);
} else {
term.printError("Do error: " + functionKey + " is not a function");
}
};
/* To run a function of a Class (like document.getElementById(..))
* We need the parent- /class-object from witch we call it from, to prevent errors (illegal acces)
* todo: ? --> use apply https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
*/
if (globalThis === undefined) {
term.printError("Do error: Missing globalThis");
} else if (argLine == '') {
term.printError("Do error: No name");
} else {
let args = WTerminal.splitToArguments(argLine);
const verbal = args.includes("-v");
if (verbal) {
args = args.filter(e => e !== '-v');
}
const gName = args.shift(); //full global function name
args.forEach(e => e = WTerminal.stringToValue(e));
let pName = gName.split('.'); //last object's parent name
let result;
if (pName.length == 1) {
result = _doFunction(globalThis, gName, args)
} else {
const lastName = pName.pop(); //last object name
result = _doFunction(WTerminal.getGlobalVariable(pName.join('.')), lastName, args);
}
if (verbal) term.printVar(result, gName + "(" + args.join(' ') + ")");
return result;
}
},
help: function(term) {
term.printLn("Runs given global function with arguments, and returns result.");
term.printBold("Usage:");
term.printLn("dovar FUNCTION_NAME [ArgumentS] //Runs function FUNCTION_NAME with optional ArgumentS");
term.printLn("dovar -v FUNCTION_NAME [ArgumentS] //Same as above but prints result too.");
term.printBold("Samples:");
term.printLn("dovar window.open https://developer.mozilla.org //Runs function window.open() with the url as argument");
term.printLn("dovar -v document.getElementById terminal-up //Runs function document.getElementById with terminal-up as argument")
term.printLn("dovar document.body.remove //Warning: removes all page content");
}
},
getvar: {
run: function(term, argLine) {
if (globalThis === undefined) {
term.printError("Getvar error: Missing globalThis");
} else if (argLine == '') {
term.printError("Getvar error: Missing argument: VARIABLE_NAME");
} else {
let result = {};
const args = WTerminal.splitToArguments(argLine);
for (const gName of args) {
result[gName] = WTerminal.getGlobalVariable(gName);
}
const keys = Object.keys(result);
if (keys.length == 1) {
return result[keys[0]];
} else {
return result;
}
}
},
help: function(term) {
term.printLn("Gets a global variable and returns it.");
term.printLn("The returned result will be found in terminal.lastResult")
term.printBold("Usage:");
term.printLn("getvar VARIABLE_NAME");
term.printBold("Samples:");
term.printLn("getvar terminal //Returns terminal");
term.printLn("getvar terminal.version //Returns terminal.version");
term.printLn("getvar var1 var2 var3 //Returns an object with var1 var2 and var3 keys and their global found value.");
term.printLn("getvar document //Returns global document object.");
term.printLn("getvar document.body.children //Returns a list of the children in the body.");
term.printLn("getvar document.head.children //Returns a list of the children in the head.");
}
},
globals: {
run: function(term) {
if (globalThis !== undefined) {
term.printVar(globalThis, "globalThis");
} else if (self !== undefined) {
term.printVar(self, "self");
} else if (global !== undefined) {
term.printVar(global, "global");
} else {
term.printError("Globals error: No globals!?");
}
if (document !== undefined && globalThis.document !== document) term.printVar(document, "document");
},
help: function(term) {
term.printLn("Prints all global variables.");
}
},
logvar: {
run: function(term, argLine) {
if (globalThis === undefined) {
term.printError("LogVar error: Missing globalThis");
} else if (argLine == '') {
term.printError("LogVar error: Missing argument: VARIABLE_NAME");
} else {
let result = {};
let args = WTerminal.splitToArguments(argLine);
const returnResult = args.includes("-r");
if (returnResult) {
args = args.filter(e => e !== '-r');
}
for (const gName of args) {
result[gName] = WTerminal.getGlobalVariable(gName);
}
if (Object.keys(result).length == 1) {
result = result[Object.keys(result)[0]];
}
// term.printVar(result);
console.log(result);
if (returnResult) return result;
}
},
help: function(term) {
term.printLn("Like printvar but Logs variable(s) to console.");
}
},
printvar: {
run: function(term, argLine) {
if (globalThis === undefined) {
term.printError("PrintVar error: Missing globalThis");
} else if (argLine == '') {
term.printError("PrintVar error: Missing argument: VARIABLE_NAME");
} else {
let result = {};
let args = WTerminal.splitToArguments(argLine);
const returnResult = args.includes("-r");
if (returnResult) {
args = args.filter(e => e !== '-r');
}
for (const gName of args) {
result[gName] = WTerminal.getGlobalVariable(gName);
}
const keys = Object.keys(result);
if (keys.length == 1) {
result = result[keys[0]];
term.printVar(result, keys[0]);
} else {
term.printVar(result);
}
if (returnResult) return result;
}
},
help: function(term) {
term.printLn("Prints value of global variable.");
term.printBold("Usage:");
term.printLn("printvar VARIABLE_NAME //Prints variable, returns nothing.");
term.printLn("printvar -r VARIABLE_NAME //Prints variable, returns variable.");
term.printBold("Samples:");
term.printLn("printvar terminal //Prints terminal");
term.printLn("printvar terminal.version //Prints terminal.version");
term.printLn("printvar -r terminal.lastResult //Prints terminal.lastResult and returns it.");
term.printLn("printvar document //Prints global document object.");
term.printLn("printvar document.body.children //Prints body elements.");
term.printLn("printvar document.head.children //Prints head elements.");
}
},
removevar: {
run: function(term, argLine) {
if (globalThis === undefined) {
term.printError("RemoveVar error: Missing globalThis");
} else if (argLine == '') {
term.printError("RemoveVar error: Missing arguments");
} else {
let args = WTerminal.splitToArguments(argLine);
const keys = Object.keys(globalThis);
const verbal = args.includes("-v");
if (verbal) {
args = args.filter(e => e !== '-v');
}
let count = 0;
if (args.includes("-a")) {
count = keys.length;
keys.forEach(key => {
if (verbal) term.printLn("removing: " + key)
delete globalThis[key];
});
term.printLn("Removed " + count + " keys.")
return;
} else if (args.includes("-n")) {
args = args.filter(e => e !== '-n');
keys.forEach(key => {
if (globalThis[key] === null || globalThis[key] === undefined) {
if (verbal) term.printLn("removing: " + key)
delete globalThis[key];
count++;
}
});
} else if (args.includes("-f")) {
args = args.filter(e => e !== '-f');
keys.forEach(key => {
if (globalThis[key] !== globalThis &&
!(typeof globalThis[key] === "function" && globalThis[key].toString().includes("[native code]"))) {
if (verbal) term.printLn("removing: " + key)
delete globalThis[key];
count++;
}
});
}
while (args.length > 0) {
const gName = args.shift(); //full global function name
const pName = gName.split('.'); //last object's parent name
const lastName = pName.pop(); //last object name
let obj = globalThis;
if (pName.length > 0) {
obj = WTerminal.getGlobalVariable(pName.join('.')); //parent object
}
if (obj !== undefined && obj[lastName] !== undefined) {
if (verbal) term.printLn("removing: " + gName)
delete obj[lastName];
count++;
} else {
if (obj === undefined) {
term.printError("Variable " + pName.join(".") + " = undefined")
} else {
term.printError("Variable " + gName + " = undefined");
}
}
}
term.printLn("Removed " + (count > 1 ? (count + " keys.") : (count === 0 ? "nothing" : "1 key")));
}
},
help: function(term) {
term.printLn("Removes global variables.");
term.printBold("Usage:");
term.printLn("removevar -v ... //Prints removing VARIABLE_NAME.");
term.printLn("removevar -f //Removes all global variables that are not a parent redefinition or native function.");
term.printLn("removevar -n //Removes all null or undefined global variables.");
term.printLn("removevar -a //Removes ALL global variables.");
term.printLn("removevar VARIABLE_NAMES //Removes the global variables provided.")
term.printBold("Samples:");
term.printLn("removevar terminal //Removes the global variable terminal.");
term.printLn("removevar var1 var2 //Removes the 2 global variables var1 and var2.");
term.printLn("removevar terminal.history //Removes history from terminal.");
term.printLn("removevar -n terminal.history //Removes history from terminal, and all null or undefined global variables.");
term.printLn("removevar -n -v //Prints variable names of all null or undefined global variables it removes.");
}
},
setvar: {
run: function(term, argLine) {
if (globalThis === undefined) {
term.printError("Setvar error: Missing globalThis");
} else {
if (argLine == '') {
term.printError("Setvar error: no name");
} else {
let args = WTerminal.splitToArguments(argLine);
for (const element of args) {
const keyValuePair = element.split("=");
if(keyValuePair.length < 2) throw new Error("missing arguements.");
const names = keyValuePair[0].split(".");
const value = WTerminal.stringToValue(keyValuePair[1]);
if (names.length == 1) {
globalThis[names[0]] = value;
term.printVar(globalThis[names[0]], keyValuePair[0]);
} else {
let obj = globalThis;
for (let i = 0; i < names.length - 1; i++) {
if (typeof obj[names[i]] === "object") obj = obj[names[i]];
else {
let rem = names.length - 1 - i;
names.splice(names.length - rem, rem);
let name = names.join('.');
term.printError(`Variable ${keyValuePair[0]} is not an object!`);
term.printVar(obj[names[i]], name);
return;
};
}
obj[names[names.length - 1]] = value;
return obj[names[names.length - 1]];
}
}
}
}
},
help: function(term) {
term.printBold("Usage:");
term.printLn("setvar NAME=VALUE //Sets VALUE to a global variable, NAME, and returns it.");
term.printBold("Samples:");
term.printLn("setvar terminal //Sets terminal to undefined");
term.printLn("setvar terminal.version=prehistoric //Sets terminal.version to string `prehistoric`");
term.printLn("setvar myNumber=8 //Sets myNumber to number 8");
term.printLn("setvar myNumber=(number)-8.1 //Sets myNumber to number -8.1");
term.printLn("setvar var1 var2 var3 //Creates 3 undefined variables");
term.printLn("setvar myName=\"Ward Truyen\" //Sets myName to string");
term.printLn('setvar obj={"1":"test","2":true} //Sets obj to JSON.stringified object');
term.printLn("setvar myFunc=(function)terminalPrintLn(\"Hello\");//Creates a function");
term.printLn("setvar myVar=(global)myFunc //Sets(binds) myVar to the contents of myFunc");
}
},
};
const aliases = {
run: "dovar",
pdo: "dovar -v ",
g: "getvar",
gg: "globals",
db: "printvar -r document.body.children",
dh: "printvar -r document.head.children",
gdb: "printvar -r document.body.children ",
gdh: "printvar -r document.head.children ",
result: "printvar -r terminal.lastResult",
error: "printvar terminal.lastError",
pv: "printvar -r ",
terminal: "printvar -r terminal",
// history: "printvar terminal.history",
};
//add commands in ext
if (WTerminal === undefined) {
console.error("WTerminal is missing!");
return;
}
for (let c of Object.keys(ext)) {
WTerminal.terminalAddCommand(c, ext[c].run, ext[c].help);
}
//add aliases
for (let c of Object.keys(aliases)) {
WTerminal.terminalAddAlias(c, aliases[c]);
}
};
//init
if (document.body) {
initTerminalVariableCommands();
} else {
window.addEventListener("load", initTerminalVariableCommands);
}
}