Initial commit
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/.idea/
 | 
				
			||||||
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					MIT License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2024 Ward Truyen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
							
								
								
									
										66
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					```
 | 
				
			||||||
 | 
					*  _  .  _  _____ .----..----. .-.   .-..-..-. .-.  .--.  .-.   
 | 
				
			||||||
 | 
					* | |/ \| |[_   _]| {__ | {)  }| .`-'. ||~|| .`| | / {} \ | |   
 | 
				
			||||||
 | 
					* |  ,-,  |  | |  | {__ | .-. \| |\ /| || || |\  |/  /\  \| `--.
 | 
				
			||||||
 | 
					* '-'   `-'  '-'  `----'`-' `-'`-' ` `-'`-'`-' `-'`-'  `-'`----'
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# For terminal fun on the web.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## About
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WTerminal is written in JavaScript and CSS. For use in websites. No compiling needed. 1 big class.
 | 
				
			||||||
 | 
					This can be used as a dropdown terminal and as a terminal on the page(static), at the same time.
 | 
				
			||||||
 | 
					It provides easy tools for printing- and changing public variables(javascript) and cookies.
 | 
				
			||||||
 | 
					The terminal is useful for testing/logging-debugging without opening the console every time.
 | 
				
			||||||
 | 
					WTerminal instances can be augmented with extention-commands and extention-aliases without changing the terminal.js code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Screenshots
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sample terminal as a static element
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sample terminal as a dropdown after playing ping pong
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sample terminal as a dropdown + darkmode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Terminal for testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Terminal for testing + darkmode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Terminal as extention (surfing youtube)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To test WTerminal I use serve on the src folder, [the npm package serve](https://www.npmjs.com/package/serve).
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					serve src/
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To install serve i suggest the following command:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					npm install --global serve
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Terminal as WebExtension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also use this terminal-project as a (Temporary) browser-extension. Get a terminal everywhere you surf.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [firefox addon paage](https://addons.mozilla.org/en-US/firefox/addon/wterminal/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					How to documentation: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [MDN WebExtension](https://developer.mozilla.org/en-US/diocs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension)
 | 
				
			||||||
 | 
					- [firefox info](https://firefox-source-docs.mozilla.org/devtools-user/about_colon_debugging/index.html#this-firefox)
 | 
				
			||||||
 | 
					- [firefox about:debugging](about:debugging)
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								icons/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										25
									
								
								manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "manifest_version": 2,
 | 
				
			||||||
 | 
					  "name": "WTerminal",
 | 
				
			||||||
 | 
					  "version": "1.0.1",
 | 
				
			||||||
 | 
					  "description": "Adds a dropdown terminal to all webpages",
 | 
				
			||||||
 | 
					  "author": "Ward Truyen",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "icons": {
 | 
				
			||||||
 | 
					    "48": "icons/icon.png"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "content_scripts": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "matches": ["<all_urls>"],
 | 
				
			||||||
 | 
					      "js": ["src/wterminal.js", "src/wterminal-addon.js",
 | 
				
			||||||
 | 
					        "src/termext/ext-cookies.js", "src/termext/ext-eval.js",
 | 
				
			||||||
 | 
					        "src/termext/ext-popvar.js", "src/termext/ext-passw.js", "src/termext/ext-timerdebug.js", 
 | 
				
			||||||
 | 
					        "src/termext/ext-transfer.js", "src/termext/ext-stresstest.js", "src/termext/ext-variables.js"],
 | 
				
			||||||
 | 
					      "css": ["src/wterminal.css"]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								public/screenshot1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 160 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/screenshot2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 162 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/screenshot3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 339 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/screenshot4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 324 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/screenshot5.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 141 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/screenshot6.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 266 KiB  | 
							
								
								
									
										103
									
								
								src/termext/ext-cookies.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						@@ -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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/termext/ext-featuretest.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						@@ -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
									
								
							
							
						
						@@ -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 = "◼";
 | 
				
			||||||
 | 
					    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 = '↻';
 | 
				
			||||||
 | 
					        btnRefresh.addEventListener("click", () => this.printVariable());
 | 
				
			||||||
 | 
					        let btnClose = WTerminal.createElement('button', { title: 'close' });
 | 
				
			||||||
 | 
					        btnClose.addEventListener("click", () => this.closePopup());
 | 
				
			||||||
 | 
					        btnClose.innerHTML = "✖";
 | 
				
			||||||
 | 
					        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 = "►";
 | 
				
			||||||
 | 
					          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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										40
									
								
								src/termext/ext-stresstest.js
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										45
									
								
								src/termext/ext-timerdebug.js
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										88
									
								
								src/termext/ext-transfer.js
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										348
									
								
								src/termext/ext-variables.js
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/wterminal-addon.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					/* Author: Ward Truyen
 | 
				
			||||||
 | 
					* Version: 1.0.0
 | 
				
			||||||
 | 
					* About:   this file is needed when the terminal is used as a browser-extention
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WTerminal.instalDropdownTerminal();
 | 
				
			||||||
							
								
								
									
										166
									
								
								src/wterminal.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,166 @@
 | 
				
			|||||||
 | 
					/* Author: Ward Truyen
 | 
				
			||||||
 | 
					* Version: 1.1.0
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-background {
 | 
				
			||||||
 | 
					  z-index: 9995;
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  top: 0px;
 | 
				
			||||||
 | 
					  left: 0px;
 | 
				
			||||||
 | 
					  color: black;
 | 
				
			||||||
 | 
					  line-height: normal;
 | 
				
			||||||
 | 
					  visibility: hidden;
 | 
				
			||||||
 | 
					  background: unset;
 | 
				
			||||||
 | 
					  transition: all 0.2s ease-out 0s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-background .wterminal-container{
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  margin: 0px auto;
 | 
				
			||||||
 | 
					  width: 70%;
 | 
				
			||||||
 | 
					  border: 1px solid #888;
 | 
				
			||||||
 | 
					  border-top: 0px solid grey;
 | 
				
			||||||
 | 
					  border-bottom-left-radius: 4px;
 | 
				
			||||||
 | 
					  border-bottom-right-radius: 4px;
 | 
				
			||||||
 | 
					  padding: 0px 4px 4px 4px;
 | 
				
			||||||
 | 
					  background: linear-gradient(24deg, rgba(209,211,196,1) 20%, rgba(221,221,221,1) 50%, rgba(221,221,221,1) 70%, rgba(190,199,207,1) 90%);
 | 
				
			||||||
 | 
					  box-shadow: 3px 3px 3px black;
 | 
				
			||||||
 | 
					  text-align: left;
 | 
				
			||||||
 | 
					  margin-top: -50%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-container pre {
 | 
				
			||||||
 | 
					  color: unset;
 | 
				
			||||||
 | 
					  border: 2px solid #a0a0a0d0;
 | 
				
			||||||
 | 
					  min-height: 20em;
 | 
				
			||||||
 | 
					  max-height: 20em;
 | 
				
			||||||
 | 
					  margin: 0px 0px 2px;
 | 
				
			||||||
 | 
					  padding: 2px 4px 6px 4px;
 | 
				
			||||||
 | 
					  background-color: #F0F0F0;
 | 
				
			||||||
 | 
					  overflow-y: scroll;
 | 
				
			||||||
 | 
					  font-family: Monospace, Incosolata, Courier;
 | 
				
			||||||
 | 
					  font-size: 12px;
 | 
				
			||||||
 | 
					  line-height: 1.08;
 | 
				
			||||||
 | 
					  width: unset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-output u{ 
 | 
				
			||||||
 | 
					  /* adds a nice fat blue underline to titles */
 | 
				
			||||||
 | 
					  text-decoration-color: #8cb4ff;
 | 
				
			||||||
 | 
					  text-decoration-thickness: .15rem;
 | 
				
			||||||
 | 
					  text-underline-offset: .1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-input {
 | 
				
			||||||
 | 
					  padding: 1px 2px;
 | 
				
			||||||
 | 
					  margin: 0px;
 | 
				
			||||||
 | 
					  background-color: #F0F0F0;
 | 
				
			||||||
 | 
					  color: black;
 | 
				
			||||||
 | 
					  border: 1px solid #ccc;
 | 
				
			||||||
 | 
					  border-radius: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-input:hover{
 | 
				
			||||||
 | 
					  background-color: #DDD;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-container input[type="submit"]:hover,
 | 
				
			||||||
 | 
					.wterminal-container button:hover{
 | 
				
			||||||
 | 
					  background-color: #DDD;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.wterminal-container input, .wterminal-container label{
 | 
				
			||||||
 | 
					  line-height: unset;
 | 
				
			||||||
 | 
					  display: unset;
 | 
				
			||||||
 | 
					  /* width: unset; */
 | 
				
			||||||
 | 
					  height: unset;
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  margin-left: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.wterminal-container input[type="submit"],
 | 
				
			||||||
 | 
					.wterminal-container button{
 | 
				
			||||||
 | 
					  width: unset;
 | 
				
			||||||
 | 
					  height: unset;
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  margin-left: 2px;
 | 
				
			||||||
 | 
					  padding: 1px 4px;
 | 
				
			||||||
 | 
					  color: black;
 | 
				
			||||||
 | 
					  background-color: #eee;
 | 
				
			||||||
 | 
					  border: 1px solid #aaa;
 | 
				
			||||||
 | 
					  border-radius: 3px;
 | 
				
			||||||
 | 
					  font-weight: normal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-background.wterminal-visible{
 | 
				
			||||||
 | 
					  background-color: #0000008F;
 | 
				
			||||||
 | 
					  backdrop-filter: blur(4px);
 | 
				
			||||||
 | 
					  visibility: visible;
 | 
				
			||||||
 | 
					  transition: background-color .1s ease-out 0s, backdrop-filter .1s ease-out 0s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-visible .wterminal-container{
 | 
				
			||||||
 | 
					  margin-top: 0px;
 | 
				
			||||||
 | 
					  transition: margin-top .2s ease-out 0s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.wterminal-container form{
 | 
				
			||||||
 | 
					  margin-left: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Width */
 | 
				
			||||||
 | 
					@media screen and (max-width: 480px) {
 | 
				
			||||||
 | 
					  .wterminal-input{
 | 
				
			||||||
 | 
					    width: 40%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@media screen and (min-width: 480px) and (max-width: 720px) {
 | 
				
			||||||
 | 
					  .wterminal-input{
 | 
				
			||||||
 | 
					    width: 50%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@media screen and (min-width: 720px) and (max-width: 1080px) {
 | 
				
			||||||
 | 
					  .wterminal-input{
 | 
				
			||||||
 | 
					    width: 60%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@media screen and (min-width: 1080px) {
 | 
				
			||||||
 | 
					  .wterminal-input{
 | 
				
			||||||
 | 
					    width: 70%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Height */
 | 
				
			||||||
 | 
					@media screen and (min-height: 512px) and (max-height: 1024px) {
 | 
				
			||||||
 | 
					  .wterminal-background .wterminal-container .wterminal-output{
 | 
				
			||||||
 | 
					    min-height: 32em;
 | 
				
			||||||
 | 
					    max-height: 32em;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@media screen and (min-height: 1024px) and (max-height: 1536px) {
 | 
				
			||||||
 | 
					  .wterminal-background .wterminal-container .wterminal-output{
 | 
				
			||||||
 | 
					    min-height: 48em;
 | 
				
			||||||
 | 
					    max-height: 48em;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@media screen and (min-height: 1536px) {
 | 
				
			||||||
 | 
					  .wterminal-background .wterminal-container .wterminal-output{
 | 
				
			||||||
 | 
					    min-height: 64em;
 | 
				
			||||||
 | 
					    max-height: 64em;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.theme-dark .wterminal-background .wterminal-container{
 | 
				
			||||||
 | 
					  color: #F0F0F0;
 | 
				
			||||||
 | 
					  background: #303030;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.theme-dark .wterminal-container pre,
 | 
				
			||||||
 | 
					.theme-dark .wterminal-container button,
 | 
				
			||||||
 | 
					.theme-dark .wterminal-container input
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  background-color: black;
 | 
				
			||||||
 | 
					  /* color: #F0F0F0; */
 | 
				
			||||||
 | 
					  color: white;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||