Compare commits

..

106 Commits

Author SHA1 Message Date
8c027332b1 Merge branch 'develop' of http://git.kmuhrer.net/maru21/templateGen into develop 2023-12-22 23:57:19 +01:00
c2810336f4 git 2023-12-22 23:56:25 +01:00
6a2126d851 up 2023-12-22 23:53:57 +01:00
9e0f0d0bd6 Update .gitignore 2023-12-22 22:43:06 +00:00
82f2454ce3 fixed set form left it commented out -_- 2023-12-22 23:41:10 +01:00
6ed652bcc8 2023-12-22 23:22:58 +01:00
8ed3166fc3 V2.0.4 2023-11-17 08:52:39 +01:00
d4f55d22ff fixed set form button and
list not been parsed with pell content
2023-11-13 18:16:34 +01:00
0a58816d4b fixed conversion error with pell 2023-11-12 16:49:21 +01:00
5eb216f395 started pell parsing on form import 2023-11-11 15:52:25 +01:00
461ba0e85c ver 2.0.3 2023-11-10 23:13:18 +01:00
99308d1e31 improved fileInfo 2023-11-06 20:45:59 +01:00
8a21ad31dd improved fileDisplay 2023-11-06 20:38:52 +01:00
546fe6ee37 import cleanup 2023-11-06 20:16:00 +01:00
edfcc95cdf sorting and cleanup 2023-11-06 20:13:18 +01:00
1c71af44ba expanded files Fileinfo 2023-11-06 19:17:21 +01:00
d737b43be6 cleanup parseForm 2023-11-06 18:51:20 +01:00
11521adff7 cleanup
merged copytoclipboard
2023-11-06 17:50:31 +01:00
aa6b528147 fixed parsedonsubmit and default userInput
implemented ts_copy
2023-11-06 16:51:26 +01:00
e15a291498 fixed ts_save 2023-11-06 12:02:36 +01:00
9fc05b97d3 implemented title and fixed empty results cause newline 2023-11-06 00:00:41 +01:00
77c7a7597a ver 2.0.2 2023-11-05 22:41:58 +01:00
cb90fb0916 cleanup 2023-11-04 19:58:12 +01:00
e2d5d28737 added create date to sidebar 2023-11-04 19:41:56 +01:00
1ac7eb8bf4 cleanup 2023-11-04 18:55:55 +01:00
1f008a22a8 fixed pells div newline
cleaned some console.logs
2023-11-02 19:36:42 +01:00
7a48cf0a63 ver 2.0.1 2023-11-01 19:43:47 +01:00
6c362693da tried some url control 2023-11-01 19:39:59 +01:00
89a44377c9 cleanup 2023-10-30 13:33:34 +01:00
54514eaa25 bug fix 2023-10-30 11:05:26 +01:00
3253f276f6 bug fixes 2023-10-29 22:18:37 +01:00
8bfa4d4c3f bug fixing 2023-10-29 21:20:40 +01:00
74469b9087 bug fixes 2023-10-29 20:29:25 +01:00
4973910146 implemented pell 2023-10-29 19:50:12 +01:00
6dc80fd74f version change
adding pell
2023-10-29 17:18:07 +01:00
6669f42bb7 cleanup 2023-10-28 22:11:28 +02:00
7a4f903bb4 made files more connected with pwHash 2023-10-28 22:07:04 +02:00
4e6562b225 cleanup 2023-10-28 21:29:47 +02:00
7f07aa2d0a string handling 2023-10-28 21:27:19 +02:00
600eab77f4 fixed getUsrId usage 2023-10-28 21:25:35 +02:00
b6fde65054 made shure that a password has been set 2023-10-28 21:15:27 +02:00
7dcc5815e3 cleanup 2023-10-28 20:42:23 +02:00
a39c16e54b fixed logout / login 2023-10-28 20:36:11 +02:00
e08e3e4bbd added force hideMenus 2023-10-28 18:21:37 +02:00
1fc89d0768 design changes 2023-10-28 17:55:31 +02:00
24b5b6e842 made modal non skippable 2023-10-28 17:46:12 +02:00
cf9a4e0efb fundamental changes
implemented temporary storage
implemented settings
bug fixes
2023-10-28 14:44:08 +02:00
e4336766a0 fixed bugs 2023-10-16 14:18:55 +02:00
9ee0b3e2c8 implemented charRed 2023-10-16 12:54:27 +02:00
fecd26f4bb implemented sanitizing 2023-10-15 23:49:05 +02:00
57d5fcceb4 fixed many bugs
edit of cl templates
setform button display
changed footer
changed overall layout a bit
2023-10-15 22:46:20 +02:00
63c072f4f2 fixed button hover for files added fontsize and font 2023-10-15 17:29:19 +02:00
43a33ed76c Version 9.9.9 2023-10-15 17:04:35 +02:00
71b2186171 bug fixes 2023-10-15 00:25:36 +02:00
1f89f0625a cleanup 2023-10-15 00:13:16 +02:00
c182c6ea49 cleanup 2023-10-14 23:42:52 +02:00
88037c5ed8 changed script launch
changed how settings are handled
2023-10-14 23:41:04 +02:00
7f67791012 Ver 9.9.8 2023-10-14 23:19:46 +02:00
895f5245a8 Ver 9.9.8 2023-10-14 23:16:57 +02:00
5ad59102a5 sidebar color change 2023-10-14 20:50:19 +02:00
f5f2e78596 fixed title on mobile devices issue 2023-10-14 20:43:00 +02:00
387d043afd improved delete all files
fixed some modal timing issues
changed modal position
testing: disabled copy and text to output field
2023-10-14 20:42:15 +02:00
b7868bc4e5 ver 9.9.7 2023-10-14 20:12:02 +02:00
dc6229c39f version 9.9.6
added clear all files to files
fixed instructions
2023-10-14 17:16:32 +02:00
c2920b898f reversed files order 2023-10-14 15:24:23 +02:00
4dc047e05a style change 2023-10-14 15:03:40 +02:00
5dd9e0c369 emergency bug fix
preventing dataloss after logout
2023-10-07 21:52:06 +02:00
9fe5a1c6d1 style changes ver 9.9.4 2023-10-07 21:50:00 +02:00
92bbebd2a1 Bugfixes and feature improvements new ver 9.9.3
fixed bug with sidebar click event not being cleared after accessing files and then pressing edit
some cosmetic changes animations
reimplemented bookshelfexport in localonly mode
added logout functionality
2023-10-07 20:42:58 +02:00
e257c55ca7 disabled upload 2023-10-07 18:27:36 +02:00
71085319c1 - 2023-10-06 21:54:29 +02:00
44a3ae0429 - 2023-10-06 21:53:01 +02:00
db41bacc52 fixed some bugs 2023-10-06 21:48:14 +02:00
f853259cbb fixed bug with replace markups before delivery 2023-10-05 17:46:05 +02:00
aae8d60ecd implemented sessionVerification 2023-10-03 20:34:42 +02:00
6d35d3d608 started with cookie implementation 2023-10-03 19:05:06 +02:00
1d711542da started with cookie implementation 2023-10-02 21:56:03 +02:00
a223e8e8cb fixed oneword title bug 2023-10-02 11:37:36 +02:00
8a25e01229 legacy reupload 2023-10-01 20:59:46 +02:00
268749a35b cleanup 2023-10-01 20:58:32 +02:00
ec90d4c676 readded 2023-10-01 18:53:26 +02:00
696c3f97a1 implemented lineBreak
default 200
2023-10-01 18:50:46 +02:00
87ec93e209 started implementing linebreak 2023-09-30 21:48:26 +02:00
9a2af80f43 code cleaning
parseForm
2023-09-30 19:29:13 +02:00
d370539def started commenting parseForm 2023-09-30 17:07:29 +03:00
e6d4e42484 fixed textblock edit
got appended every time configedit was accessed
2023-09-23 14:12:00 +02:00
ca697d40df Merge branch 'develop' of 10.196.211.3:222]:maru21/templateGen
into develop
2023-09-23 14:05:30 +02:00
eac9c04c4f configTemplates
fixed issue of reoccuring textBlocks entry
2023-09-21 14:21:36 +02:00
8e25ed1e75 cleanup 2023-09-21 14:18:06 +02:00
7198470dc2 version update 2023-09-21 14:16:34 +02:00
a85ca96bfd styled logo 2023-09-18 17:42:45 +02:00
4a2b88132b added logo 2023-09-18 17:31:36 +02:00
10938eb91a init 2023-09-18 17:15:35 +02:00
cae8dfa68b customized login screen
added name stenodok
2023-09-17 21:08:03 +02:00
b5e548c97f made textblocks editable 2023-09-17 18:45:00 +02:00
381d98403a Merge branch 'develop' of 10.196.211.3:222]:maru21/templateGen into develop 2023-09-17 18:44:27 +02:00
177080bc89 d 2023-09-17 18:44:17 +02:00
d94e2195e3 made textblocks editable 2023-09-17 18:41:54 +02:00
ae0249a4ec update 2023-09-17 18:41:26 +02:00
c204e45912 made textBlocks file editable 2023-09-17 18:38:48 +02:00
f52c1e5adb added storage folder for bookshelf files 2023-09-17 18:29:28 +02:00
25e5cfc3e3 to be improved 2023-09-17 18:25:44 +02:00
798ab52dcb changed passwordHash object
goal was do prevent fingerprint change to destroy decryption
2023-09-17 18:07:16 +02:00
ce8e56290f fixed spelling error 2023-09-17 14:10:30 +02:00
be677cf9e0 fixed textBlock insert
fixed tracking activeState.lastElement
2023-09-17 14:03:47 +02:00
0aec5b7625 raised js version to 9.3
fixed textblocks dispay error
fixed bulletpoints on empty lines
2023-09-16 13:00:15 +02:00
340 changed files with 79611 additions and 189 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.vscode
font-awesome
storage/*
template/*

27
css/pell.css Normal file
View File

@ -0,0 +1,27 @@
.pell {
border: 1px solid rgba(10, 10, 10, 0.1);
box-sizing: border-box; }
.pell-content {
background-color: #FFF;
box-sizing: border-box;
height: 300px;
outline: 0;
overflow-y: auto;
padding: 10px; }
.pell-actionbar {
border-bottom: 1px solid rgba(10, 10, 10, 0.1); }
.pell-button {
background-color: transparent;
border: none;
cursor: pointer;
height: 30px;
outline: 0;
width: 30px;
vertical-align: bottom; }
.pell-button-selected {
background-color: #9e9e9e; }

View File

@ -49,3 +49,9 @@ a {text-decoration: none;}
textarea {
resize: none;
}
.logo {
border: #202e3f;
border-style: solid;
}

View File

@ -33,8 +33,11 @@
.w3-flat-pumpkin
{color:#fff;background-color:#d35400}
.w3-flat-pomegranate
{color:#fff;background-color:#c0392b}
{color:#fff;background-color:#c0392b !important}
.w3-flat-silver
{color:#000;background-color:#bdc3c7}
.w3-flat-asbestos
{color:#fff;background-color:#7f8c8d}
.w3-hover-flat-pomegranate:hover
{color:#fff !important;background-color:#c0392b !important}

View File

@ -58,7 +58,7 @@ hr{border:0;border-top:1px solid #eee;margin:20px 0}
.w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%}
.w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px}
.w3-main,#main{transition:margin-left .4s}
.w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.6)}
.w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.6);backdrop-filter: blur(6px);}
.w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px}
.w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto}
.w3-bar .w3-bar-item{padding:8px 16px;float:left;width:auto;border:none;display:block;outline:0}

View File

@ -1,38 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<title>Template Generator</title>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<head>
<title>Template Generator</title>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Montserrat"
/>
<link rel="stylesheet" href="css/w3.css" />
<link rel="stylesheet" href="css/w3-colors-flat.css" />
<link rel="stylesheet" href="css/font-awesome/css/all.min.css" />
<link rel="stylesheet" href="css/styles.css" />
<script>
//current javascript version
let jsVer = "2.0.4";
<script type="module" src="js/9.2/main.js"></script>
let script = document.createElement("script");
script.src = "js/" + jsVer + "/init.js";
script.type = "module";
document.head.appendChild(script);
</script>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lato"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Montserrat"
/>
<link rel="stylesheet" href="css/w3.css" />
<link rel="stylesheet" href="css/w3-colors-flat.css" />
<link rel="stylesheet" href="css/font-awesome/css/all.min.css" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="stylesheet" href="css/pell.css" />
</head>
<body>
<body class="w3-flat-clouds">
<div
class="w3-sidebar w3-bar-block w3-collapse w3-large"
style="width: 300px; margin-top: 51px"
class="w3-sidebar w3-bar-block w3-collapse w3-large w3-flat-clouds"
style="width: 300px; margin-top: 51px; padding-top: 12px"
id="sidebar"
>
<ul class="w3-ul">
<li
<ul class="w3-ul" style="padding-top: 1px;">
<!-- <li
class="w3-bar-item w3-padding-large w3-button"
style="border-bottom: 1px solid rgb(221, 221, 221)"
id="loadTemplateBtn"
>
Load new template
</li>
</li> -->
<li
class="w3-bar-item w3-padding-large w3-button"
style="border-bottom: 1px solid rgb(221, 221, 221)"
@ -42,7 +55,7 @@
</li>
<li
class="w3-bar-item w3-padding-large w3-button"
style="display: block; border-bottom: 2px solid rgb(221, 221, 221)"
style="border-bottom: 2px solid rgb(221, 221, 221)"
id="importFilesSB"
>
Manage backup files
@ -71,29 +84,28 @@
href="javascript:void(0);"
title="Toggle Navigation Menu"
id="toggleNavigationMenu"
><i class="fa fa-bars"></i
><i class="fa fa-ellipsis-v"></i
></a>
<a
class="w3-button w3-right w3-padding-large w3-hover-grey w3-large w3-flat-wet-aspalt"
href="javascript:void(0);"
title="Toggle Textblocks Menu"
id="toggleTestBlocksMenu"
style="display: none"
><i class="fa fa-plane"></i
></a>
<a
class="w3-button w3-right w3-padding-large w3-hover-grey w3-large w3-flat-wet-aspalt"
href="javascript:void(0);"
title="Toggle Files Menu"
title="Open Files Menu"
id="toggleFilesMenu"
><i class="fa fa-file"></i
></a>
<a
href="."
id="siteTitle"
class="w3-left-align w3-button w3-padding-large w3-flat-wet-asphalt"
>Template Gen</a
>
<div
id="logo"
class="w3-left-align w3-padding-large w3-flat-wet-asphalt"
><img class="logo" src="logo.png" alt="logo" height="30px"
/></div>
</div>
<div
@ -107,9 +119,11 @@
</div>
<div class="w3-main" style="margin-left: 300px">
<h2 id="siteTitle" style="display: none">hello</h2>
<div
id="mainForm"
class="w3-row-padding w3-padding-top-64 w3-container w3-flat-clouds"
style="min-height: 600px"
>
<div class="w3-content">
<div class="w3-third w3-center">
@ -124,11 +138,30 @@
<h5 class="w3-padding-32">
Generate Text and Copy it to Clipboard.
<br />
Create a new Template using text markings shown below. Please make
sure to follow the instructions closeley.
Create a new Template using text markings shown below.
</h5>
<h5 class="w3-padding-top w3-text-grey">
<b>Instructions:</b>
<b>Shortcuts for template input:</b>
</h5>
<ul class="w3-text-grey w3-ul">
<li>
<b>Textblocks can be invoked by adding a leading ! sign:</b>
click the airplane button for a complete list
<code class="w3-codespan">!ne = no entry</code>
</li>
<li>
You can use markups directly in the textarea at the beginning of
a line.<br />
<b>These markups are available:</b><br />
<code class="w3-codespan">!l = list</code><br />
<code class="w3-codespan">!ls = sub item</code><br />
<code class="w3-codespan">!n = numbered list</code><br />
<code class="w3-codespan">!e = end markup</code><br />
<code class="w3-codespan">!es = end sub markup</code><br />
</li>
</ul>
<h5 class="w3-padding-top w3-text-grey">
<b>Instructions for creating a template:</b>
</h5>
<ul class="w3-text-grey w3-ul">
<li>
@ -136,110 +169,106 @@
and has to be always set
</li>
<li>
The <b>Priorities</b> organize each input field and shows higher
priority ones first.
The <b>Priority</b> value organizes each input field and shows
higher priority ones first.
</li>
<li>
<b>For one word which needs to change:</b><br />
<code class="w3-codespan">%Sample Word%1</code>
</li>
<li>
<code class="w3-codespan">%Sample Word%1</code><br />
Use <code class="w3-codespan">%</code> at the start and end
position of the placeholder
position of the placeholder<br />
Set <code class="w3-codespan">1</code> as priority or any other
number up until <code class="w3-codespan">99</code>
</li>
<li>
<b>Custom input placeholders:</b><br />
<code class="w3-codespan">%Sample Expression=longText%1</code
><br />
Use <code class="w3-codespan">%</code> at the start and end
position of the placeholder<br />
Use
<code class="w3-codespan">Sample Expression=</code> placeholder
name<br />
Set <code class="w3-codespan">1</code> as priority or any other
number up until 99
number up until <code class="w3-codespan">99</code> <br />
Config <code class="w3-codespan">hiddenField</code> like so:
<br />
<code class="w3-codespan"
>%Sample Expression=hiddenField:id:longText:!l%1</code
><br />
in this example <code class="w3-codespan">longText:!l</code> can
also be omitted.<br />
With <code class="w3-codespan">longText</code> you can add
markups like <code class="w3-codespan">!l</code> by adding them
like this:<br />
<code class="w3-codespan"
>%Sample Expression=longText:!l%1</code
>
</li>
<li>
<b
>Use field types like longText or markup to customize
further</b
>
These are all the different Field types:<br />
<code class="w3-codespan">simpleInput</code><br />
<code class="w3-codespan">longText</code><br />
<code class="w3-codespan">hiddenField</code><br />
<code class="w3-codespan">current_time</code><br />
<code class="w3-codespan">current_date</code><br />
<code class="w3-codespan">title</code><br />
<code class="w3-codespan">markup:title</code><br />
And these are the markups you can add:<br />
<code class="w3-codespan">title</code><br />
<code class="w3-codespan">link</code><br />
<code class="w3-codespan">italic</code><br />
<code class="w3-codespan">green_highlighted</code><br />
<code class="w3-codespan">highlighted</code><br />
</li>
<li>
<b>For gender specific expressions:</b><br />
<code class="w3-codespan"
>%Sample Expression=m:der Bauer;w:die B&auml;uerin;d:
Bauern;%1</code
>
</li>
<li>
><br />
Use <code class="w3-codespan">%</code> at the start and end
position of the placeholder
</li>
<li>
position of the placeholder<br />
Use <code class="w3-codespan">Sample Expression=</code> as
placeholder name
</li>
<li>
Use <code class="w3-codespan">m:der Bauer;</code> for each
gender; be careful to add it like so for every gender.
placeholder name<br />
Use <code class="w3-codespan">m:der Bauer;</code> <br />for each
gender; be careful to add it for the last item aswell
</li>
<li>
<b>For dropdown lists:</b><br />
Use <code class="w3-codespan">l:item 1;</code> for each
item
Use
<code class="w3-codespan"
>%Sample Expression=l:item 1;l:item 2;%1</code
>
for each item
</li>
<li>
<b>For hidden fields and its trigger:</b><br />
Use <code class="w3-codespan">h:item 1!id;</code> for each
item add an unique id!
</li>
<li>
This works only in conjunction with <code class="w3-codespan">hiddenField</code> below
</li>
<li>
<b>Custom input placeholders:</b><br />
<code class="w3-codespan">%Sample Expression=longText%1</code>
</li>
<li>
Use <code class="w3-codespan">%</code> at the start and end
position of the placeholder
</li>
<li>
Use
<code class="w3-codespan">Sample Expression=</code> placeholder
name
</li>
<li>
Set <code class="w3-codespan">1</code> as priority or any other
number up until 99
</li>
<li>
At the moment there are these custom ones:<br />
<code class="w3-codespan"
>simpleInput, longText, hiddenField, current_time,
current_date</code
>
</li>
<li>
Config <code class="w3-codespan">hiddenField</code> like so: <br>
<code class="w3-codespan">%Sample Expression=hiddenField:id:longText:!l%1</code>
</li>
<li>
in this example <code class="w3-codespan">longText:!l</code> can also be omitted.
</li>
<li>
With <code class="w3-codespan">longText</code> you can add
markups like <code class="w3-codespan">!l</code> by adding them
like this:
</li>
<li>
<code class="w3-codespan"
>%Sample Expression=longText:!l%1</code
>
</li>
<li>
You can also use markups directly in the textarea or in the
template file at the beginning of a line.
</li>
<li>
<b>These markups are available:</b><br />
<code class="w3-codespan"
>!l = list, !ls = sub item, !n = numbered list, !e = end
markup, !es = end sub markup</code
>
</li>
<li>
<b>Textblocks can be invoked by adding a leading ! sign:</b
>%Sample Expression=h:itemid 1:fieldtype:formatting;%1</code
><br />
<code class="w3-codespan">!ne = no entry</code>
You can also have multiple hidden fields selectable by a list
</li>
<li>
<b>For titles in form</b><br />
Use
<code class="w3-codespan"
>%Sample Expression=title%1</code>
</li>
<li>
You can also use markups in the template file at the beginning
of a line.<br />
<b>These markups are available:</b><br />
<code class="w3-codespan">!l = list</code><br />
<code class="w3-codespan">!ls = sub item</code><br />
<code class="w3-codespan">!n = numbered list</code><br />
<code class="w3-codespan">!e = end markup</code><br />
<code class="w3-codespan">!es = end sub markup</code><br />
</li>
</ul>
</div>
@ -253,18 +282,30 @@
</div>
<div class="w3-container w3-flat-clouds w3-padding">
<div
id="outputInfo"
class="w3-row-padding w3-padding-64 w3-container w3-flat-clouds w3-small"
style="margin-bottom: 0px; display: none"
></div>
<div
id="output"
class="w3-row-padding w3-padding-64 w3-container w3-flat-clouds"
style="margin-bottom: 0px"
style="margin-bottom: 0px; display: none"
></div>
</div>
<div id="login" style="display: none" class="w3-modal w3-card-4">
<div class="w3-modal-content w3-margin-top">
<div id="login" style="display: none" class="w3-modal">
<div
class="w3-card-4 w3-modal-content w3-margin-top w3-animate-opacity"
style="max-width: 600px"
>
<div class="w3-container w3-padding-32 w3-flat-clouds">
<form method="post" action="javascript:void(0)" id="loginForm">
<h1>
Welcome to <img src="logo.png" alt="logo" height="40px" />
</h1>
<br />
<br />
<label> enter password: </label>
<input
type="password"
@ -276,7 +317,8 @@
id="submitPassword"
type="submit"
value="Submit"
style="display: none"
class="w3-button w3-flat-wet-asphalt"
style="display: block; margin-top: 20px"
/>
</form>
</div>
@ -292,53 +334,41 @@
>
<p>
wrong password - would you like to
<a
href="#"
style="text-decoration: underline"
onclick="localStorage.clear()"
>clear</a
>
<a href="#" style="text-decoration: underline">clear</a>
all files?
</p>
</div>
</div>
</div>
<div id="modalNotifier" style="display: none" class="w3-modal w3-card-4">
<div class="w3-modal-content w3-margin-top">
<div
id="modalNotifier"
style="display: none; padding-top: 200px !important"
class="w3-modal"
>
<div
class="w3-card-4 w3-modal-content w3-margin-top"
style="max-width: 600px"
>
<span
onclick="this.parentElement.parentElement.style.display='none'"
class="w3-button w3-display-topright w3-flat-clouds"
>&times;</span>
onclick="this.parentElement.parentElement.style.display='none'"
class="w3-button w3-display-topright w3-flat-clouds"
id="modalNotifierClose"
>&times;</span
>
<div class="w3-container w3-padding-32 w3-flat-clouds">
<span id="modalMsg"></span>
</div>
</div>
</div>
<div class="w3-container w3-flat-clouds" style="height: 15em">
<br />
</div>
<!-- Footer -->
<footer
class="w3-container w3-padding-64 w3-center w3-opacity w3-flat-asbestos"
class="w3-container w3-padding w3-flat-clouds w3-center w3-margin-top"
>
<br />
<br />
<div
class="upload-btn-wrapper"
id="setFormButton"
style="display: none"
class="w3-container w3-margin-top w3-right-align w3-small"
id="currentVersion"
>
<button
class="w3-button w3-border w3-flat-wet-asphalt"
id="setFormBtn"
>
Set Form as Template
</button>
</div>
<div class="w3-container w3-margin-top" id="currentVersion">
<span></span>
</div>
</footer>

478
js/2.0.0/buildForm.js Normal file
View File

@ -0,0 +1,478 @@
import { getFileName } from "./storage.js";
import pell from "./pell.js"
import { inputRead } from "./scripts.js";
function transformTemplateObject(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//console.log(objects);
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//create sidebar set form button
let sidebarSetFormButton = document.createElement("li");
sidebarSetFormButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSetFormButton.style.borderTop = "2px solid #ddd";
sidebarSetFormButton.id = "sb-setform";
sidebarSetFormButton.innerHTML = "Set input as preset";
sidebarList.appendChild(sidebarSetFormButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
copyBtn.id = "fromCopyBtn";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = connectedListsArray[0].word;
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
label = document.createElement("LABEL");
label.innerHTML = '';
//div.classList.add("w3-center");
div.classList.replace("w3-flat-silver", "w3-flat-clouds");
div.appendChild(label);
div.appendChild(select3);
} else {
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
}
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
divContainer.classList.add("w3-animate-opacity")
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
sidebarList.appendChild(sidebarListItem);
}
function buildLongTextInput(source, textarea, label) {
if (activeState.settings.enablePell == "false") return;
//hide default textarea
textarea.style.display = "none";
label.style.display = "none";
let title = document.createElement("b");
title.innerText = label.innerText;
const editor = pell.init({
element: source,
defaultParagraphSeparator: "br",
actions: [
"bold",
"italic",
"underline",
"strikethrough",
"paragraph",
"heading1",
"heading2",
{
name: 'ulist',
icon: 'L'
},
"olist"
],
onChange: function (html) {
//correct lastElement
activeState.lastElement = textarea.id;
textarea.value = html;
},
});
let actionBar = editor.getElementsByClassName("pell-actionbar")[0];
let content = editor.getElementsByClassName("pell-content")[0];
let actionBarElements = actionBar.getElementsByClassName("pell-button");
let newActionBarElements = [];
for (let actionBarElement of actionBarElements ) {
actionBarElement.classList.add("w3-right");
actionBarElement.setAttribute("tabindex","-1");
newActionBarElements.push(actionBarElement);
}
//reverse actionbar back to org order
actionBar.innerHTML = "";
for (let newActionBarElement of newActionBarElements.reverse()) {
actionBar.appendChild(newActionBarElement);
}
actionBar.classList.add("w3-container");
actionBar.style.paddingLeft = "0px";
actionBar.appendChild(title);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default transformTemplateObject;

208
js/2.0.0/createTemplate.js Normal file
View File

@ -0,0 +1,208 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { hideMenus, modalNotifier, resetNavBar } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus("force");
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
if (!templates.includes('_textBlocks')) {
templates.push('_textBlocks');
}
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", activeState.settings.notifierPause);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

314
js/2.0.0/evts.js Normal file
View File

@ -0,0 +1,314 @@
import { passwordHash } from "./scripts.js";
import { clearData, createBookShelf, importBookShelf } from "./storage.js";
import {
loadTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer,
} from "./web.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
sidebar.style.marginTop = "35px";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += " " + insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
if (element.parentElement != undefined) {
if (
element.parentElement.getElementsByClassName("pell-content")[0] !=
undefined
) {
element.parentElement.getElementsByClassName(
"pell-content"
)[0].innerHTML = element.value;
element = element.parentElement.getElementsByClassName("pell-content")[0];
}
}
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
//createStorageObj();
}
function clickClearForm() {
//document.activeElement.blur();
//document.getElementById("sidebar").focus();
clearData("userInput");
let lT = activeState.loadedTemplate;
loadTemplate(lT);
}
function hideMenus(evt) {
if (evt === undefined) return;
if (evt != "force" && evt.target.parentElement != null) {
if (evt.target.parentElement.id == "navMob") return;
if (evt.target.parentElement.id == "navReg") return;
if (evt.target.parentElement.parentElement != null) {
if (evt.target.parentElement.parentElement.id == "navMob") return;
if (evt.target.parentElement.parentElement.id == "navReg") return;
}
}
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout = 3, closeable = true) {
let modalElement = document.getElementById("modalNotifier");
let modalElementCloseBtn = document.getElementById("modalNotifierClose");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
if (!closeable) modalElementCloseBtn.style.display = "none";
msgElement.innerHTML = msg;
if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function printVersion(msg = "") {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length - 2];
//add it to document footer currentVersion
versionSpan.textContent = msg + " version: " + pathVersion;
}
}
}
function clickImportFiles() {
if (activeState.settings.localOnly == "true") {
createBookShelfDownload();
return;
}
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Imported!",
activeState.settings.notifierPause
);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display =
"none";
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: " +
activeState.serverFilesTs.replace("_", " - ") +
"<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0
);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
activeState.userId +
".txt' style='text-decoration: underline;' download>download</a> them?",
0
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0
);
}
function createBookShelfDownload() {
let data = createBookShelf();
let filename = data[0]["data"] + ".txt";
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," +
encodeURIComponent(JSON.stringify(data))
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
modalNotifier(
"Since you are in local only mode you can only export a backup of your files \
<br><br> \
<div class='w3-container'> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Export</button></div>",
0
);
}
function resetNavBar() {
//enable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "";
//enable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "block";
}
function resetPage() {
return;
//set current page value in activeState object
activeState.activePage = "landing";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Template Gen";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(activeState.orgPage.main);
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(activeState.orgPage.sidebar);
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
clickClearForm,
modalNotifier,
clickImportFiles,
resetNavBar,
printVersion,
resetPage,
};

454
js/2.0.0/files.js Normal file
View File

@ -0,0 +1,454 @@
import {
storeData,
clearData,
retrieveData,
} from "./storage.js";
import { loadTemplate } from "./web.js";
import parseFormOnSubmit from "./parseForm.js";
import { modalNotifier, resetNavBar } from "./evts.js";
import { passwordHash } from "./scripts.js";
function buildFile() {
//set current page value in activeState object
activeState.activePage = "files";
//set templateFiles array
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
//console.log("none yet");
modalNotifier("there are no saved texts yet", activeState.settings.notifierPause);
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Saved files";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//disable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = 'background-color:#9e9e9e !important';
target.style.borderBottom = "4px solid #9e9e9e";
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
let fileInfoDiv = document.getElementById("outputInfo");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
fileInfoDiv.innerHTML = "";
fileInfoDiv.replaceWith(fileInfoDiv.cloneNode(true));
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let fileName = e.target.dataset.file;
let template = e.target.dataset.template;
let pos = e.target.dataset.tfpos;
clickLoadFileDiv(fileName, template, pos);
}
});
}
function loadFileDiv(fileName, template, pos) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
//append TS info
let fileInfoDiv = document.getElementById("outputInfo");
let tF = retrieveData("templateFiles");
let ts = tF[pos].metadata.ts_create;
ts = ts.current_time_long+" "+ts.current_date+"."+ts.current_year;
fileInfoDiv.innerHTML = "<p>created at: "+ts+" | template: "+template+"</p>";
fileInfoDiv.style.display = "block";
}
function loadFileDivCallBack() {
let tF = retrieveData("templateFiles");
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "_m21_" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-flat-pomegranate");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
let parsedTemplate = parseFormOnSubmit(false, true);
div.appendChild(parsedTemplate);
fileDisplay.appendChild(div);
let ts = document.createElement("p");
ts.innerHTML = ""
//fileDisplay.appendChild(ts);
document.getElementById("mainForm").appendChild(fileDisplay);
//fix min height of file display
try {
document.getElementById("fileDisplay").style.cssText = "min-height: 300px;";
} catch (e) {}
//fix fontsize for display
try {
document.getElementById("fileDisplay").firstChild.style.fontSize = "1em";
} catch (e) {}
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template, pos) {
if (fileName == "_overflow") return;
if (fileName == "_clearAll") {
clickClearAllFiles();
return;
}
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template, pos);
}
function clearFileData(storData) {
let fileName = storData.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
clearData(fileName);
clearData("userInput");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-padding-large",
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Saved Files:"
sidebarList.appendChild(sidebarListItem);
let c = 0;
let sidebarItemsAmount = 10;
for (let obj of tF.reverse()) {
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
//handle to many files on screen and display hidden files amount
if (c > sidebarItemsAmount) {
sidebarListItem.setAttribute("data-template", "_overflow");
sidebarListItem.setAttribute("data-file", "_overflow");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML =
tF.length - sidebarItemsAmount + " files not shown";
sidebarList.appendChild(sidebarListItem);
break;
}
sidebarListItem.innerHTML = obj.fileName.replace(/_/g, " ");
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarListItem.setAttribute("data-tFPos", obj.pos);
sidebarList.appendChild(sidebarListItem);
c++;
}
//clear all files button
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button");
sidebarListItem.setAttribute("data-template", "_clearAll");
sidebarListItem.setAttribute("data-file", "_clearAll");
sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.style.width = "300px";
sidebarListItem.innerHTML = "Clear all files";
sidebarList.appendChild(sidebarListItem);
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return (
"<div id='fileDisplay' class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" +
msg +
"</p><br><br><br><br><br><br><br><br><br><br><br></div></div>"
);
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
editSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-carrot"
);
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-carrot",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
break;
case "Delete":
console.log(storageName);
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
let delFileName = activeState.fileName;
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(previousFile.fileName, previousFile.template, previousFile.pos);
} else {
document.getElementById("mainForm").innerHTML =
mainFormPlaceholder("No file yet");
}
modalNotifier(delFileName + " deleted!", activeState.settings.notifierPause);
break;
default:
e.preventDefault;
}
}
});
}
function editSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("_m21_")[0], storageName.split("_m21_")[1])
);
//reset sidebar to clear events
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
//reset navbar above all else
resetNavBar();
//reset correct activePage
activeState.activePage = "template";
loadTemplate(storageName.split("_m21_")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i - 1];
if (previousFile === undefined) {
//get the next one if there is no previous one
previousFile = tF[i + 1];
}
break;
}
i++;
}
return previousFile != undefined ? previousFile : false;
}
function clickClearAllFiles() {
let modal = document.getElementById("modalMsg");
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Delete":
clearAllFiles();
modal.replaceWith(modal.cloneNode(true));
modalNotifier("All files deleted!", activeState.settings.notifierPause);
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
<p>Would you really like to delete all stored files?</p> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button>",
0
);
}
function clearAllFiles() {
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
modalNotifier("there are no saved texts yet", activeState.settings.notifierPause);
return;
}
for (let storageName of tF) {
clearFileData(storageName.fileName);
}
}
export { buildFile, loadFileDivCallBack };

303
js/2.0.0/form.js Normal file
View File

@ -0,0 +1,303 @@
import { storeData, createStorageObj } from "./storage.js";
import parseInput from "./parseTemplate.js";
import transformTemplateObject from "./buildForm.js";
import { handleOnBlur, modalNotifier } from "./evts.js";
import parseFormOnSubmit, { parseTextMarkups } from "./parseForm.js";
import { setTemplatePreset } from "./web.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
let placeholder;
try {
placeholder = JSON.parse(jsonPlaceholder);
} catch (e) {
placeholder = ""
}
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", placeholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseInput Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseInput(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
activeState.templateObjects = objects;
activeState.fullString = templateInput;
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
activeState.templateObjectsPurified = objectsPurified;
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
//sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) {return};
transformTemplateObject(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj();
parseFormOnSubmit();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
e.target.value = "Copied";
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
const timeoutCopy = setTimeout(() => {
//e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
//e.target.value = "Copy";
e.target.style.pointerEvents = "auto";
}, 5000);
break;
case "Save":
createStorageObj();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause);
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
parseFormOnSubmit();
modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause);
}
if (e.target.id == "sb-setform") {
let dataArray = parseFormOnSubmit(true);
let lT = activeState.loadedTemplate;
setTemplatePreset(lT, JSON.stringify(dataArray));
modalNotifier("Input saved as preset", activeState.settings.notifierPause);
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener to each form object
let mainForm = document.getElementById("mainFormObj");
for (let formElement of mainForm.children) {
let id = formElement.firstChild.lastChild.id;
document.getElementById(id).addEventListener("blur", (e) => {
e.preventDefault;
handleOnBlur(e.target);
});
}
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
//handle pell content focus
if (targetElement.parentElement != undefined) {
if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0];
}
}
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/2.0.0/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

185
js/2.0.0/init.js Normal file
View File

@ -0,0 +1,185 @@
import {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
clickImportFiles,
modalNotifier,
printVersion,
resetPage
} from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, {
passwordHash,
inputRead
} from "./scripts.js";
import parseFormOnSubmit from "./parseForm.js";
import { createStorageObj, storeSettings } from "./storage.js";
import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js";
window.activeState = {
userId: "",
sessionToken: "",
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
settings: {
localOnly: "true",
lineBreak: 120,
font: "Arial",
fontSize: "10px",
notifierPause: 1,
persistentStorage: "false",
enablePell: "false",
},
templates: [],
templateObjectsPurified: [],
templateObjects: [],
fullString: "",
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
],
markups: ["title", "link", "italic", "green_highlighted", "highlighted"],
storage: [],
orgPage: {
main: {},
sidebar: {}
}
};
function init() {
//init passwordhash to retrieve cookie info and set passwordHash
passwordHash.initHash();
//check if user is logged in
if (passwordHash.verify()) {
//user logged in
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load settings from storage and apply
let settings = storeSettings("getInit", true);
if (settings != null) {
for (let setting of Object.entries(settings)) {
activeState.settings[setting[0]] = setting[1];
}
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version and storage mode to footer
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
//backup landing page
activeState.orgPage.sidebar = document.getElementById("sidebar");
activeState.orgPage.main = document.getElementById("mainForm");
}
function eventListeners() {
//add hideMenu to Body
document
.body
.addEventListener("click", (e) => hideMenus(e));
//add logo reset event
document
.getElementById("logo")
.addEventListener("click", resetPage);
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
/* document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu); */
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
inputRead.init();
window.addEventListener("keydown", (e) => {
if (activeState.activePage == "template") {
inputRead.read(e);
if (e.ctrlKey && e.key == "s") {
createStorageObj();
parseFormOnSubmit();
modalNotifier("File copied to clipboard", activeState.settings.notifierPause);
let copyButton = document.getElementById("fromCopyBtn");
copyButton.className.replace(" w3-grey", " w3-flat-carrot");
copyButton.value = "Copied";
e.preventDefault();
}
}
});
//add url listener
window.addEventListener("hashchange", (e) => {
let newURLArr = e.newURL.split("/");
let template;
if (newURLArr != undefined) {
template = newURLArr[newURLArr.length -1];
if (template != undefined) {
template = template.split("=")[1];
if (template != undefined) {
if (activeState.templates.includes("")) {
loadNewTemplate(template);
}
}
}
}
console.log(template);
});
}
init();

431
js/2.0.0/parseForm.js Normal file
View File

@ -0,0 +1,431 @@
import { sanitize } from "./scripts.js";
import { storeData, clearData, retrieveData } from "./storage.js";
function parseFormOnSubmit(returnJSON = false, parseOnly = false) {
//event.preventDefault;
let dataArray = [];
if (parseOnly) {
let lT = activeState.loadedTemplate;
dataArray = retrieveData("userInputForce", lT);
if (dataArray == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
let div = wrapper.firstChild;
return div;
}
if (dataArray.length <= 0) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("File empty");
let div = wrapper.firstChild;
return div;
}
} else {
let x = document.getElementById("mainFormObj");
if (x != null) {
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
}
//set filename to active state according to userFileName field from loadTemplate
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
} else if (userFileNamePH != null) {
activeState.fileName = userFileNamePH;
}
}
//get original objects from sessionstorage gen from loadTemplate
let objects = activeState.templateObjects;
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = activeState.fullString;
//define output buffer
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
//compaire each obj with elements from mainFormObj
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
//if obj is the connected list main selector
if (data.name.split("-")[0] == "clM") {
//if connected list main matches current object
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
//set flag for next iteration of loop
conListFlag = true;
data.name = data.name.substring(4);
//selection is not added to buffer
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
//if field matches current object
if (obj.word.replace(/ /g, "_") == data.name) {
let value = parseDataForResult(obj, data.value);
if (value == "!none") value = "";
obj.result = value;
}
//handle conlist elements for parsing each element
if (conListFlag && obj.type == "conList") {
let value = parseConListForResult(obj, data, dataArray);
if (value == "!none") value = "";
obj.result = value;
continue;
}
}
}
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
b +=
objects[i].result +
fullString.substring(objects[i].epos, objects[j].spos);
}
}
let bHtml = b.replace(/(?:\r\n|\r|\n)/g, "<br>");
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
bHtml = bHtml.replace(/ /g, "&nbsp;");
let divContent = document.createElement("div");
divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
divContent.style.fontSize = activeState.settings.fontSize;
divContent.innerHTML = bHtml;
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.appendChild(divContent);
if (parseOnly) {
return div;
}
storeData("userInput", dataArray);
clearData("userInput");
if (returnJSON) {
return dataArray;
} else {
copyToClipBoard(bHtml);
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
//parse global linebreak after marked text was already fixed
value = parseGlobalLineBreak(value);
return value;
}
function parseConListForResult(obj, data, dataArray) {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
}
}
return ""
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
if (dataArray[i] == "") continue;
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
continue;
}
//check if list indicator has been set and adjust userInput accordingly
let listIndicator = "";
if (listNumberFlag) {
listIndicator = " " + listNumberFlagNum + ". ";
listNumberFlagNum++;
}
if (listSubFlag && listIndicator == "") listIndicator = " ○ ";
if (listFlag && listIndicator == "") listIndicator = " • ";
//handle global linebreak and fit according to indicator according to list indicator
if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function parseGlobalLineBreak(data) {
//parse each line of input with parseLineBreak return condensed string with newlines
let parsedData = '';
for (let line of data.split('\n')) {
let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
if (parsedData != '') {
parsedData = parsedData + '\n' + parsedLine;
} else {
parsedData = parsedLine;
}
}
return parsedData
}
function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
//add 5 chars buffer to fix list intendation issue
//each input field gets parsed line by line twice once for list inputs and a second time for each input
let lines;
if (line.length > lineBreak) {
//create linebreak in between second to last word
let correctedLineBreak;
let newLineStart;
let cLBt = lineBreak-(intendation*2)
//find last space before linebreak
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
//and fix the next lines start
newLineStart = correctedLineBreak+1;
//add to parsed output
lines = line.substring(0, correctedLineBreak);
//delete first parsed output from inputstring
line = line.substring(newLineStart);
let intendationSpaces = '';
//check if an intendation is given if so convert it to correct spaces
if (intendation != 0) intendationSpaces = ' '.repeat(intendation);
//start loop to parse rest of the string
while(line.length > lineBreak) {
let cLBt = lineBreak-(intendation*2)
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
newLineStart = correctedLineBreak+1;
//add to output with intendation if given
lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
//delete from input
line = line.substring(newLineStart);
}
//process rest of the string with correct intendation
lines += "\n" + intendationSpaces + line;
} else {
//if string is within lineBreak just forward input to output
lines = line;
}
return lines;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function mainFormPlaceholder(msg) {
return "<div class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" + msg + "</p><br><br><br><br><br><br><br><br><br><br><br></div></div>";
}
export default parseFormOnSubmit;

388
js/2.0.0/parseTemplate.js Normal file
View File

@ -0,0 +1,388 @@
function parseInput(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//bugfix if the title of an input has no space in it ex: %test=l:first word;l:second word;%1
let oneWordFlag = false;
if (word.substring(0, 1) == "%" && word.indexOf('=') != -1) {
oneWordFlag = true;
}
//for loop to escape spaces in simple input
for (let j = i+1; j < wordArray.length; j++) {
//if title has no space then go back one word to include "=" ex:
if (oneWordFlag) {
j = i;
oneWordFlag = false;
} else {
w = w + " " + wordArray[j];
}
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseInput;

254
js/2.0.0/pell.js Normal file
View File

@ -0,0 +1,254 @@
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? factory(exports)
: typeof define === "function" && define.amd
? define(["exports"], factory)
: factory((globalThis.pell = {}));
})(this, function (exports) {
"use strict";
var _extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var defaultParagraphSeparatorString = "defaultParagraphSeparator";
var formatBlock = "formatBlock";
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
state: function state() {
return queryCommandState("bold");
},
result: function result() {
return exec("bold");
},
},
italic: {
icon: "<i>I</i>",
title: "Italic",
state: function state() {
return queryCommandState("italic");
},
result: function result() {
return exec("italic");
},
},
underline: {
icon: "<u>U</u>",
title: "Underline",
state: function state() {
return queryCommandState("underline");
},
result: function result() {
return exec("underline");
},
},
strikethrough: {
icon: "<strike>S</strike>",
title: "Strike-through",
state: function state() {
return queryCommandState("strikeThrough");
},
result: function result() {
return exec("strikeThrough");
},
},
heading1: {
icon: "<b>H<sub>1</sub></b>",
title: "Heading 1",
result: function result() {
return exec(formatBlock, "<h1>");
},
},
heading2: {
icon: "<b>H<sub>2</sub></b>",
title: "Heading 2",
result: function result() {
return exec(formatBlock, "<h2>");
},
},
paragraph: {
icon: "&#182;",
title: "Paragraph",
result: function result() {
return exec(formatBlock, "<p>");
},
},
quote: {
icon: "&#8220; &#8221;",
title: "Quote",
result: function result() {
return exec(formatBlock, "<blockquote>");
},
},
olist: {
icon: "&#35;",
title: "Ordered List",
result: function result() {
return exec("insertOrderedList");
},
},
ulist: {
icon: "&#8226;",
title: "Unordered List",
result: function result() {
return exec("insertUnorderedList");
},
},
code: {
icon: "&lt;/&gt;",
title: "Code",
result: function result() {
return exec(formatBlock, "<pre>");
},
},
line: {
icon: "&#8213;",
title: "Horizontal Line",
result: function result() {
return exec("insertHorizontalRule");
},
},
link: {
icon: "&#128279;",
title: "Link",
result: function result() {
var url = window.prompt("Enter the link URL");
if (url) exec("createLink", url);
},
},
image: {
icon: "&#128247;",
title: "Image",
result: function result() {
var url = window.prompt("Enter the image URL");
if (url) exec("insertImage", url);
},
},
};
var defaultClasses = {
actionbar: "pell-actionbar",
button: "pell-button",
content: "pell-content",
selected: "pell-button-selected",
};
var init = function init(settings) {
var actions = settings.actions
? settings.actions.map(function (action) {
if (typeof action === "string") return defaultActions[action];
else if (defaultActions[action.name])
return _extends({}, defaultActions[action.name], action);
return action;
})
: Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator =
settings[defaultParagraphSeparatorString] || "div";
var actionbar = createElement("div");
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = (settings.element.content = createElement("div"));
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3)
exec(formatBlock, "<" + defaultParagraphSeparator + ">");
else if (content.innerHTML === "<br>") content.innerHTML = "";
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (
event.key === "Enter" &&
queryCommandValue(formatBlock) === "blockquote"
) {
setTimeout(function () {
return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement("button");
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute("type", "button");
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? "add" : "remove"](
classes.selected
);
};
addEventListener(content, "keyup", handler);
addEventListener(content, "mouseup", handler);
addEventListener(button, "click", handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec("styleWithCSS");
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports["default"] = pell;
Object.defineProperty(exports, "__esModule", { value: true });
});
export default pell;

239
js/2.0.0/scripts.js Normal file
View File

@ -0,0 +1,239 @@
import { clearStorage, createStorageObj, retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
export const passwordHash = {
name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
toString: function () {
let token = window.activeState.sessionToken;
if (token == null) return "";
if (token == "") return "";
return XORCipher.decode(this.name, token);
},
set: function (pw) {
if (pw == "") return;
activeState.sessionToken = XORCipher.encode(this.name, pw);
},
initHash: function () {
//check if cookie exists
if (getCookie(sha256(this.name)) != null) {
if (getCookie(sha256(this.name)) != "") {
this.set(XORCipher.decode(sha256(this.name), getCookie(sha256(this.name))));
}
}
let verifiedStatus = false;
let tF = retrieveData("templateFiles");
if (tF != null) {verifiedStatus = true}
if (verifiedStatus == true) {
//set user id
activeState.userId = getUsrId();
setCookie(sha256(this.name), XORCipher.encode(sha256(this.name), this), 10);
}
},
verify: function () {
if (passwordHash == "") return false;
let verifiedStatus = false;
let tF = retrieveData("templateFiles");
if (tF != null) verifiedStatus = true
return verifiedStatus;
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = sanitize(x.elements[0].value);
if (pw != "" || pw !== "undefined") {
passwordHash.set(sha256(pw));
let tF = retrieveData("templateFiles");
if (tF == null) {
wrongPwAlert();
passwordHash.set("");
x.elements[0].value = "";
return;
}
//user logged in
//make sure to bring back persistent stat after logout
activeState.settings.persistentStorage = "true";
tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
activeState.settings.persistentStorage = "false";
}
document.getElementById("login").style.display = "none";
setCookie(sha256(passwordHash.name), XORCipher.encode(sha256(passwordHash.name), passwordHash), 10)
}
}
function wrongPwAlert() {
let wrongPWAlert = document.getElementById("wrongPWAlert");
wrongPWAlert.style.display = "block";
wrongPWAlert.addEventListener("click", (e) => {
if (e.target && e.target.tagName === "A") {
clearStorage();
document.getElementById("wrongPWAlert").innerHTML =
"<p>all files cleared - set new password</p>";
}
});
}
function cyrb53(str, seed = 21) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function getUsrId() {
const fingerprint = getBrowserFingerprint( { hardwareOnly: true } );
return cyrb53(fingerprint + passwordHash);
}
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
export function logout() {
let id = sha256(passwordHash.name);
activeState.sessionToken = "";
setCookie(sha256(passwordHash.name), "", 10);
document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.getElementById("passwordField").value = "";
document.getElementById("login").style.display = "block";
}
export function sanitize(string) {
const map = {
'&': '_',
'<': '_',
'>': '_',
'"': '_',
"'": '_',
'/': '_',
'`': '_',
'=': '_'
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
export function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
export const inputRead = {
init: function () {
this.event = "";
this.inputString = "";
this.source = "";
this.inputContent = "";
this.lastRunTime = new Date();
this.target = document.getElementById("toggleFilesMenu");
this.lastExecId = "";
},
read: function (event) {
this.event = event;
this.source = event.srcElement.id;
if (event.target.className == "pell-content") {
this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
}
let previousContent = this.inputContent;
let key = (event.key !=undefined) ? event.key : "";
let contentElement = document.getElementById(this.source);
this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
if (this.inputContent == "" || key == "") return;
if (key.length > 1) return;
if (event.ctrlKey) return;
if (this.inputContent == previousContent) return;
this.lastRunTime = new Date();
clearTimeout(this.lastExecId);
this.target.style.borderBottom = "3px solid #c0392b";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-save");
this.target.appendChild(i);
this.lastExecId = setTimeout(() => {
createStorageObj();
this.target.style.borderBottom = "none";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
this.target.appendChild(i);
}, 1000);
},
}
export function getCurrentDate() {
let date = new Date();
let uts = Date.now();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
let current_second = date.getSeconds();
current_second = current_second <= 9 ? "0" + current_second : current_second;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_day = date.getDate();
current_day = current_day <= 9 ? "0" + current_day : current_day;
let current_year = date.getFullYear();
let current_time = current_hour + ":" + current_minute;
let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
let current_date = current_day + "." + current_month;
return {
current_time: current_time,
current_time_long: current_time_long,
current_date: current_date,
current_year: current_year,
uts: uts
};
}
export default setPassword;

210
js/2.0.0/settings.js Normal file
View File

@ -0,0 +1,210 @@
import { hideMenus, modalNotifier, printVersion, resetNavBar } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
import { retrieveData, storeData, storeSettings } from "./storage.js";
const buildSettings = () => {
//set current page value in activeState object
activeState.activePage = "settings";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Settings";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
addSidebar();
buildForm();
//add events
formEvts();
};
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
saveSettings();
modalNotifier(
"Settings saved!",
activeState.settings.notifierPause
);
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-nephritis"
);
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-nephritis",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
}
function buildForm() {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let settings = storeSettings("get", true);
if (settings == "") settings = activeState.settings;
for (let setting of Object.entries(settings)) {
buildField(setting, form);
}
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
}
function buildField(obj, form) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj[0]);
input.setAttribute("id", obj[0]);
input.classList.add("w3-input");
input.id = obj[0];
input.value = obj[1];
label.innerHTML = obj[0];
div.appendChild(label);
div.appendChild(input);
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
}
function addSidebar() {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Edit Settings"
sidebarList.appendChild(sidebarListItem);
document.getElementById("sidebar").appendChild(sidebarList);
}
function saveSettings() {
let x = document.getElementById("mainFormObj");
let obj = {};
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
let name = x.elements[i].name;
let value = x.elements[i].value;
obj[name] = sanitize(value);
}
for (let setting of Object.entries(obj)) {
if (activeState.settings[setting[0]] != setting[1]) {
//change detected
if (setting[0] == "persistentStorage") {
//get tF from old storage
let tF = retrieveData("templateFiles");
//get previous settings
let settings = storeSettings("get", true);
//store the new settings in old storage
storeSettings(obj);
//apply the new setting
activeState.settings[setting[0]] = setting[1];
//store the new settings in the new storage
if (settings != "") storeSettings(obj);
//transfer tF
if (tF != null) storeData("templateFiles", tF);
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
}
}
activeState.settings[setting[0]] = setting[1];
}
storeSettings(obj);
}
export default buildSettings;

3
js/2.0.0/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

291
js/2.0.0/storage.js Normal file
View File

@ -0,0 +1,291 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { getCurrentDate, passwordHash, sanitize } from "./scripts.js";
const store = {
getItem: function (key) {return getStor().getItem(sha256(key+activeState.userId))},
setItem: function (key, data) {getStor().setItem(sha256(key+activeState.userId), data)},
removeItem: function (key) {getStor().removeItem(sha256(key+activeState.userId))},
clear: function () {getStor().clear()},
};
const tempStore = {
setItem: function (key, data) {
globalThis.activeState.storage[key] = data;
},
getItem: function (key) {
return globalThis.activeState.storage[key];
},
removeItem: function (key) {
globalThis.activeState.storage[key] = "";
},
clear: function () {
globalThis.activeState.storage = [];
},
};
function getStor() {
if (window.activeState.settings.persistentStorage == "true") {
return window.localStorage;
} else {
return tempStore;
}
}
function createStorageObj() {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//console.log(this, dataArray);
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
storeData("userInput", dataArray, "save");
}
function storeData(name, data, ref) {
if (passwordHash == "") return;
data = JSON.stringify(data);
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName(ref);
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = sha256(name + "_m21_" + lT);
if (name == "templateFiles") {
key = sha256(name + "_m21_" + activeState.userId);
}
store.setItem(key, obfuscate(data));
}
function retrieveData(name, template = "none") {
if (passwordHash == "") return null;
if (name == "userInput") {
let tF = retrieveData("templateFiles");
if (tF == null) {
return [];
} else {
name = tF[tF.length - 1].fileName;
}
}
if (name == "userInputForce") {
name = "userInput";
}
let cdata;
let key;
if (template == "none") {
let lT = activeState.loadedTemplate;
key = sha256(name + "_m21_" + lT);
if (name == "templateFiles") {
key = sha256(name + "_m21_"+activeState.userId);
}
} else {
key = sha256(name + "_m21_" + template);
}
cdata = store.getItem(key);
if (cdata != null) {
cdata = obfuscate(cdata, false);
let data;
try {
data = JSON.parse(cdata);
} catch (e) {
data = null;
}
return data;
} else {
return [];
}
}
function clearData(name, template = "none") {
let lT;
let key;
if (template == "none") {
lT = activeState.loadedTemplate;
key = sha256(name + "_m21_" + lT);
if (name == "templateFiles") {
key = sha256(name + "_m21_"+activeState.userId);
}
} else {
lT = template;
key = sha256(name + "_m21_" + template);
}
store.removeItem(key);
}
function getFileName(ref = "none") {
let currentFileName = activeState.fileName;
let lT = activeState.loadedTemplate;
if (currentFileName == "none" || currentFileName == "") {
let date = getCurrentDate();
currentFileName = date.current_time + "_" + date.current_date + " " + lT;
//console.log(currentFileName);
}
let tF = retrieveData("templateFiles");
const metadata = {
ts_create: getCurrentDate(),
ts_save: "",
id: sha256(currentFileName),
};
if (tF.length != 0) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {
tFi.metadata.ts_save = getCurrentDate();
return currentFileName;
}
}
tF.push({
fileName: currentFileName,
template: lT,
metadata: metadata,
pos: tF.length - 1,
});
} else {
tF = [
{ fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
];
}
storeData("templateFiles", tF);
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if (data == null | data == "") return "";
if (mode) {
return XORCipher.encode(sha256(passwordHash), data);
} else {
return XORCipher.decode(sha256(passwordHash), data);
}
}
function popFromTemplateFiles(fileName) {
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
}
function createBookShelf() {
let tF = retrieveData("templateFiles");
let bookShelf = {};
let date = getCurrentDate();
let saveFileName = date.current_time + "_" + date.current_date;
if (tF != null) {
bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
if (activeState.settings.localOnly == "true") {
bookShelf[i].data = data;
} else {
bookShelf[i].data = obfuscate(data);
}
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
store.setItem(sha256(file.name), file.data);
templateFilesArray.push({
fileName: file.name.split("_m21_")[0],
template: file.name.split("_m21_")[1],
});
}
store.setItem(
sha256("templateFiles_m21_"+activeState.userId),
obfuscate(JSON.stringify(templateFilesArray))
);
}
}
};
xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
xhttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhttp.send();
}
function storeSettings(data, get = false) {
let key = sha256("settings_m21_"+activeState.userId);
if (get) {
let cdata = "";
if (data == "getInit") {activeState.settings.persistentStorage = "true"}
try {
cdata = JSON.parse(obfuscate(store.getItem(key), false));
} catch (e) {
cdata = "";
}
if (data == "getInit") {activeState.settings.persistentStorage = "false"};
return cdata;
} else {
store.setItem(key, obfuscate(JSON.stringify(data)));
}
}
function clearStorage() {
store.clear();
}
export {
createStorageObj,
storeData,
retrieveData,
clearData,
getFileName,
createBookShelf,
importBookShelf,
storeSettings,
clearStorage
};

361
js/2.0.0/web.js Normal file
View File

@ -0,0 +1,361 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName } from "./storage.js";
import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { logout, passwordHash } from "./scripts.js";
import buildSettings from "./settings.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
}
if (cdata != "") {
if (cdata != null) {
retrieveForm(cdata);
}
}
//select first object and focus on it
let obj = activeState.templateObjectsPurified;
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//reset navbar above all else
resetNavBar();
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText);
return;
}
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "javascript:void(0)");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!settings");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Settings";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!logout");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
createEntry.innerHTML = "Logout";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
e.preventDefault;
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "!createNew") {
createTemplate();
return;
}
if (template == "!logout") {
logout();
return;
}
if (template == "!settings") {
buildSettings();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText)
return;
}
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
if (res[x][1].length < 1) continue;
let aReg = document.createElement("a");
aReg.setAttribute("href", "javascript:void(0)");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: formData,
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
let e = document.getElementById(arr[i].name);
if (e === null) {
//parse connected list
let id = arr[i].name.split("cl-")[1];
//escape cl-text:!ls
if (id != undefined) id = id.split(":")[0];
e = document.getElementById(id);
if (e === null) {
//parse connected list main
let id = arr[i].name.split("clM-")[1];
e = document.getElementById(id);
if (e === null) continue;
}
}
//handle connected list Main item button or list
if (e.name.substr(0, 4) == "clM-") {
if (arr[i].value != "!none") {
let clElement = document.getElementById(e.dataset.word);
if (clElement === null) {
clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
}
//make shure it is visible if selected before
if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
e.value = arr[i].value;
}
continue;
}
switch (e.nodeName) {
case "TEXTAREA":
if (e.parentElement != undefined) {
if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
e.innerHTML = arr[i].value;
e = e.parentElement.getElementsByClassName("pell-content")[0];
}
}
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

187
js/2.0.0/xorc.js Normal file
View File

@ -0,0 +1,187 @@
const XORCipher = {
encode: function (key, data, seed) {
data = xor_encrypt(key, data, seed);
return b64_encode(data);
},
decode: function (key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
},
seed: function (n) {
return randString(n);
},
};
function stringToUtf8ByteArray(str) {
var out = [],
p = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) == 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return out;
}
function utf8ByteArrayToString(bytes) {
// array of bytes
var out = [],
pos = 0,
c = 0;
while (pos < bytes.length) {
var c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
var c2 = bytes[pos++];
out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
} else if (c1 > 239 && c1 < 365) {
// Surrogate Pair
var c2 = bytes[pos++];
var c3 = bytes[pos++];
var c4 = bytes[pos++];
var u =
(((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
0x10000;
out[c++] = String.fromCharCode(0xd800 + (u >> 10));
out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
} else {
var c2 = bytes[pos++];
var c3 = bytes[pos++];
out[c++] = String.fromCharCode(
((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
}
}
return out.join("");
}
var b64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function b64_encode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = (o1 << 16) | (o2 << 8) | o3;
h1 = (bits >> 18) & 0x3f;
h2 = (bits >> 12) & 0x3f;
h3 = (bits >> 6) & 0x3f;
h4 = bits & 0x3f;
enc +=
b64_table.charAt(h1) +
b64_table.charAt(h2) +
b64_table.charAt(h3) +
b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
}
function b64_decode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = b64_table.indexOf(data.charAt(i++));
h2 = b64_table.indexOf(data.charAt(i++));
h3 = b64_table.indexOf(data.charAt(i++));
h4 = b64_table.indexOf(data.charAt(i++));
bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
o1 = (bits >> 16) & 0xff;
o2 = (bits >> 8) & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randString(n) {
var r = "";
for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
return r;
}
function xor_encrypt(key, data, seed) {
if (typeof seed == "undefined") seed = randString(32);
var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
return r;
}
function xor_decrypt(key, data) {
var d = data,
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
r.splice(0, r.indexOf(0) + 1);
return utf8ByteArrayToString(r);
}
export default XORCipher;

477
js/2.0.1/buildForm.js Normal file
View File

@ -0,0 +1,477 @@
import { getFileName } from "./storage.js";
import pell from "./pell.js"
function transformTemplateObject(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//console.log(objects);
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//create sidebar set form button
let sidebarSetFormButton = document.createElement("li");
sidebarSetFormButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSetFormButton.style.borderTop = "2px solid #ddd";
sidebarSetFormButton.id = "sb-setform";
sidebarSetFormButton.innerHTML = "Set input as preset";
sidebarList.appendChild(sidebarSetFormButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
copyBtn.id = "fromCopyBtn";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = connectedListsArray[0].word;
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
label = document.createElement("LABEL");
label.innerHTML = '';
//div.classList.add("w3-center");
div.classList.replace("w3-flat-silver", "w3-flat-clouds");
div.appendChild(label);
div.appendChild(select3);
} else {
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
}
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
divContainer.classList.add("w3-animate-opacity")
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
sidebarList.appendChild(sidebarListItem);
}
function buildLongTextInput(source, textarea, label) {
if (activeState.settings.enablePell == "false") return;
//hide default textarea
textarea.style.display = "none";
label.style.display = "none";
let title = document.createElement("b");
title.innerText = label.innerText;
const editor = pell.init({
element: source,
defaultParagraphSeparator: "div",
actions: [
"bold",
"italic",
"underline",
"strikethrough",
"paragraph",
"heading1",
"heading2",
{
name: 'ulist',
icon: 'L'
},
"olist"
],
onChange: function (html) {
//correct lastElement
activeState.lastElement = textarea.id;
textarea.value = html;
},
});
let actionBar = editor.getElementsByClassName("pell-actionbar")[0];
let content = editor.getElementsByClassName("pell-content")[0];
let actionBarElements = actionBar.getElementsByClassName("pell-button");
let newActionBarElements = [];
for (let actionBarElement of actionBarElements ) {
actionBarElement.classList.add("w3-right");
actionBarElement.setAttribute("tabindex","-1");
newActionBarElements.push(actionBarElement);
}
//reverse actionbar back to org order
actionBar.innerHTML = "";
for (let newActionBarElement of newActionBarElements.reverse()) {
actionBar.appendChild(newActionBarElement);
}
actionBar.classList.add("w3-container");
actionBar.style.paddingLeft = "0px";
actionBar.appendChild(title);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default transformTemplateObject;

208
js/2.0.1/createTemplate.js Normal file
View File

@ -0,0 +1,208 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { hideMenus, modalNotifier, resetNavBar } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus("force");
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
if (!templates.includes('_textBlocks')) {
templates.push('_textBlocks');
}
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", activeState.settings.notifierPause);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

284
js/2.0.1/evts.js Normal file
View File

@ -0,0 +1,284 @@
import { passwordHash } from "./scripts.js";
import { clearData, createBookShelf, importBookShelf } from "./storage.js";
import {
loadTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer,
} from "./web.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += " " + insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
if (element.parentElement != undefined) {
if (
element.parentElement.getElementsByClassName("pell-content")[0] !=
undefined
) {
element.parentElement.getElementsByClassName(
"pell-content"
)[0].innerHTML = element.value;
element = element.parentElement.getElementsByClassName("pell-content")[0];
}
}
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
//createStorageObj();
}
function clickClearForm() {
//document.activeElement.blur();
//document.getElementById("sidebar").focus();
clearData("userInput");
let lT = activeState.loadedTemplate;
loadTemplate(lT);
}
function hideMenus(evt) {
if (evt === undefined) return;
if (evt != "force" && evt.target.parentElement != null) {
if (evt.target.parentElement.id == "navMob") return;
if (evt.target.parentElement.id == "navReg") return;
if (evt.target.parentElement.parentElement != null) {
if (evt.target.parentElement.parentElement.id == "navMob") return;
if (evt.target.parentElement.parentElement.id == "navReg") return;
}
}
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout = 3, closeable = true) {
let modalElement = document.getElementById("modalNotifier");
let modalElementCloseBtn = document.getElementById("modalNotifierClose");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
if (!closeable) modalElementCloseBtn.style.display = "none";
msgElement.innerHTML = msg;
if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function printVersion(msg = "") {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length - 2];
//add it to document footer currentVersion
versionSpan.textContent = msg + " version: " + pathVersion;
}
}
}
function clickImportFiles() {
if (activeState.settings.localOnly == "true") {
createBookShelfDownload();
return;
}
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Imported!",
activeState.settings.notifierPause
);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display =
"none";
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: " +
activeState.serverFilesTs.replace("_", " - ") +
"<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0
);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
activeState.userId +
".txt' style='text-decoration: underline;' download>download</a> them?",
0
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0
);
}
function createBookShelfDownload() {
let data = createBookShelf();
let filename = data[0]["data"] + ".txt";
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," +
encodeURIComponent(JSON.stringify(data))
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
modalNotifier(
"Since you are in local only mode you can only export a backup of your files \
<br><br> \
<div class='w3-container'> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Export</button></div>",
0
);
}
function resetNavBar() {
//enable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "";
//enable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "block";
}
function wrongPwAlert() {
let wrongPWAlert = document.getElementById("wrongPWAlert");
wrongPWAlert.style.display = "block";
wrongPWAlert.addEventListener("click", (e) => {
if (e.target && e.target.tagName === "A") {
clearStorage();
document.getElementById("wrongPWAlert").innerHTML =
"<p>all files cleared - set new password</p>";
}
});
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
clickClearForm,
modalNotifier,
clickImportFiles,
resetNavBar,
printVersion,
wrongPwAlert
};

470
js/2.0.1/files.js Normal file
View File

@ -0,0 +1,470 @@
import {
storeData,
clearData,
retrieveData,
} from "./storage.js";
import { loadTemplate } from "./web.js";
import parseFormOnSubmit from "./parseForm.js";
import { modalNotifier, resetNavBar } from "./evts.js";
import { passwordHash } from "./scripts.js";
function buildFile() {
//set current page value in activeState object
activeState.activePage = "files";
//set templateFiles array
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
//console.log("none yet");
modalNotifier("there are no saved texts yet", activeState.settings.notifierPause);
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Saved files";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//disable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = 'background-color:#9e9e9e !important';
target.style.borderBottom = "4px solid #9e9e9e";
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
let fileInfoDiv = document.getElementById("outputInfo");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
fileInfoDiv.innerHTML = "";
fileInfoDiv.replaceWith(fileInfoDiv.cloneNode(true));
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
let target = e.target.parentElement;
if (e.target.matches("li.w3-bar-item")) target = e.target;
if (target.classList.contains("w3-bar-item")) {
let fileName = target.dataset.file;
let template = target.dataset.template;
let pos = target.dataset.tfpos;
clickLoadFileDiv(fileName, template, pos);
}
});
}
function loadFileDiv(fileName, template, pos) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
//append TS info
let fileInfoDiv = document.getElementById("outputInfo");
let tF = retrieveData("templateFiles");
let ts = tF[pos].metadata.ts_create;
ts = ts.current_time_long+" "+ts.current_date+"."+ts.current_year;
fileInfoDiv.innerHTML = "<p>created at: "+ts+" | template: "+template+"</p>";
fileInfoDiv.style.display = "block";
}
function loadFileDivCallBack() {
let tF = retrieveData("templateFiles");
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "_m21_" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-flat-pomegranate");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
let parsedTemplate = parseFormOnSubmit(false, true);
div.appendChild(parsedTemplate);
fileDisplay.appendChild(div);
let ts = document.createElement("p");
ts.innerHTML = ""
//fileDisplay.appendChild(ts);
document.getElementById("mainForm").appendChild(fileDisplay);
//fix min height of file display
try {
document.getElementById("fileDisplay").style.cssText = "min-height: 300px;";
} catch (e) {}
//fix fontsize for display
try {
document.getElementById("fileDisplay").firstChild.style.fontSize = "1em";
} catch (e) {}
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template, pos) {
if (fileName == "_overflow") return;
if (fileName == "_clearAll") {
clickClearAllFiles();
return;
}
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template, pos);
}
function clearFileData(storData) {
let fileName = storData.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
clearData(fileName);
clearData("userInput");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-padding-large",
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Saved Files:"
sidebarList.appendChild(sidebarListItem);
let c = 0;
let sidebarItemsAmount = 10;
for (let obj of tF.reverse()) {
console.log(obj);
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
//handle to many files on screen and display hidden files amount
if (c > sidebarItemsAmount) {
sidebarListItem.setAttribute("data-template", "_overflow");
sidebarListItem.setAttribute("data-file", "_overflow");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML =
tF.length - sidebarItemsAmount + " files not shown";
sidebarList.appendChild(sidebarListItem);
break;
}
let sidebarListItemTitle = document.createElement("p");
sidebarListItemTitle.innerText = obj.fileName.replace(/_/g, " ");
sidebarListItemTitle.style.cssText = "margin: 0;"
let sidebarListItemInfo = document.createElement("span");
sidebarListItemInfo.classList.add("w3-small");
sidebarListItemInfo.innerText = "created at: "
+obj.metadata.ts_create.current_time
+" - "
+obj.metadata.ts_create.current_date;
sidebarListItem.appendChild(sidebarListItemTitle);
sidebarListItem.append(sidebarListItemInfo);
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarListItem.setAttribute("data-tFPos", obj.pos);
sidebarList.appendChild(sidebarListItem);
c++;
}
//clear all files button
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button");
sidebarListItem.setAttribute("data-template", "_clearAll");
sidebarListItem.setAttribute("data-file", "_clearAll");
sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.style.width = "300px";
sidebarListItem.innerHTML = "Clear all files";
sidebarList.appendChild(sidebarListItem);
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return (
"<div id='fileDisplay' class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" +
msg +
"</p><br><br><br><br><br><br><br><br><br><br><br></div></div>"
);
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
editSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-carrot"
);
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-carrot",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
break;
case "Delete":
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
let delFileName = activeState.fileName;
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(previousFile.fileName, previousFile.template, previousFile.pos);
} else {
document.getElementById("mainForm").innerHTML =
mainFormPlaceholder("No file yet");
}
modalNotifier(delFileName + " deleted!", activeState.settings.notifierPause);
break;
default:
e.preventDefault;
}
}
});
}
function editSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("_m21_")[0], storageName.split("_m21_")[1])
);
//reset sidebar to clear events
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
//reset navbar above all else
resetNavBar();
//reset correct activePage
activeState.activePage = "template";
loadTemplate(storageName.split("_m21_")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i - 1];
if (previousFile === undefined) {
//get the next one if there is no previous one
previousFile = tF[i + 1];
}
break;
}
i++;
}
return previousFile != undefined ? previousFile : false;
}
function clickClearAllFiles() {
let modal = document.getElementById("modalMsg");
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Delete":
clearAllFiles();
modal.replaceWith(modal.cloneNode(true));
modalNotifier("All files deleted!", activeState.settings.notifierPause);
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
<p>Would you really like to delete all stored files?</p> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button>",
0
);
}
function clearAllFiles() {
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
modalNotifier("there are no saved texts yet", activeState.settings.notifierPause);
return;
}
for (let storageName of tF) {
clearFileData(storageName.fileName);
}
}
export { buildFile, loadFileDivCallBack };

303
js/2.0.1/form.js Normal file
View File

@ -0,0 +1,303 @@
import { storeData, createStorageObj } from "./storage.js";
import parseInput from "./parseTemplate.js";
import transformTemplateObject from "./buildForm.js";
import { handleOnBlur, modalNotifier } from "./evts.js";
import parseFormOnSubmit, { parseTextMarkups } from "./parseForm.js";
import { setTemplatePreset } from "./web.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
let placeholder;
try {
placeholder = JSON.parse(jsonPlaceholder);
} catch (e) {
placeholder = ""
}
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", placeholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseInput Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseInput(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
activeState.templateObjects = objects;
activeState.fullString = templateInput;
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
activeState.templateObjectsPurified = objectsPurified;
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
//sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) {return};
transformTemplateObject(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj();
parseFormOnSubmit();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
e.target.value = "Copied";
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
const timeoutCopy = setTimeout(() => {
//e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
//e.target.value = "Copy";
e.target.style.pointerEvents = "auto";
}, 5000);
break;
case "Save":
createStorageObj();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause);
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
parseFormOnSubmit();
modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause);
}
if (e.target.id == "sb-setform") {
let dataArray = parseFormOnSubmit(true);
let lT = activeState.loadedTemplate;
setTemplatePreset(lT, JSON.stringify(dataArray));
modalNotifier("Input saved as preset", activeState.settings.notifierPause);
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener to each form object
let mainForm = document.getElementById("mainFormObj");
for (let formElement of mainForm.children) {
let id = formElement.firstChild.lastChild.id;
document.getElementById(id).addEventListener("blur", (e) => {
e.preventDefault;
handleOnBlur(e.target);
});
}
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
//handle pell content focus
if (targetElement.parentElement != undefined) {
if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0];
}
}
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/2.0.1/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

178
js/2.0.1/init.js Normal file
View File

@ -0,0 +1,178 @@
import {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
clickImportFiles,
modalNotifier,
printVersion
} from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, {
passwordHash,
inputRead
} from "./scripts.js";
import parseFormOnSubmit from "./parseForm.js";
import { createStorageObj, storeSettings } from "./storage.js";
import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js";
window.activeState = {
userId: "",
sessionToken: "",
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
settings: {
localOnly: "true",
lineBreak: 120,
font: "Arial",
fontSize: "10px",
notifierPause: 1,
persistentStorage: "false",
enablePell: "false",
debug: "false"
},
templates: [],
templateObjectsPurified: [],
templateObjects: [],
fullString: "",
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
],
markups: ["title", "link", "italic", "green_highlighted", "highlighted"],
storage: [],
orgPage: {
main: {},
sidebar: {}
}
};
function init() {
//init passwordhash to retrieve cookie info and set passwordHash
passwordHash.initHash();
//check if user is logged in
if (passwordHash.verify()) {
//user logged in
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load settings from storage and apply
let settings = storeSettings("getInit", true);
if (settings != null) {
for (let setting of Object.entries(settings)) {
activeState.settings[setting[0]] = setting[1];
}
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version and storage mode to footer
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
//backup landing page
activeState.orgPage.sidebar = document.getElementById("sidebar");
activeState.orgPage.main = document.getElementById("mainForm");
}
function eventListeners() {
//add hideMenu to Body
document
.body
.addEventListener("click", (e) => hideMenus(e));
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
/* document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu); */
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
inputRead.init();
window.addEventListener("keydown", (e) => {
if (activeState.activePage == "template") {
inputRead.read(e);
if (e.ctrlKey && e.key == "s") {
createStorageObj();
parseFormOnSubmit();
modalNotifier("File copied to clipboard", activeState.settings.notifierPause);
let copyButton = document.getElementById("fromCopyBtn");
copyButton.className = "w3-button w3-flat-carrot";
copyButton.value = "Copied";
e.preventDefault();
}
}
});
//add url listener
window.addEventListener("hashchange", (e) => {
let newURLArr = e.newURL.split("/");
let template;
if (newURLArr != undefined) {
template = newURLArr[newURLArr.length -1];
if (template != undefined) {
template = template.split("=")[1];
if (template != undefined) {
if (activeState.templates.includes("")) {
loadNewTemplate(template);
}
}
}
}
});
}
init();

445
js/2.0.1/parseForm.js Normal file
View File

@ -0,0 +1,445 @@
import { sanitize } from "./scripts.js";
import { storeData, clearData, retrieveData } from "./storage.js";
function parseFormOnSubmit(returnJSON = false, parseOnly = false) {
//event.preventDefault;
let dataArray = [];
if (parseOnly) {
let lT = activeState.loadedTemplate;
dataArray = retrieveData("userInputForce", lT);
if (dataArray == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
let div = wrapper.firstChild;
return div;
}
if (dataArray.length <= 0) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("File empty");
let div = wrapper.firstChild;
return div;
}
} else {
let x = document.getElementById("mainFormObj");
if (x != null) {
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
}
//set filename to active state according to userFileName field from loadTemplate
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
} else if (userFileNamePH != null) {
activeState.fileName = userFileNamePH;
}
}
//get original objects from sessionstorage gen from loadTemplate
let objects = activeState.templateObjects;
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = activeState.fullString;
//define output buffer
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
//compaire each obj with elements from mainFormObj
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
//if obj is the connected list main selector
if (data.name.split("-")[0] == "clM") {
//if connected list main matches current object
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
//set flag for next iteration of loop
conListFlag = true;
data.name = data.name.substring(4);
//selection is not added to buffer
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
//if field matches current object
if (obj.word.replace(/ /g, "_") == data.name) {
let value = parseDataForResult(obj, data.value);
if (value == "!none") value = "";
obj.result = value;
}
//handle conlist elements for parsing each element
if (conListFlag && obj.type == "conList") {
let value = parseConListForResult(obj, data, dataArray);
if (value == "!none") value = "";
obj.result = value;
continue;
}
}
}
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
b +=
objects[i].result +
fullString.substring(objects[i].epos, objects[j].spos);
}
}
//sanitizing
let bHtml = b;
bHtml = bHtml.replace(/ /g, "&nbsp;");
bHtml = bHtml.replace(/(?:\r\n|\r|\n)/g, "<br />");
bHtml = bHtml.replace(/<\/div>/g, '<br />');
bHtml = bHtml.replace(/<div>/g, '');
if (activeState.settings.enablePell == "true") {
bHtml = bHtml.replace(/!l /g, "");
bHtml = bHtml.replace(/!n /g, "");
bHtml = bHtml.replace(/!ls /g, "");
} else {
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
}
let divContent = document.createElement("div");
divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
divContent.style.fontSize = activeState.settings.fontSize;
divContent.innerHTML = bHtml;
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.appendChild(divContent);
if (parseOnly) {
return div;
}
storeData("userInput", dataArray);
clearData("userInput");
if (returnJSON) {
return dataArray;
} else {
copyToClipBoard(bHtml);
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
//parse global linebreak after marked text was already fixed
value = parseGlobalLineBreak(value);
return value;
}
function parseConListForResult(obj, data, dataArray) {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
}
}
return ""
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
if (dataArray[i] == "") continue;
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
continue;
}
//check if list indicator has been set and adjust userInput accordingly
let listIndicator = "";
if (listNumberFlag) {
listIndicator = " " + listNumberFlagNum + ". ";
listNumberFlagNum++;
}
if (listSubFlag && listIndicator == "") listIndicator = " ○ ";
if (listFlag && listIndicator == "") listIndicator = " • ";
//exclude settings if pell is enabled
if (activeState.settings.enablePell == "true") listIndicator = "";
//handle global linebreak and fit according to indicator according to list indicator
if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function parseGlobalLineBreak(data) {
//parse each line of input with parseLineBreak return condensed string with newlines
let parsedData = '';
for (let line of data.split('\n')) {
let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
if (parsedData != '') {
parsedData = parsedData + '\n' + parsedLine;
} else {
parsedData = parsedLine;
}
}
return parsedData
}
function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
//add 5 chars buffer to fix list intendation issue
//each input field gets parsed line by line twice once for list inputs and a second time for each input
let lines;
if (line.length > lineBreak) {
//create linebreak in between second to last word
let correctedLineBreak;
let newLineStart;
let cLBt = lineBreak-(intendation*2)
//find last space before linebreak
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
//and fix the next lines start
newLineStart = correctedLineBreak+1;
//add to parsed output
lines = line.substring(0, correctedLineBreak);
//delete first parsed output from inputstring
line = line.substring(newLineStart);
let intendationSpaces = '';
//check if an intendation is given if so convert it to correct spaces
if (intendation != 0) intendationSpaces = ' '.repeat(intendation);
//start loop to parse rest of the string
while(line.length > lineBreak) {
let cLBt = lineBreak-(intendation*2)
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
newLineStart = correctedLineBreak+1;
//add to output with intendation if given
lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
//delete from input
line = line.substring(newLineStart);
}
//process rest of the string with correct intendation
lines += "\n" + intendationSpaces + line;
} else {
//if string is within lineBreak just forward input to output
lines = line;
}
return lines;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function mainFormPlaceholder(msg) {
return "<div class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" + msg + "</p><br><br><br><br><br><br><br><br><br><br><br></div></div>";
}
export default parseFormOnSubmit;

388
js/2.0.1/parseTemplate.js Normal file
View File

@ -0,0 +1,388 @@
function parseInput(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//bugfix if the title of an input has no space in it ex: %test=l:first word;l:second word;%1
let oneWordFlag = false;
if (word.substring(0, 1) == "%" && word.indexOf('=') != -1) {
oneWordFlag = true;
}
//for loop to escape spaces in simple input
for (let j = i+1; j < wordArray.length; j++) {
//if title has no space then go back one word to include "=" ex:
if (oneWordFlag) {
j = i;
oneWordFlag = false;
} else {
w = w + " " + wordArray[j];
}
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseInput;

254
js/2.0.1/pell.js Normal file
View File

@ -0,0 +1,254 @@
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? factory(exports)
: typeof define === "function" && define.amd
? define(["exports"], factory)
: factory((globalThis.pell = {}));
})(this, function (exports) {
"use strict";
var _extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var defaultParagraphSeparatorString = "defaultParagraphSeparator";
var formatBlock = "formatBlock";
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
state: function state() {
return queryCommandState("bold");
},
result: function result() {
return exec("bold");
},
},
italic: {
icon: "<i>I</i>",
title: "Italic",
state: function state() {
return queryCommandState("italic");
},
result: function result() {
return exec("italic");
},
},
underline: {
icon: "<u>U</u>",
title: "Underline",
state: function state() {
return queryCommandState("underline");
},
result: function result() {
return exec("underline");
},
},
strikethrough: {
icon: "<strike>S</strike>",
title: "Strike-through",
state: function state() {
return queryCommandState("strikeThrough");
},
result: function result() {
return exec("strikeThrough");
},
},
heading1: {
icon: "<b>H<sub>1</sub></b>",
title: "Heading 1",
result: function result() {
return exec(formatBlock, "<h1>");
},
},
heading2: {
icon: "<b>H<sub>2</sub></b>",
title: "Heading 2",
result: function result() {
return exec(formatBlock, "<h2>");
},
},
paragraph: {
icon: "&#182;",
title: "Paragraph",
result: function result() {
return exec(formatBlock, "<p>");
},
},
quote: {
icon: "&#8220; &#8221;",
title: "Quote",
result: function result() {
return exec(formatBlock, "<blockquote>");
},
},
olist: {
icon: "&#35;",
title: "Ordered List",
result: function result() {
return exec("insertOrderedList");
},
},
ulist: {
icon: "&#8226;",
title: "Unordered List",
result: function result() {
return exec("insertUnorderedList");
},
},
code: {
icon: "&lt;/&gt;",
title: "Code",
result: function result() {
return exec(formatBlock, "<pre>");
},
},
line: {
icon: "&#8213;",
title: "Horizontal Line",
result: function result() {
return exec("insertHorizontalRule");
},
},
link: {
icon: "&#128279;",
title: "Link",
result: function result() {
var url = window.prompt("Enter the link URL");
if (url) exec("createLink", url);
},
},
image: {
icon: "&#128247;",
title: "Image",
result: function result() {
var url = window.prompt("Enter the image URL");
if (url) exec("insertImage", url);
},
},
};
var defaultClasses = {
actionbar: "pell-actionbar",
button: "pell-button",
content: "pell-content",
selected: "pell-button-selected",
};
var init = function init(settings) {
var actions = settings.actions
? settings.actions.map(function (action) {
if (typeof action === "string") return defaultActions[action];
else if (defaultActions[action.name])
return _extends({}, defaultActions[action.name], action);
return action;
})
: Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator =
settings[defaultParagraphSeparatorString] || "div";
var actionbar = createElement("div");
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = (settings.element.content = createElement("div"));
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3)
exec(formatBlock, "<" + defaultParagraphSeparator + ">");
else if (content.innerHTML === "<br>") content.innerHTML = "";
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (
event.key === "Enter" &&
queryCommandValue(formatBlock) === "blockquote"
) {
setTimeout(function () {
return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement("button");
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute("type", "button");
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? "add" : "remove"](
classes.selected
);
};
addEventListener(content, "keyup", handler);
addEventListener(content, "mouseup", handler);
addEventListener(button, "click", handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec("styleWithCSS");
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports["default"] = pell;
Object.defineProperty(exports, "__esModule", { value: true });
});
export default pell;

216
js/2.0.1/scripts.js Normal file
View File

@ -0,0 +1,216 @@
import { createStorageObj, retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
import { wrongPwAlert } from "./evts.js";
export const passwordHash = {
name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
toString: function () {
let token = window.activeState.sessionToken;
if (token == null) return "";
if (token == "") return "";
return XORCipher.decode(this.name, token);
},
set: function (pw) {
if (pw == "") return;
activeState.sessionToken = XORCipher.encode(this.name, sha256(pw));
},
initHash: function () {
//check if cookie exists
if (getCookie(this.name) != null) {
if (getCookie(this.name) != "") {
this.set(XORCipher.decode(this.name, getCookie(this.name)));
}
}
if (retrieveData("templateFiles") != null) {
//set user id
activeState.userId = passwordHash.name;
setCookie(this.name, XORCipher.encode(this.name, this), 10);
}
},
verify: function () {
if (passwordHash == "") return false;
return (retrieveData("templateFiles") != null) ? true : false;
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = sanitize(x.elements[0].value);
if (pw != "" || pw !== "undefined") {
passwordHash.set(pw);
let tF = retrieveData("templateFiles");
if (tF == null) {
wrongPwAlert();
passwordHash.set("");
x.elements[0].value = "";
return;
}
//user logged in
//make sure to bring back persistent stat after logout
activeState.settings.persistentStorage = "true";
tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
activeState.settings.persistentStorage = "false";
}
activeState.userId = passwordHash.name;
document.getElementById("login").style.display = "none";
setCookie(passwordHash.name, XORCipher.encode(passwordHash.name, passwordHash), 10)
}
}
export function cyrb53(str, seed = 21) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
export function logout() {
let id = passwordHash.name;
activeState.sessionToken = "";
setCookie(passwordHash.name, "", 10);
document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.getElementById("passwordField").value = "";
document.getElementById("login").style.display = "block";
}
export function sanitize(string) {
const map = {
'&': '_',
'<': '_',
'>': '_',
'"': '_',
"'": '_',
'/': '_',
'`': '_',
'=': '_'
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
export function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
export const inputRead = {
init: function () {
this.event = "";
this.inputString = "";
this.source = "";
this.inputContent = "";
this.lastRunTime = new Date();
this.target = document.getElementById("toggleFilesMenu");
this.lastExecId = "";
},
read: function (event) {
this.event = event;
this.source = event.srcElement.id;
if (event.target.className == "pell-content") {
this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
}
let previousContent = this.inputContent;
let key = (event.key !=undefined) ? event.key : "";
let contentElement = document.getElementById(this.source);
this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
if (this.inputContent == "" || key == "") return;
if (key.length > 1) return;
if (event.ctrlKey) return;
if (this.inputContent == previousContent) return;
this.lastRunTime = new Date();
clearTimeout(this.lastExecId);
this.target.style.borderBottom = "3px solid #c0392b";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-save");
this.target.appendChild(i);
this.lastExecId = setTimeout(() => {
createStorageObj();
this.target.style.borderBottom = "none";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
this.target.appendChild(i);
}, 1000);
},
}
export function getCurrentDate() {
let date = new Date();
let uts = Date.now();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
let current_second = date.getSeconds();
current_second = current_second <= 9 ? "0" + current_second : current_second;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_day = date.getDate();
current_day = current_day <= 9 ? "0" + current_day : current_day;
let current_year = date.getFullYear();
let current_time = current_hour + ":" + current_minute;
let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
let current_date = current_day + "." + current_month;
return {
current_time: current_time,
current_time_long: current_time_long,
current_date: current_date,
current_year: current_year,
uts: uts
};
}
export default setPassword;

210
js/2.0.1/settings.js Normal file
View File

@ -0,0 +1,210 @@
import { hideMenus, modalNotifier, printVersion, resetNavBar } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
import { retrieveData, storeData, storeSettings } from "./storage.js";
const buildSettings = () => {
//set current page value in activeState object
activeState.activePage = "settings";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Settings";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
addSidebar();
buildForm();
//add events
formEvts();
};
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
saveSettings();
modalNotifier(
"Settings saved!",
activeState.settings.notifierPause
);
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-nephritis"
);
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-nephritis",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
}
function buildForm() {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let settings = storeSettings("get", true);
if (settings == "") settings = activeState.settings;
for (let setting of Object.entries(settings)) {
buildField(setting, form);
}
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
}
function buildField(obj, form) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj[0]);
input.setAttribute("id", obj[0]);
input.classList.add("w3-input");
input.id = obj[0];
input.value = obj[1];
label.innerHTML = obj[0];
div.appendChild(label);
div.appendChild(input);
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
}
function addSidebar() {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Edit Settings"
sidebarList.appendChild(sidebarListItem);
document.getElementById("sidebar").appendChild(sidebarList);
}
function saveSettings() {
let x = document.getElementById("mainFormObj");
let obj = {};
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
let name = x.elements[i].name;
let value = x.elements[i].value;
obj[name] = sanitize(value);
}
for (let setting of Object.entries(obj)) {
if (activeState.settings[setting[0]] != setting[1]) {
//change detected
if (setting[0] == "persistentStorage") {
//get tF from old storage
let tF = retrieveData("templateFiles");
//get previous settings
let settings = storeSettings("get", true);
//store the new settings in old storage
storeSettings(obj);
//apply the new setting
activeState.settings[setting[0]] = setting[1];
//store the new settings in the new storage
if (settings != "") storeSettings(obj);
//transfer tF
if (tF != null) storeData("templateFiles", tF);
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
}
}
activeState.settings[setting[0]] = setting[1];
}
storeSettings(obj);
}
export default buildSettings;

3
js/2.0.1/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

315
js/2.0.1/storage.js Normal file
View File

@ -0,0 +1,315 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { cyrb53, getCurrentDate, passwordHash, sanitize } from "./scripts.js";
const store = {
getItem: function (key) {
return debug("GET", key, getStor().getItem(sha256(key + activeState.userId)));
},
setItem: function (key, data) {
debug("SET", key, "setItem: "+data);
getStor().setItem(sha256(key + activeState.userId), data);
},
removeItem: function (key) {
getStor().removeItem(sha256(key + activeState.userId));
},
clear: function () {
getStor().clear();
},
};
const tempStore = {
setItem: function (key, data) {
globalThis.activeState.storage[key] = data;
},
getItem: function (key) {
return globalThis.activeState.storage[key];
},
removeItem: function (key) {
globalThis.activeState.storage[key] = "";
},
clear: function () {
globalThis.activeState.storage = [];
},
};
function getStor() {
if (window.activeState.settings.persistentStorage == "true") {
return window.localStorage;
} else {
return tempStore;
}
}
function debug(mode, key, data) {
if (activeState.settings.debug == "false") return data;
console.log({
mode: mode,
key: key,
data: (data != null) ? data.substring(0,10): "",
persistent: activeState.settings.persistentStorage
});
return data;
}
function createStorageObj() {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//console.log(this, dataArray);
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
storeData("userInput", dataArray);
}
function storeData(name, data) {
if (passwordHash == "") return;
data = JSON.stringify(data);
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName();
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
store.setItem(key, obfuscate(data));
}
function retrieveData(name, template = "none") {
if (passwordHash == "") return null;
if (name == "userInput") {
let tF = retrieveData("templateFiles");
if (tF == null) {
return [];
} else {
name = tF[tF.length - 1].fileName;
}
}
if (name == "userInputForce") {
name = "userInput";
}
let cdata;
let key;
if (template == "none") {
let lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
key = name + "_m21_" + template;
}
cdata = store.getItem(key);
if (cdata != null) {
cdata = obfuscate(cdata, false);
let data;
try {
data = JSON.parse(cdata);
} catch (e) {
data = null;
}
return data;
} else {
return [];
}
}
function clearData(name, template = "none") {
let lT;
let key;
if (template == "none") {
lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
lT = template;
key = name + "_m21_" + template;
}
store.removeItem(key);
}
function getFileName(ref = "none") {
let currentFileName = activeState.fileName;
let lT = activeState.loadedTemplate;
if (currentFileName == "none" || currentFileName == "") {
let date = getCurrentDate();
currentFileName = date.current_time + "_" + date.current_date + " " + lT;
//console.log(currentFileName);
}
let tF = retrieveData("templateFiles");
const metadata = {
ts_create: getCurrentDate(),
ts_save: "",
id: cyrb53(currentFileName),
};
if (tF.length != 0) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {
tFi.metadata.ts_save = getCurrentDate();
return currentFileName;
}
}
tF.push({
fileName: currentFileName,
template: lT,
metadata: metadata,
pos: tF.length - 1,
});
} else {
tF = [
{ fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
];
}
storeData("templateFiles", tF);
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if ((data == null) | (data == "")) return "";
if (mode) {
return XORCipher.encode(passwordHash, data);
} else {
return XORCipher.decode(passwordHash, data);
}
}
function popFromTemplateFiles(fileName) {
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
}
function createBookShelf() {
let tF = retrieveData("templateFiles");
let bookShelf = {};
let date = getCurrentDate();
let saveFileName = date.current_time + "_" + date.current_date;
if (tF != null) {
bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
if (activeState.settings.localOnly == "true") {
bookShelf[i].data = data;
} else {
bookShelf[i].data = obfuscate(data);
}
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
store.setItem(file.name, file.data);
templateFilesArray.push({
fileName: file.name.split("_m21_")[0],
template: file.name.split("_m21_")[1],
});
}
store.setItem(
"templateFiles_m21_" + activeState.userId,
obfuscate(JSON.stringify(templateFilesArray))
);
}
}
};
xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
xhttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhttp.send();
}
function storeSettings(data, get = false) {
let key = "settings_m21_" + activeState.userId;
if (get) {
let cdata = "";
if (data == "getInit") {
activeState.settings.persistentStorage = "true";
}
try {
cdata = JSON.parse(obfuscate(store.getItem(key), false));
} catch (e) {
cdata = "";
}
if (data == "getInit") {
activeState.settings.persistentStorage = "false";
}
return cdata;
} else {
store.setItem(key, obfuscate(JSON.stringify(data)));
}
}
function clearStorage() {
store.clear();
}
export {
createStorageObj,
storeData,
retrieveData,
clearData,
getFileName,
createBookShelf,
importBookShelf,
storeSettings,
clearStorage,
};

361
js/2.0.1/web.js Normal file
View File

@ -0,0 +1,361 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName } from "./storage.js";
import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { logout, passwordHash } from "./scripts.js";
import buildSettings from "./settings.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
}
if (cdata != "") {
if (cdata != null) {
retrieveForm(cdata);
}
}
//select first object and focus on it
let obj = activeState.templateObjectsPurified;
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//reset navbar above all else
resetNavBar();
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText);
return;
}
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "javascript:void(0)");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!settings");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Settings";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!logout");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
createEntry.innerHTML = "Logout";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
e.preventDefault;
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "!createNew") {
createTemplate();
return;
}
if (template == "!logout") {
logout();
return;
}
if (template == "!settings") {
buildSettings();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText)
return;
}
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
if (res[x][1].length < 1) continue;
let aReg = document.createElement("a");
aReg.setAttribute("href", "javascript:void(0)");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: formData,
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
let e = document.getElementById(arr[i].name);
if (e === null) {
//parse connected list
let id = arr[i].name.split("cl-")[1];
//escape cl-text:!ls
if (id != undefined) id = id.split(":")[0];
e = document.getElementById(id);
if (e === null) {
//parse connected list main
let id = arr[i].name.split("clM-")[1];
e = document.getElementById(id);
if (e === null) continue;
}
}
//handle connected list Main item button or list
if (e.name.substr(0, 4) == "clM-") {
if (arr[i].value != "!none") {
let clElement = document.getElementById(e.dataset.word);
if (clElement === null) {
clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
}
//make shure it is visible if selected before
if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
e.value = arr[i].value;
}
continue;
}
switch (e.nodeName) {
case "TEXTAREA":
if (e.parentElement != undefined) {
if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
e.innerHTML = arr[i].value;
e = e.parentElement.getElementsByClassName("pell-content")[0];
}
}
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

187
js/2.0.1/xorc.js Normal file
View File

@ -0,0 +1,187 @@
const XORCipher = {
encode: function (key, data, seed) {
data = xor_encrypt(key, data, seed);
return b64_encode(data);
},
decode: function (key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
},
seed: function (n) {
return randString(n);
},
};
function stringToUtf8ByteArray(str) {
var out = [],
p = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) == 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return out;
}
function utf8ByteArrayToString(bytes) {
// array of bytes
var out = [],
pos = 0,
c = 0;
while (pos < bytes.length) {
var c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
var c2 = bytes[pos++];
out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
} else if (c1 > 239 && c1 < 365) {
// Surrogate Pair
var c2 = bytes[pos++];
var c3 = bytes[pos++];
var c4 = bytes[pos++];
var u =
(((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
0x10000;
out[c++] = String.fromCharCode(0xd800 + (u >> 10));
out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
} else {
var c2 = bytes[pos++];
var c3 = bytes[pos++];
out[c++] = String.fromCharCode(
((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
}
}
return out.join("");
}
var b64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function b64_encode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = (o1 << 16) | (o2 << 8) | o3;
h1 = (bits >> 18) & 0x3f;
h2 = (bits >> 12) & 0x3f;
h3 = (bits >> 6) & 0x3f;
h4 = bits & 0x3f;
enc +=
b64_table.charAt(h1) +
b64_table.charAt(h2) +
b64_table.charAt(h3) +
b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
}
function b64_decode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = b64_table.indexOf(data.charAt(i++));
h2 = b64_table.indexOf(data.charAt(i++));
h3 = b64_table.indexOf(data.charAt(i++));
h4 = b64_table.indexOf(data.charAt(i++));
bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
o1 = (bits >> 16) & 0xff;
o2 = (bits >> 8) & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randString(n) {
var r = "";
for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
return r;
}
function xor_encrypt(key, data, seed) {
if (typeof seed == "undefined") seed = randString(32);
var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
return r;
}
function xor_decrypt(key, data) {
var d = data,
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
r.splice(0, r.indexOf(0) + 1);
return utf8ByteArrayToString(r);
}
export default XORCipher;

493
js/2.0.2/buildHtmlForm.js Normal file
View File

@ -0,0 +1,493 @@
import { getFileName } from "./storage.js";
import pell from "./pell.js"
function buildHtmlForm(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//create sidebar set form button
let sidebarSetFormButton = document.createElement("li");
sidebarSetFormButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSetFormButton.style.borderTop = "2px solid #ddd";
sidebarSetFormButton.id = "sb-setform";
sidebarSetFormButton.innerHTML = "Set input as preset";
sidebarList.appendChild(sidebarSetFormButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
copyBtn.id = "fromCopyBtn";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = connectedListsArray[0].word;
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
label = document.createElement("LABEL");
label.innerHTML = '';
//div.classList.add("w3-center");
div.classList.replace("w3-flat-silver", "w3-flat-clouds");
div.appendChild(label);
div.appendChild(select3);
} else {
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
}
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
case "title":
let title = document.createElement("p");
title.classList.add("w3-xxlarge");
title.innerHTML = obj.word;
title.id = obj.word.replace(/ /g, "_");
title.setAttribute("tabindex", "-1");
title.style.cssText = "margin: 20px 0 0 0";
divContainer.className = "w3-container";
div.style.cssText = "padding: 0 10px";
div.appendChild(title);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
divContainer.classList.add("w3-animate-opacity")
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
if (obj.type == "title") {
sidebarListItem.setAttribute("data-item", "_title");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML = "<b>"+obj.word+"</b>";
}
sidebarList.appendChild(sidebarListItem);
}
function buildLongTextInput(source, textarea, label) {
if (activeState.settings.enablePell == "false") return;
//hide default textarea
textarea.style.display = "none";
label.style.display = "none";
let title = document.createElement("b");
title.innerText = label.innerText;
const editor = pell.init({
element: source,
defaultParagraphSeparator: "div",
actions: [
"bold",
"italic",
"underline",
"strikethrough",
"paragraph",
"heading1",
"heading2",
{
name: 'ulist',
icon: 'L'
},
"olist"
],
onChange: function (html) {
//correct lastElement
activeState.lastElement = textarea.id;
textarea.value = html;
},
});
let actionBar = editor.getElementsByClassName("pell-actionbar")[0];
let content = editor.getElementsByClassName("pell-content")[0];
let actionBarElements = actionBar.getElementsByClassName("pell-button");
let newActionBarElements = [];
for (let actionBarElement of actionBarElements ) {
actionBarElement.classList.add("w3-right");
actionBarElement.setAttribute("tabindex","-1");
newActionBarElements.push(actionBarElement);
}
//reverse actionbar back to org order
actionBar.innerHTML = "";
for (let newActionBarElement of newActionBarElements.reverse()) {
actionBar.appendChild(newActionBarElement);
}
actionBar.classList.add("w3-container");
actionBar.style.paddingLeft = "0px";
actionBar.appendChild(title);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default buildHtmlForm;

196
js/2.0.2/createTemplate.js Normal file
View File

@ -0,0 +1,196 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { hideMenus, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus("force");
resetPage();
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
if (!templates.includes('_textBlocks')) {
templates.push('_textBlocks');
}
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", activeState.settings.notifierPause);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

332
js/2.0.2/evts.js Normal file
View File

@ -0,0 +1,332 @@
import { createBookShelf, importBookShelf } from "./storage.js";
import {
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer,
} from "./web.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += " " + insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
if (element.parentElement != undefined) {
if (
element.parentElement.getElementsByClassName("pell-content")[0] !=
undefined
) {
element.parentElement.getElementsByClassName(
"pell-content"
)[0].innerHTML = element.value;
element = element.parentElement.getElementsByClassName("pell-content")[0];
}
}
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
}
function hideMenus(evt) {
if (evt === undefined) return;
if (evt != "force" && evt.target.parentElement != null) {
if (evt.target.parentElement.id == "navMob") return;
if (evt.target.parentElement.id == "navReg") return;
if (evt.target.parentElement.parentElement != null) {
if (evt.target.parentElement.parentElement.id == "navMob") return;
if (evt.target.parentElement.parentElement.id == "navReg") return;
}
}
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout = 3, closeable = true) {
let modalElement = document.getElementById("modalNotifier");
let modalElementCloseBtn = document.getElementById("modalNotifierClose");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
if (!closeable) modalElementCloseBtn.style.display = "none";
msgElement.innerHTML = msg;
if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function printVersion(msg = "") {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length - 2];
//add it to document footer currentVersion
versionSpan.textContent = msg + " version: " + pathVersion;
}
}
}
function clickImportFiles() {
if (activeState.settings.localOnly == "true") {
createBookShelfDownload();
return;
}
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Imported!",
activeState.settings.notifierPause
);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display =
"none";
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: " +
activeState.serverFilesTs.replace("_", " - ") +
"<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0
);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
activeState.userId +
".txt' style='text-decoration: underline;' download>download</a> them?",
0
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0
);
}
function createBookShelfDownload() {
let data = createBookShelf();
let filename = data[0]["data"] + ".txt";
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," +
encodeURIComponent(JSON.stringify(data))
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
modalNotifier(
"Since you are in local only mode you can only export a backup of your files \
<br><br> \
<div class='w3-container'> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Export</button></div>",
0
);
}
function resetNavBar() {
//enable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "";
//enable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "block";
}
function wrongPwAlert() {
let wrongPWAlert = document.getElementById("wrongPWAlert");
wrongPWAlert.style.display = "block";
wrongPWAlert.addEventListener("click", (e) => {
if (e.target && e.target.tagName === "A") {
clearStorage();
document.getElementById("wrongPWAlert").innerHTML =
"<p>all files cleared - set new password</p>";
}
});
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function resetPage() {
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
let fileInfoDiv = document.getElementById("outputInfo");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
fileInfoDiv.innerHTML = "";
fileInfoDiv.replaceWith(fileInfoDiv.cloneNode(true));
fileInfoDiv.style.display = "none";
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
modalNotifier,
clickImportFiles,
resetNavBar,
printVersion,
wrongPwAlert,
copyToClipBoard,
resetPage
};

515
js/2.0.2/files.js Normal file
View File

@ -0,0 +1,515 @@
import { storeData, clearData, retrieveData, setTimeStamp } from "./storage.js";
import { loadTemplate } from "./web.js";
import parseForm from "./parseForm.js";
import { copyToClipBoard, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash } from "./scripts.js";
function buildFile() {
//set current page value in activeState object
activeState.activePage = "files";
//set templateFiles array
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
//console.log("none yet");
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Saved files";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//disable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "background-color:#9e9e9e !important";
target.style.borderBottom = "4px solid #9e9e9e";
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
resetPage();
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
let target = e.target.parentElement;
if (e.target.matches("li.w3-bar-item")) target = e.target;
if (target.classList.contains("w3-bar-item")) {
let fileName = target.dataset.file;
let template = target.dataset.template;
let pos = target.dataset.tfpos;
clickLoadFileDiv(fileName, template, pos);
}
});
}
function loadFileDiv(fileName, template, pos) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
pos = parseInt(pos) + 1;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
}
function loadFileDivCallBack() {
let tF = retrieveData("templateFiles");
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "_m21_" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-flat-pomegranate");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
let parsedTemplate = parseForm(true);
if (parsedTemplate == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
if (parsedTemplate == "") {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("File empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
div.appendChild(parsedTemplate);
fileDisplay.appendChild(div);
document.getElementById("mainForm").appendChild(fileDisplay);
//append TS info
let fileInfoDiv = document.getElementById("outputInfo");
let pos = "";
tF = retrieveData("templateFiles");
for (let tFi of tF) {
if (tFi.fileName == fN) {
pos = parseInt(tFi.pos);
}
}
let tsCreate = tF[pos].metadata.ts_create;
let created = "";
if (tsCreate != "") {
tsCreate =
tsCreate.current_time_long +
" " +
tsCreate.current_date +
"." +
tsCreate.current_year;
created = "";
created = "<tr><td>Created at</td><td>" + tsCreate + "</td></tr>";
}
let tsSave = tF[pos].metadata.ts_save;
let lastSaved = "";
if (tsSave != "") {
tsSave =
tsSave.current_time_long +
" " +
tsSave.current_date +
"." +
tsSave.current_year;
lastSaved = "";
lastSaved = "<tr><td>Last saved at</td><td>" + tsSave + "</td></tr>";
}
let tsCopy = tF[pos].metadata.ts_copy;
let lastCopy = "";
if (tsCopy != "") {
tsCopy =
tsCopy.current_time_long +
" " +
tsCopy.current_date +
"." +
tsCopy.current_year;
lastCopy = "";
lastCopy = "<tr><td>Last copied at</td><td>" + tsCopy + "</td></tr>";
}
let tsEdit = tF[pos].metadata.ts_edit;
let lastEdit = "";
if (tsEdit != "") {
tsEdit =
tsEdit.current_time_long +
" " +
tsEdit.current_date +
"." +
tsEdit.current_year;
lastEdit = "";
lastEdit = "<tr><td>Last edited at</td><td>" + tsEdit + "</td></tr>";
}
fileInfoDiv.innerHTML =
"<p><b>Fileinformation:</b></p>" +
"<table class='w3-table w3-bordered'>" +
"<tr><td>Template</td><td>" +
lT +
"</td></tr>" +
"<tr><td>ID</td><td>" +
pos + "." +
tF[pos].metadata.id +
"</td></tr>" +
created +
lastSaved +
lastCopy +
lastEdit +
"</table>"
fileInfoDiv.style.display = "block";
fileInfoDiv.classList.add("w3-third");
//fix min height of file display
try {
document.getElementById("fileDisplay").style.cssText = "min-height: 300px;";
} catch (e) {}
//fix fontsize for display
try {
document.getElementById("fileDisplay").firstChild.style.fontSize = "1em";
} catch (e) {}
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template, pos) {
if (fileName == "_overflow") return;
if (fileName == "_clearAll") {
clickClearAllFiles();
return;
}
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template, pos);
}
function clearFileData(storData) {
let fileName = storData.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
clearData(fileName);
clearData("userInputForce");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("outputInfo").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-padding-large");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Saved Files:";
sidebarList.appendChild(sidebarListItem);
let c = 0;
let sidebarItemsAmount = 6;
for (let obj of tF.reverse()) {
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
//handle to many files on screen and display hidden files amount
if (c > sidebarItemsAmount) {
sidebarListItem.setAttribute("data-template", "_overflow");
sidebarListItem.setAttribute("data-file", "_overflow");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML =
tF.length - sidebarItemsAmount + " files not shown";
sidebarList.appendChild(sidebarListItem);
break;
}
let sidebarListItemTitle = document.createElement("p");
sidebarListItemTitle.innerText = obj.fileName.replace(/_/g, " ");
sidebarListItemTitle.style.cssText = "margin: 0;";
let sidebarListItemInfo = document.createElement("span");
sidebarListItemInfo.classList.add("w3-small");
sidebarListItemInfo.innerText =
"created at: " +
obj.metadata.ts_create.current_time +
" - " +
obj.metadata.ts_create.current_date;
sidebarListItem.appendChild(sidebarListItemTitle);
sidebarListItem.append(sidebarListItemInfo);
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarListItem.setAttribute("data-tFPos", obj.pos);
sidebarList.appendChild(sidebarListItem);
c++;
}
//clear all files button
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button");
sidebarListItem.setAttribute("data-template", "_clearAll");
sidebarListItem.setAttribute("data-file", "_clearAll");
sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.style.width = "300px";
sidebarListItem.innerHTML = "Clear all files";
sidebarList.appendChild(sidebarListItem);
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return (
"<div id='fileDisplay' class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" +
msg +
"</p><br><br><br><br><br><br><br><br><br><br><br></div></div>"
);
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
editSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-carrot"
);
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-carrot",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
modalNotifier(
activeState.fileName + " copied to clipboard",
activeState.settings.notifierPause
);
break;
case "Delete":
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
let delFileName = activeState.fileName;
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(
previousFile.fileName,
previousFile.template,
previousFile.pos
);
} else {
document.getElementById("mainForm").innerHTML =
mainFormPlaceholder("No file yet");
}
modalNotifier(
delFileName + " deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
}
function editSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("_m21_")[0], storageName.split("_m21_")[1])
);
//reset sidebar to clear events
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
//reset navbar above all else
resetNavBar();
//reset correct activePage
activeState.activePage = "template";
//set edit timestamp
setTimeStamp("edit");
loadTemplate(storageName.split("_m21_")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i - 1];
if (previousFile === undefined) {
//get the next one if there is no previous one
previousFile = tF[i + 1];
}
break;
}
i++;
}
return previousFile != undefined ? previousFile : false;
}
function clickClearAllFiles() {
let modal = document.getElementById("modalMsg");
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Delete":
clearAllFiles();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"All files deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
<p>Would you really like to delete all stored files?</p> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button>",
0
);
}
function clearAllFiles() {
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
for (let storageName of tF) {
clearFileData(storageName.fileName);
}
}
export { buildFile, loadFileDivCallBack };

295
js/2.0.2/form.js Normal file
View File

@ -0,0 +1,295 @@
import { retrieveData, storeData, createStorageObj } from "./storage.js";
import parseTemplate from "./parseTemplate.js";
import buildHtmlForm from "./buildHtmlForm.js";
import { copyToClipBoard, handleOnBlur, modalNotifier, resetPage } from "./evts.js";
import parseForm, { parseTextMarkups } from "./parseForm.js";
import { setTemplatePreset } from "./web.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
let placeholder;
try {
placeholder = JSON.parse(jsonPlaceholder);
} catch (e) {
placeholder = ""
}
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", placeholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseTemplate Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseTemplate(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
activeState.templateObjects = objects;
activeState.fullString = templateInput;
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
activeState.templateObjectsPurified = objectsPurified;
//reset page and event listeners
resetPage();
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) return;
buildHtmlForm(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj("copy");
copyToClipBoard(parseForm());
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
e.target.value = "Copied";
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
const timeoutCopy = setTimeout(() => {
//e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
//e.target.value = "Copy";
e.target.style.pointerEvents = "auto";
}, 5000);
break;
case "Save":
createStorageObj("save");
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause);
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause);
}
if (e.target.id == "sb-setform") {
createStorageObj("setform");
let dataArray = retrieveData("userInput");
let lT = activeState.loadedTemplate;
setTemplatePreset(lT, dataArray);
modalNotifier("Input saved as preset", activeState.settings.notifierPause);
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener to each form object
let mainForm = document.getElementById("mainFormObj");
for (let formElement of mainForm.children) {
if (formElement.firstChild.lastChild == null) continue;
let id = formElement.firstChild.lastChild.id;
document.getElementById(id).addEventListener("blur", (e) => {
e.preventDefault;
handleOnBlur(e.target);
});
}
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
if (targetElement == null) return;
//handle pell content focus
if (targetElement.parentElement != undefined) {
if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0];
}
}
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/2.0.2/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

180
js/2.0.2/init.js Normal file
View File

@ -0,0 +1,180 @@
import {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
clickImportFiles,
modalNotifier,
printVersion,
copyToClipBoard
} from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, {
passwordHash,
inputRead
} from "./scripts.js";
import parseForm from "./parseForm.js";
import { createStorageObj, storeSettings } from "./storage.js";
import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js";
window.activeState = {
userId: "",
sessionToken: "",
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
settings: {
localOnly: "true",
lineBreak: 120,
font: "Arial",
fontSize: "10px",
notifierPause: 1,
persistentStorage: "false",
enablePell: "false",
debug: "false"
},
templates: [],
templateObjectsPurified: [],
templateObjects: [],
fullString: "",
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
"title",
],
markups: ["title", "link", "italic", "green_highlighted", "highlighted"],
storage: [],
orgPage: {
main: {},
sidebar: {}
}
};
function init() {
//init passwordhash to retrieve cookie info and set passwordHash
passwordHash.initHash();
//check if user is logged in
if (passwordHash.verify()) {
//user logged in
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load settings from storage and apply
let settings = storeSettings("getInit", true);
if (settings != null) {
for (let setting of Object.entries(settings)) {
activeState.settings[setting[0]] = setting[1];
}
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version and storage mode to footer
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
//backup landing page
activeState.orgPage.sidebar = document.getElementById("sidebar");
activeState.orgPage.main = document.getElementById("mainForm");
}
function eventListeners() {
//add hideMenu to Body
document
.body
.addEventListener("click", (e) => hideMenus(e));
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
/* document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu); */
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
inputRead.init();
window.addEventListener("keydown", (e) => {
if (activeState.activePage == "template") {
inputRead.read(e);
if (e.ctrlKey && e.key == "s") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File copied to clipboard", activeState.settings.notifierPause);
let copyButton = document.getElementById("fromCopyBtn");
copyButton.className = "w3-button w3-flat-carrot";
copyButton.value = "Copied";
e.preventDefault();
}
}
});
//add url listener
window.addEventListener("hashchange", (e) => {
let newURLArr = e.newURL.split("/");
let template;
if (newURLArr != undefined) {
template = newURLArr[newURLArr.length -1];
if (template != undefined) {
template = template.split("=")[1];
if (template != undefined) {
if (activeState.templates.includes("")) {
loadNewTemplate(template);
}
}
}
}
});
}
init();

374
js/2.0.2/parseForm.js Normal file
View File

@ -0,0 +1,374 @@
import { clearData, retrieveData } from "./storage.js";
function parseForm(returnDIV = false) {
//get user Inout Data from preset or from file
let dataArray = [];
if (returnDIV) {
dataArray = retrieveData("userInputForce");
clearData("userInputForce");
} else {
dataArray = retrieveData("userInput");
}
//if the decryption went wrong return null
if (dataArray == null) return dataArray;
//if there are no files yet return empty array
if (dataArray == []) return "";
//get original objects from sessionstorage gen from loadTemplate
let objects = activeState.templateObjects;
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = activeState.fullString;
//define output buffer
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
obj.result = "";
//compaire each obj with elements from mainFormObj
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
//if obj is the connected list main selector
if (data.name.split("-")[0] == "clM") {
//if connected list main matches current object
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
//set flag for next iteration of loop
conListFlag = true;
data.name = data.name.substring(4);
//selection is not added to buffer
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
//if field matches current object
if (obj.word.replace(/ /g, "_") == data.name) {
let value = parseDataForResult(obj, data.value);
if (value == "!none") value = "";
obj.result = value;
}
//handle conlist elements for parsing each element
if (conListFlag && obj.type == "conList") {
let value = parseConListForResult(obj, data, dataArray);
if (value == "!none") value = "";
obj.result = value;
continue;
}
}
}
//build final output string by inserting objects
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
let tepos = objects[i].epos;
//skip empty results by skipping the newline char
if (objects[i].result == "") tepos += 1;
b +=
objects[i].result +
fullString.substring(tepos, objects[j].spos);
}
}
//sanitizing final output string
let bHtml = b;
bHtml = bHtml.replace(/ /g, "&nbsp;");
bHtml = bHtml.replace(/(?:\r\n|\r|\n)/g, "<br />");
bHtml = bHtml.replace(/<\/div>/g, '<br />');
bHtml = bHtml.replace(/<div>/g, '');
if (activeState.settings.enablePell == "true") {
bHtml = bHtml.replace(/!l /g, "");
bHtml = bHtml.replace(/!n /g, "");
bHtml = bHtml.replace(/!ls /g, "");
} else {
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
}
//creating output div
let divContent = document.createElement("div");
divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
divContent.style.fontSize = activeState.settings.fontSize;
divContent.innerHTML = bHtml;
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.appendChild(divContent);
if (returnDIV) {
return div;
} else {
return bHtml;
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
//parse global linebreak after marked text was already fixed
value = parseGlobalLineBreak(value);
return value;
}
function parseConListForResult(obj, data, dataArray) {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
}
}
return ""
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
if (dataArray[i] == "") continue;
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
continue;
}
//check if list indicator has been set and adjust userInput accordingly
let listIndicator = "";
if (listNumberFlag) {
listIndicator = " " + listNumberFlagNum + ". ";
listNumberFlagNum++;
}
if (listSubFlag && listIndicator == "") listIndicator = " ○ ";
if (listFlag && listIndicator == "") listIndicator = " • ";
//exclude settings if pell is enabled
if (activeState.settings.enablePell == "true") listIndicator = "";
//handle global linebreak and fit according to indicator according to list indicator
if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function parseGlobalLineBreak(data) {
//parse each line of input with parseLineBreak return condensed string with newlines
let parsedData = '';
for (let line of data.split('\n')) {
let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
if (parsedData != '') {
parsedData = parsedData + '\n' + parsedLine;
} else {
parsedData = parsedLine;
}
}
return parsedData
}
function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
//add 5 chars buffer to fix list intendation issue
//each input field gets parsed line by line twice once for list inputs and a second time for each input
let lines;
if (line.length > lineBreak) {
//create linebreak in between second to last word
let correctedLineBreak;
let newLineStart;
let cLBt = lineBreak-(intendation*2)
//find last space before linebreak
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
//and fix the next lines start
newLineStart = correctedLineBreak+1;
//add to parsed output
lines = line.substring(0, correctedLineBreak);
//delete first parsed output from inputstring
line = line.substring(newLineStart);
let intendationSpaces = '';
//check if an intendation is given if so convert it to correct spaces
if (intendation != 0) intendationSpaces = ' '.repeat(intendation);
//start loop to parse rest of the string
while(line.length > lineBreak) {
let cLBt = lineBreak-(intendation*2)
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
newLineStart = correctedLineBreak+1;
//add to output with intendation if given
lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
//delete from input
line = line.substring(newLineStart);
}
//process rest of the string with correct intendation
lines += "\n" + intendationSpaces + line;
} else {
//if string is within lineBreak just forward input to output
lines = line;
}
return lines;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
export default parseForm;

388
js/2.0.2/parseTemplate.js Normal file
View File

@ -0,0 +1,388 @@
function parseTemplate(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//bugfix if the title of an input has no space in it ex: %test=l:first word;l:second word;%1
let oneWordFlag = false;
if (word.substring(0, 1) == "%" && word.indexOf('=') != -1) {
oneWordFlag = true;
}
//for loop to escape spaces in simple input
for (let j = i+1; j < wordArray.length; j++) {
//if title has no space then go back one word to include "=" ex:
if (oneWordFlag) {
j = i;
oneWordFlag = false;
} else {
w = w + " " + wordArray[j];
}
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseTemplate;

254
js/2.0.2/pell.js Normal file
View File

@ -0,0 +1,254 @@
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? factory(exports)
: typeof define === "function" && define.amd
? define(["exports"], factory)
: factory((globalThis.pell = {}));
})(this, function (exports) {
"use strict";
var _extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var defaultParagraphSeparatorString = "defaultParagraphSeparator";
var formatBlock = "formatBlock";
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
state: function state() {
return queryCommandState("bold");
},
result: function result() {
return exec("bold");
},
},
italic: {
icon: "<i>I</i>",
title: "Italic",
state: function state() {
return queryCommandState("italic");
},
result: function result() {
return exec("italic");
},
},
underline: {
icon: "<u>U</u>",
title: "Underline",
state: function state() {
return queryCommandState("underline");
},
result: function result() {
return exec("underline");
},
},
strikethrough: {
icon: "<strike>S</strike>",
title: "Strike-through",
state: function state() {
return queryCommandState("strikeThrough");
},
result: function result() {
return exec("strikeThrough");
},
},
heading1: {
icon: "<b>H<sub>1</sub></b>",
title: "Heading 1",
result: function result() {
return exec(formatBlock, "<h1>");
},
},
heading2: {
icon: "<b>H<sub>2</sub></b>",
title: "Heading 2",
result: function result() {
return exec(formatBlock, "<h2>");
},
},
paragraph: {
icon: "&#182;",
title: "Paragraph",
result: function result() {
return exec(formatBlock, "<p>");
},
},
quote: {
icon: "&#8220; &#8221;",
title: "Quote",
result: function result() {
return exec(formatBlock, "<blockquote>");
},
},
olist: {
icon: "&#35;",
title: "Ordered List",
result: function result() {
return exec("insertOrderedList");
},
},
ulist: {
icon: "&#8226;",
title: "Unordered List",
result: function result() {
return exec("insertUnorderedList");
},
},
code: {
icon: "&lt;/&gt;",
title: "Code",
result: function result() {
return exec(formatBlock, "<pre>");
},
},
line: {
icon: "&#8213;",
title: "Horizontal Line",
result: function result() {
return exec("insertHorizontalRule");
},
},
link: {
icon: "&#128279;",
title: "Link",
result: function result() {
var url = window.prompt("Enter the link URL");
if (url) exec("createLink", url);
},
},
image: {
icon: "&#128247;",
title: "Image",
result: function result() {
var url = window.prompt("Enter the image URL");
if (url) exec("insertImage", url);
},
},
};
var defaultClasses = {
actionbar: "pell-actionbar",
button: "pell-button",
content: "pell-content",
selected: "pell-button-selected",
};
var init = function init(settings) {
var actions = settings.actions
? settings.actions.map(function (action) {
if (typeof action === "string") return defaultActions[action];
else if (defaultActions[action.name])
return _extends({}, defaultActions[action.name], action);
return action;
})
: Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator =
settings[defaultParagraphSeparatorString] || "div";
var actionbar = createElement("div");
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = (settings.element.content = createElement("div"));
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3)
exec(formatBlock, "<" + defaultParagraphSeparator + ">");
else if (content.innerHTML === "<br>") content.innerHTML = "";
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (
event.key === "Enter" &&
queryCommandValue(formatBlock) === "blockquote"
) {
setTimeout(function () {
return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement("button");
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute("type", "button");
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? "add" : "remove"](
classes.selected
);
};
addEventListener(content, "keyup", handler);
addEventListener(content, "mouseup", handler);
addEventListener(button, "click", handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec("styleWithCSS");
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports["default"] = pell;
Object.defineProperty(exports, "__esModule", { value: true });
});
export default pell;

216
js/2.0.2/scripts.js Normal file
View File

@ -0,0 +1,216 @@
import { createStorageObj, retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
import { wrongPwAlert } from "./evts.js";
export const passwordHash = {
name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
toString: function () {
let token = window.activeState.sessionToken;
if (token == null) return "";
if (token == "") return "";
return XORCipher.decode(this.name, token);
},
set: function (pw) {
if (pw == "") return;
activeState.sessionToken = XORCipher.encode(this.name, sha256(pw));
},
initHash: function () {
//check if cookie exists
if (getCookie(this.name) != null) {
if (getCookie(this.name) != "") {
this.set(XORCipher.decode(this.name, getCookie(this.name)));
}
}
if (retrieveData("templateFiles") != null) {
//set user id
activeState.userId = passwordHash.name;
setCookie(this.name, XORCipher.encode(this.name, this), 10);
}
},
verify: function () {
if (passwordHash == "") return false;
return (retrieveData("templateFiles") != null) ? true : false;
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = sanitize(x.elements[0].value);
if (pw != "" || pw !== "undefined") {
passwordHash.set(pw);
let tF = retrieveData("templateFiles");
if (tF == null) {
wrongPwAlert();
passwordHash.set("");
x.elements[0].value = "";
return;
}
//user logged in
//make sure to bring back persistent stat after logout
activeState.settings.persistentStorage = "true";
tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
activeState.settings.persistentStorage = "false";
}
activeState.userId = passwordHash.name;
document.getElementById("login").style.display = "none";
setCookie(passwordHash.name, XORCipher.encode(passwordHash.name, passwordHash), 10)
}
}
export function cyrb53(str, seed = 21) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
export function logout() {
let id = passwordHash.name;
activeState.sessionToken = "";
setCookie(passwordHash.name, "", 10);
document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.getElementById("passwordField").value = "";
document.getElementById("login").style.display = "block";
}
export function sanitize(string) {
const map = {
'&': '_',
'<': '_',
'>': '_',
'"': '_',
"'": '_',
'/': '_',
'`': '_',
'=': '_'
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
export function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
export const inputRead = {
init: function () {
this.event = "";
this.inputString = "";
this.source = "";
this.inputContent = "";
this.lastRunTime = new Date();
this.target = document.getElementById("toggleFilesMenu");
this.lastExecId = "";
},
read: function (event) {
this.event = event;
this.source = event.srcElement.id;
if (event.target.className == "pell-content") {
this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
}
let previousContent = this.inputContent;
let key = (event.key !=undefined) ? event.key : "";
let contentElement = document.getElementById(this.source);
this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
if (this.inputContent == "" || key == "") return;
if (key.length > 1) return;
if (event.ctrlKey) return;
if (this.inputContent == previousContent) return;
this.lastRunTime = new Date();
clearTimeout(this.lastExecId);
this.target.style.borderBottom = "3px solid #c0392b";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-save");
this.target.appendChild(i);
this.lastExecId = setTimeout(() => {
createStorageObj("save");
this.target.style.borderBottom = "none";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
this.target.appendChild(i);
}, 1000);
},
}
export function getCurrentDate() {
let date = new Date();
let uts = Date.now();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
let current_second = date.getSeconds();
current_second = current_second <= 9 ? "0" + current_second : current_second;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_day = date.getDate();
current_day = current_day <= 9 ? "0" + current_day : current_day;
let current_year = date.getFullYear();
let current_time = current_hour + ":" + current_minute;
let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
let current_date = current_day + "." + current_month;
return {
current_time: current_time,
current_time_long: current_time_long,
current_date: current_date,
current_year: current_year,
uts: uts
};
}
export default setPassword;

198
js/2.0.2/settings.js Normal file
View File

@ -0,0 +1,198 @@
import { hideMenus, modalNotifier, printVersion, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
import { retrieveData, storeData, storeSettings } from "./storage.js";
const buildSettings = () => {
//set current page value in activeState object
activeState.activePage = "settings";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Settings";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
resetPage();
addSidebar();
buildForm();
//add events
formEvts();
};
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
saveSettings();
modalNotifier(
"Settings saved!",
activeState.settings.notifierPause
);
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-nephritis"
);
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-nephritis",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
}
function buildForm() {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let settings = storeSettings("get", true);
if (settings == "") settings = activeState.settings;
for (let setting of Object.entries(settings)) {
buildField(setting, form);
}
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
}
function buildField(obj, form) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj[0]);
input.setAttribute("id", obj[0]);
input.classList.add("w3-input");
input.id = obj[0];
input.value = obj[1];
label.innerHTML = obj[0];
div.appendChild(label);
div.appendChild(input);
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
}
function addSidebar() {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Edit Settings"
sidebarList.appendChild(sidebarListItem);
document.getElementById("sidebar").appendChild(sidebarList);
}
function saveSettings() {
let x = document.getElementById("mainFormObj");
let obj = {};
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
let name = x.elements[i].name;
let value = x.elements[i].value;
obj[name] = sanitize(value);
}
for (let setting of Object.entries(obj)) {
if (activeState.settings[setting[0]] != setting[1]) {
//change detected
if (setting[0] == "persistentStorage") {
//get tF from old storage
let tF = retrieveData("templateFiles");
//get previous settings
let settings = storeSettings("get", true);
//store the new settings in old storage
storeSettings(obj);
//apply the new setting
activeState.settings[setting[0]] = setting[1];
//store the new settings in the new storage
if (settings != "") storeSettings(obj);
//transfer tF
if (tF != null) storeData("templateFiles", tF);
let msg = (activeState.settings.persistentStorage == "false") ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
}
}
activeState.settings[setting[0]] = setting[1];
}
storeSettings(obj);
}
export default buildSettings;

3
js/2.0.2/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

354
js/2.0.2/storage.js Normal file
View File

@ -0,0 +1,354 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { cyrb53, getCurrentDate, passwordHash, sanitize } from "./scripts.js";
const store = {
getItem: function (key) {
return debug("GET", key, getStor().getItem(sha256(key + activeState.userId)));
},
setItem: function (key, data) {
debug("SET", key, "setItem: "+data);
getStor().setItem(sha256(key + activeState.userId), data);
},
removeItem: function (key) {
getStor().removeItem(sha256(key + activeState.userId));
},
clear: function () {
getStor().clear();
},
};
const tempStore = {
setItem: function (key, data) {
globalThis.activeState.storage[key] = data;
},
getItem: function (key) {
return globalThis.activeState.storage[key];
},
removeItem: function (key) {
globalThis.activeState.storage[key] = "";
},
clear: function () {
globalThis.activeState.storage = [];
},
};
function getStor() {
if (window.activeState.settings.persistentStorage == "true") {
return window.localStorage;
} else {
return tempStore;
}
}
function debug(mode, key, data) {
if (activeState.settings.debug == "false") return data;
console.log({
mode: mode,
key: key,
data: (data != null) ? data.substring(0,10): "",
persistent: activeState.settings.persistentStorage
});
return data;
}
function createStorageObj(ref = "none") {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//console.log(this, dataArray);
//set current filename according to filenamefield
setCurrentFileName();
//set savetime in templateFiles
setTimeStamp(ref);
storeData("userInput", dataArray);
}
function storeData(name, data) {
if (passwordHash == "") return;
data = JSON.stringify(data);
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName();
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
store.setItem(key, obfuscate(data));
}
function retrieveData(name, template = "none") {
if (passwordHash == "") return null;
if (name == "userInput") {
if (activeState.fileName != "") {
name = activeState.fileName;
} else {
return [];
}
}
if (name == "userInputForce") {
name = "userInput";
}
let cdata;
let key;
if (template == "none") {
let lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
key = name + "_m21_" + template;
}
cdata = store.getItem(key);
if (cdata != null) {
cdata = obfuscate(cdata, false);
let data;
try {
data = JSON.parse(cdata);
} catch (e) {
data = null;
}
return data;
} else {
return [];
}
}
function clearData(name, template = "none") {
let lT;
let key;
if (name == "userInputForce") name = "userInput";
if (template == "none") {
lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
lT = template;
key = name + "_m21_" + template;
}
store.removeItem(key);
}
function getFileName() {
let currentFileName = activeState.fileName;
let lT = activeState.loadedTemplate;
if (currentFileName == "none" || currentFileName == "") {
let date = getCurrentDate();
currentFileName = date.current_time + "_" + date.current_date + " " + lT;
//console.log(currentFileName);
}
let tF = retrieveData("templateFiles");
const metadata = {
ts_create: getCurrentDate(),
ts_save: "",
ts_copy: "",
ts_edit: "",
id: cyrb53(currentFileName),
editor: (activeState.settings.enablePell == "true") ? "pell": "textarea"
};
if (tF.length != 0) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {
return currentFileName;
}
}
tF.push({
fileName: currentFileName,
template: lT,
metadata: metadata,
pos: tF.length,
});
} else {
tF = [
{ fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
];
}
storeData("templateFiles", tF);
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if ((data == null) | (data == "")) return "";
if (mode) {
return XORCipher.encode(passwordHash, data);
} else {
return XORCipher.decode(passwordHash, data);
}
}
function popFromTemplateFiles(fileName) {
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
}
function createBookShelf() {
let tF = retrieveData("templateFiles");
let bookShelf = {};
let date = getCurrentDate();
let saveFileName = date.current_time + "_" + date.current_date;
if (tF != null) {
bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
if (activeState.settings.localOnly == "true") {
bookShelf[i].data = data;
} else {
bookShelf[i].data = obfuscate(data);
}
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
store.setItem(file.name, file.data);
templateFilesArray.push({
fileName: file.name.split("_m21_")[0],
template: file.name.split("_m21_")[1],
});
}
store.setItem(
"templateFiles_m21_" + activeState.userId,
obfuscate(JSON.stringify(templateFilesArray))
);
}
}
};
xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
xhttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhttp.send();
}
function storeSettings(data, get = false) {
let key = "settings_m21_" + activeState.userId;
if (get) {
let cdata = "";
if (data == "getInit") {
activeState.settings.persistentStorage = "true";
}
try {
cdata = JSON.parse(obfuscate(store.getItem(key), false));
} catch (e) {
cdata = "";
}
if (data == "getInit") {
activeState.settings.persistentStorage = "false";
}
return cdata;
} else {
store.setItem(key, obfuscate(JSON.stringify(data)));
}
}
function clearStorage() {
store.clear();
}
function setCurrentFileName() {
activeState.fileName = "";
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
}
function setTimeStamp(type) {
if (activeState.fileName != "") {
let tF = retrieveData("templateFiles");
if (tF.length != 0) {
let c = 0;
for (let tFi of tF) {
if (tFi.fileName == activeState.fileName) {
switch (type) {
case "save":
tF[c].metadata.ts_save = getCurrentDate();
break;
case "copy":
console.log("copy");
tF[c].metadata.ts_copy = getCurrentDate();
break;
case "edit":
tF[c].metadata.ts_edit = getCurrentDate();
break;
}
storeData("templateFiles", tF);
}
c += 1;
}
}
}
}
export {
createStorageObj,
storeData,
retrieveData,
clearData,
getFileName,
createBookShelf,
importBookShelf,
storeSettings,
clearStorage,
setCurrentFileName,
setTimeStamp
};

362
js/2.0.2/web.js Normal file
View File

@ -0,0 +1,362 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName } from "./storage.js";
import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { logout, passwordHash } from "./scripts.js";
import buildSettings from "./settings.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
clearData("userInputForce");
}
if (cdata != "") {
if (cdata != null) {
retrieveForm(cdata);
}
}
//select first object and focus on it
let obj = activeState.templateObjectsPurified;
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//reset navbar above all else
resetNavBar();
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText);
return;
}
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "javascript:void(0)");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!settings");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Settings";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!logout");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
createEntry.innerHTML = "Logout";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
e.preventDefault;
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "!createNew") {
createTemplate();
return;
}
if (template == "!logout") {
logout();
return;
}
if (template == "!settings") {
buildSettings();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText)
return;
}
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
if (res[x][1].length < 1) continue;
let aReg = document.createElement("a");
aReg.setAttribute("href", "javascript:void(0)");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: JSON.stringify(formData),
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
let e = document.getElementById(arr[i].name);
if (e === null) {
//parse connected list
let id = arr[i].name.split("cl-")[1];
//escape cl-text:!ls
if (id != undefined) id = id.split(":")[0];
e = document.getElementById(id);
if (e === null) {
//parse connected list main
let id = arr[i].name.split("clM-")[1];
e = document.getElementById(id);
if (e === null) continue;
}
}
//handle connected list Main item button or list
if (e.name.substr(0, 4) == "clM-") {
if (arr[i].value != "!none") {
let clElement = document.getElementById(e.dataset.word);
if (clElement === null) {
clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
}
//make shure it is visible if selected before
if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
e.value = arr[i].value;
}
continue;
}
switch (e.nodeName) {
case "TEXTAREA":
if (e.parentElement != undefined) {
if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
e.innerHTML = arr[i].value;
e = e.parentElement.getElementsByClassName("pell-content")[0];
}
}
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

187
js/2.0.2/xorc.js Normal file
View File

@ -0,0 +1,187 @@
const XORCipher = {
encode: function (key, data, seed) {
data = xor_encrypt(key, data, seed);
return b64_encode(data);
},
decode: function (key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
},
seed: function (n) {
return randString(n);
},
};
function stringToUtf8ByteArray(str) {
var out = [],
p = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) == 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return out;
}
function utf8ByteArrayToString(bytes) {
// array of bytes
var out = [],
pos = 0,
c = 0;
while (pos < bytes.length) {
var c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
var c2 = bytes[pos++];
out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
} else if (c1 > 239 && c1 < 365) {
// Surrogate Pair
var c2 = bytes[pos++];
var c3 = bytes[pos++];
var c4 = bytes[pos++];
var u =
(((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
0x10000;
out[c++] = String.fromCharCode(0xd800 + (u >> 10));
out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
} else {
var c2 = bytes[pos++];
var c3 = bytes[pos++];
out[c++] = String.fromCharCode(
((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
}
}
return out.join("");
}
var b64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function b64_encode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = (o1 << 16) | (o2 << 8) | o3;
h1 = (bits >> 18) & 0x3f;
h2 = (bits >> 12) & 0x3f;
h3 = (bits >> 6) & 0x3f;
h4 = bits & 0x3f;
enc +=
b64_table.charAt(h1) +
b64_table.charAt(h2) +
b64_table.charAt(h3) +
b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
}
function b64_decode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = b64_table.indexOf(data.charAt(i++));
h2 = b64_table.indexOf(data.charAt(i++));
h3 = b64_table.indexOf(data.charAt(i++));
h4 = b64_table.indexOf(data.charAt(i++));
bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
o1 = (bits >> 16) & 0xff;
o2 = (bits >> 8) & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randString(n) {
var r = "";
for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
return r;
}
function xor_encrypt(key, data, seed) {
if (typeof seed == "undefined") seed = randString(32);
var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
return r;
}
function xor_decrypt(key, data) {
var d = data,
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
r.splice(0, r.indexOf(0) + 1);
return utf8ByteArrayToString(r);
}
export default XORCipher;

493
js/2.0.3/buildHtmlForm.js Normal file
View File

@ -0,0 +1,493 @@
import { getFileName } from "./storage.js";
import pell from "./pell.js"
function buildHtmlForm(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//create sidebar set form button
let sidebarSetFormButton = document.createElement("li");
sidebarSetFormButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSetFormButton.style.borderTop = "2px solid #ddd";
sidebarSetFormButton.id = "sb-setform";
sidebarSetFormButton.innerHTML = "Set input as preset";
sidebarList.appendChild(sidebarSetFormButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
copyBtn.id = "fromCopyBtn";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = connectedListsArray[0].word;
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
label = document.createElement("LABEL");
label.innerHTML = '';
//div.classList.add("w3-center");
div.classList.replace("w3-flat-silver", "w3-flat-clouds");
div.appendChild(label);
div.appendChild(select3);
} else {
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
}
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
case "title":
let title = document.createElement("p");
title.classList.add("w3-xxlarge");
title.innerHTML = obj.word;
title.id = obj.word.replace(/ /g, "_");
title.setAttribute("tabindex", "-1");
title.style.cssText = "margin: 20px 0 0 0";
divContainer.className = "w3-container";
div.style.cssText = "padding: 0 10px";
div.appendChild(title);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
divContainer.classList.add("w3-animate-opacity")
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
if (obj.type == "title") {
sidebarListItem.setAttribute("data-item", "_title");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML = "<b>"+obj.word+"</b>";
}
sidebarList.appendChild(sidebarListItem);
}
function buildLongTextInput(source, textarea, label) {
if (!activeState.settings.enablePell) return;
//hide default textarea
textarea.style.display = "none";
label.style.display = "none";
let title = document.createElement("b");
title.innerText = label.innerText;
const editor = pell.init({
element: source,
defaultParagraphSeparator: "div",
actions: [
"bold",
"italic",
"underline",
"strikethrough",
"paragraph",
"heading1",
"heading2",
//{
// name: 'ulist',
// icon: '<b>•</b>'
//},
//"olist"
],
onChange: function (html) {
//correct lastElement
activeState.lastElement = textarea.id;
textarea.value = html;
},
});
let actionBar = editor.getElementsByClassName("pell-actionbar")[0];
let content = editor.getElementsByClassName("pell-content")[0];
let actionBarElements = actionBar.getElementsByClassName("pell-button");
let newActionBarElements = [];
for (let actionBarElement of actionBarElements ) {
actionBarElement.classList.add("w3-right");
actionBarElement.setAttribute("tabindex","-1");
newActionBarElements.push(actionBarElement);
}
//reverse actionbar back to org order
actionBar.innerHTML = "";
for (let newActionBarElement of newActionBarElements.reverse()) {
actionBar.appendChild(newActionBarElement);
}
actionBar.classList.add("w3-container");
actionBar.style.paddingLeft = "0px";
actionBar.appendChild(title);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default buildHtmlForm;

196
js/2.0.3/createTemplate.js Normal file
View File

@ -0,0 +1,196 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { hideMenus, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus("force");
resetPage();
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
if (!templates.includes('_textBlocks')) {
templates.push('_textBlocks');
}
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", activeState.settings.notifierPause);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

332
js/2.0.3/evts.js Normal file
View File

@ -0,0 +1,332 @@
import { createBookShelf, importBookShelf } from "./storage.js";
import {
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer,
} from "./web.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += " " + insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
if (element.parentElement != undefined) {
if (
element.parentElement.getElementsByClassName("pell-content")[0] !=
undefined
) {
element.parentElement.getElementsByClassName(
"pell-content"
)[0].innerHTML = element.value;
element = element.parentElement.getElementsByClassName("pell-content")[0];
}
}
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
}
function hideMenus(evt) {
if (evt === undefined) return;
if (evt != "force" && evt.target.parentElement != null) {
if (evt.target.parentElement.id == "navMob") return;
if (evt.target.parentElement.id == "navReg") return;
if (evt.target.parentElement.parentElement != null) {
if (evt.target.parentElement.parentElement.id == "navMob") return;
if (evt.target.parentElement.parentElement.id == "navReg") return;
}
}
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout = 3, closeable = true) {
let modalElement = document.getElementById("modalNotifier");
let modalElementCloseBtn = document.getElementById("modalNotifierClose");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
if (!closeable) modalElementCloseBtn.style.display = "none";
msgElement.innerHTML = msg;
if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function printVersion(msg = "") {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length - 2];
//add it to document footer currentVersion
versionSpan.textContent = msg + " version: " + pathVersion;
}
}
}
function clickImportFiles() {
if (activeState.settings.localOnly) {
createBookShelfDownload();
return;
}
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Imported!",
activeState.settings.notifierPause
);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display =
"none";
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: " +
activeState.serverFilesTs.replace("_", " - ") +
"<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0
);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
activeState.userId +
".txt' style='text-decoration: underline;' download>download</a> them?",
0
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0
);
}
function createBookShelfDownload() {
let data = createBookShelf();
let filename = data[0]["data"] + ".txt";
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," +
encodeURIComponent(JSON.stringify(data))
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
modalNotifier(
"Since you are in local only mode you can only export a backup of your files \
<br><br> \
<div class='w3-container'> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Export</button></div>",
0
);
}
function resetNavBar() {
//enable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "";
//enable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "block";
}
function wrongPwAlert() {
let wrongPWAlert = document.getElementById("wrongPWAlert");
wrongPWAlert.style.display = "block";
wrongPWAlert.addEventListener("click", (e) => {
if (e.target && e.target.tagName === "A") {
clearStorage();
document.getElementById("wrongPWAlert").innerHTML =
"<p>all files cleared - set new password</p>";
}
});
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function resetPage() {
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
let fileInfoDiv = document.getElementById("outputInfo");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
fileInfoDiv.innerHTML = "";
fileInfoDiv.replaceWith(fileInfoDiv.cloneNode(true));
fileInfoDiv.style.display = "none";
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
modalNotifier,
clickImportFiles,
resetNavBar,
printVersion,
wrongPwAlert,
copyToClipBoard,
resetPage
};

515
js/2.0.3/files.js Normal file
View File

@ -0,0 +1,515 @@
import { storeData, clearData, retrieveData, setTimeStamp } from "./storage.js";
import { loadTemplate } from "./web.js";
import parseForm from "./parseForm.js";
import { copyToClipBoard, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash } from "./scripts.js";
function buildFile() {
//set current page value in activeState object
activeState.activePage = "files";
//set templateFiles array
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
//console.log("none yet");
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Saved files";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//disable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "background-color:#9e9e9e !important";
target.style.borderBottom = "4px solid #9e9e9e";
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
resetPage();
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
let target = e.target.parentElement;
if (e.target.matches("li.w3-bar-item")) target = e.target;
if (target.classList.contains("w3-bar-item")) {
let fileName = target.dataset.file;
let template = target.dataset.template;
let pos = target.dataset.tfpos;
clickLoadFileDiv(fileName, template, pos);
}
});
}
function loadFileDiv(fileName, template, pos) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
pos = parseInt(pos) + 1;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
}
function loadFileDivCallBack() {
let tF = retrieveData("templateFiles");
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "_m21_" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-flat-pomegranate");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
let parsedTemplate = parseForm(true);
if (parsedTemplate == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
if (parsedTemplate == "") {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("File empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
div.appendChild(parsedTemplate);
fileDisplay.appendChild(div);
document.getElementById("mainForm").appendChild(fileDisplay);
//append TS info
let fileInfoDiv = document.getElementById("outputInfo");
let pos = "";
tF = retrieveData("templateFiles");
for (let tFi of tF) {
if (tFi.fileName == fN) {
pos = parseInt(tFi.pos);
}
}
let tsCreate = tF[pos].metadata.ts_create;
let created = "";
if (tsCreate != "") {
tsCreate =
tsCreate.current_time_long +
" " +
tsCreate.current_date +
"." +
tsCreate.current_year;
created = "";
created = "<tr><td>Created at</td><td>" + tsCreate + "</td></tr>";
}
let tsSave = tF[pos].metadata.ts_save;
let lastSaved = "";
if (tsSave != "") {
tsSave =
tsSave.current_time_long +
" " +
tsSave.current_date +
"." +
tsSave.current_year;
lastSaved = "";
lastSaved = "<tr><td>Last saved at</td><td>" + tsSave + "</td></tr>";
}
let tsCopy = tF[pos].metadata.ts_copy;
let lastCopy = "";
if (tsCopy != "") {
tsCopy =
tsCopy.current_time_long +
" " +
tsCopy.current_date +
"." +
tsCopy.current_year;
lastCopy = "";
lastCopy = "<tr><td>Last copied at</td><td>" + tsCopy + "</td></tr>";
}
let tsEdit = tF[pos].metadata.ts_edit;
let lastEdit = "";
if (tsEdit != "") {
tsEdit =
tsEdit.current_time_long +
" " +
tsEdit.current_date +
"." +
tsEdit.current_year;
lastEdit = "";
lastEdit = "<tr><td>Last edited at</td><td>" + tsEdit + "</td></tr>";
}
fileInfoDiv.innerHTML =
"<p><b>Fileinformation:</b></p>" +
"<table class='w3-table w3-bordered'>" +
"<tr><td>Template</td><td>" +
lT +
"</td></tr>" +
"<tr><td>ID</td><td>" +
pos + "." +
tF[pos].metadata.id +
"</td></tr>" +
created +
lastSaved +
lastCopy +
lastEdit +
"</table>"
fileInfoDiv.style.display = "block";
fileInfoDiv.classList.add("w3-third");
//fix min height of file display
try {
document.getElementById("fileDisplay").style.cssText = "min-height: 300px;";
} catch (e) {}
//fix fontsize for display
try {
document.getElementById("fileDisplay").firstChild.style.fontSize = "1em";
} catch (e) {}
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template, pos) {
if (fileName == "_overflow") return;
if (fileName == "_clearAll") {
clickClearAllFiles();
return;
}
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template, pos);
}
function clearFileData(storData) {
let fileName = storData.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
clearData(fileName);
clearData("userInputForce");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("outputInfo").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-padding-large");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Saved Files:";
sidebarList.appendChild(sidebarListItem);
let c = 0;
let sidebarItemsAmount = 6;
for (let obj of tF.reverse()) {
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
//handle to many files on screen and display hidden files amount
if (c > sidebarItemsAmount) {
sidebarListItem.setAttribute("data-template", "_overflow");
sidebarListItem.setAttribute("data-file", "_overflow");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML =
tF.length - sidebarItemsAmount + " files not shown";
sidebarList.appendChild(sidebarListItem);
break;
}
let sidebarListItemTitle = document.createElement("p");
sidebarListItemTitle.innerText = obj.fileName.replace(/_/g, " ");
sidebarListItemTitle.style.cssText = "margin: 0;";
let sidebarListItemInfo = document.createElement("span");
sidebarListItemInfo.classList.add("w3-small");
sidebarListItemInfo.innerText =
"created at: " +
obj.metadata.ts_create.current_time +
" - " +
obj.metadata.ts_create.current_date;
sidebarListItem.appendChild(sidebarListItemTitle);
sidebarListItem.append(sidebarListItemInfo);
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarListItem.setAttribute("data-tFPos", obj.pos);
sidebarList.appendChild(sidebarListItem);
c++;
}
//clear all files button
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button");
sidebarListItem.setAttribute("data-template", "_clearAll");
sidebarListItem.setAttribute("data-file", "_clearAll");
sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.style.width = "300px";
sidebarListItem.innerHTML = "Clear all files";
sidebarList.appendChild(sidebarListItem);
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return (
"<div id='fileDisplay' class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" +
msg +
"</p><br><br><br><br><br><br><br><br><br><br><br></div></div>"
);
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
editSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-carrot"
);
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-carrot",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
modalNotifier(
activeState.fileName + " copied to clipboard",
activeState.settings.notifierPause
);
break;
case "Delete":
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
let delFileName = activeState.fileName;
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(
previousFile.fileName,
previousFile.template,
previousFile.pos
);
} else {
document.getElementById("mainForm").innerHTML =
mainFormPlaceholder("No file yet");
}
modalNotifier(
delFileName + " deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
}
function editSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("_m21_")[0], storageName.split("_m21_")[1])
);
//reset sidebar to clear events
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
//reset navbar above all else
resetNavBar();
//reset correct activePage
activeState.activePage = "template";
//set edit timestamp
setTimeStamp("edit");
loadTemplate(storageName.split("_m21_")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i - 1];
if (previousFile === undefined) {
//get the next one if there is no previous one
previousFile = tF[i + 1];
}
break;
}
i++;
}
return previousFile != undefined ? previousFile : false;
}
function clickClearAllFiles() {
let modal = document.getElementById("modalMsg");
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Delete":
clearAllFiles();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"All files deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
<p>Would you really like to delete all stored files?</p> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button>",
0
);
}
function clearAllFiles() {
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
for (let storageName of tF) {
clearFileData(storageName.fileName);
}
}
export { buildFile, loadFileDivCallBack };

296
js/2.0.3/form.js Normal file
View File

@ -0,0 +1,296 @@
import { retrieveData, storeData, createStorageObj } from "./storage.js";
import parseTemplate from "./parseTemplate.js";
import buildHtmlForm from "./buildHtmlForm.js";
import { copyToClipBoard, handleOnBlur, modalNotifier, resetPage } from "./evts.js";
import parseForm, { parseTextMarkups } from "./parseForm.js";
import { setTemplatePreset } from "./web.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
let placeholder;
try {
placeholder = JSON.parse(jsonPlaceholder);
} catch (e) {
placeholder = ""
}
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", placeholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseTemplate Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseTemplate(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
activeState.templateObjects = objects;
activeState.fullString = templateInput;
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
activeState.templateObjectsPurified = objectsPurified;
//reset page and event listeners
resetPage();
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) return;
buildHtmlForm(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj("copy");
copyToClipBoard(parseForm());
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
e.target.value = "Copied";
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
const timeoutCopy = setTimeout(() => {
//e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
//e.target.value = "Copy";
e.target.style.pointerEvents = "auto";
}, 5000);
break;
case "Save":
createStorageObj("save");
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause);
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause);
}
if (e.target.id == "sb-setform") {
createStorageObj("setform");
let dataArray = retrieveData("userInput");
let lT = activeState.loadedTemplate;
console.log(lT, dataArray);
//setTemplatePreset(lT, dataArray);
modalNotifier("Input saved as preset", activeState.settings.notifierPause);
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener to each form object
let mainForm = document.getElementById("mainFormObj");
for (let formElement of mainForm.children) {
if (formElement.firstChild.lastChild == null) continue;
let id = formElement.firstChild.lastChild.id;
document.getElementById(id).addEventListener("blur", (e) => {
e.preventDefault;
handleOnBlur(e.target);
});
}
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
if (targetElement == null) return;
//handle pell content focus
if (targetElement.parentElement != undefined) {
if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0];
}
}
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/2.0.3/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

182
js/2.0.3/init.js Normal file
View File

@ -0,0 +1,182 @@
import {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
clickImportFiles,
modalNotifier,
printVersion,
copyToClipBoard
} from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, {
passwordHash,
inputRead
} from "./scripts.js";
import parseForm from "./parseForm.js";
import { createStorageObj, retrieveData, storeSettings } from "./storage.js";
import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js";
window.activeState = {
userId: "",
sessionToken: "",
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
settings: {
localOnly: true,
lineBreak: 120,
font: "Arial",
fontSize: "10px",
notifierPause: 1,
persistentStorage: false,
enablePell: false,
debug: false
},
templates: [],
templateObjectsPurified: [],
templateObjects: [],
fullString: "",
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
"title",
],
markups: ["title", "link", "italic", "green_highlighted", "highlighted"],
storage: [],
orgPage: {
main: {},
sidebar: {}
}
};
function init() {
//init passwordhash to retrieve cookie info and set passwordHash
passwordHash.initHash();
//check if user is logged in
if (passwordHash.verify()) {
//user logged in
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load settings from storage and apply
let settings = storeSettings("getInit", true);
if (settings != null) {
for (let setting of Object.entries(settings)) {
if (typeof(setting[1]) == "string" && setting[1].toLowerCase() === "true") setting[1] = true;
if (typeof(setting[1]) == "string" && setting[1].toLowerCase() === "false") setting[1] = false;
activeState.settings[setting[0]] = setting[1];
}
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version and storage mode to footer
let msg = (activeState.settings.persistentStorage) ? "persistent" : "temporary";
printVersion("storage mode: "+msg+" |");
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
//backup landing page
activeState.orgPage.sidebar = document.getElementById("sidebar").childNodes;
activeState.orgPage.main = document.getElementById("mainForm").childNodes;
}
function eventListeners() {
//add hideMenu to Body
document
.body
.addEventListener("click", (e) => hideMenus(e));
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
/* document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu); */
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
inputRead.init();
window.addEventListener("keydown", (e) => {
if (activeState.activePage == "template") {
inputRead.read(e);
if (e.ctrlKey && e.key == "s") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File copied to clipboard", activeState.settings.notifierPause);
let copyButton = document.getElementById("fromCopyBtn");
copyButton.className = "w3-button w3-flat-carrot";
copyButton.value = "Copied";
e.preventDefault();
}
}
});
//add url listener
window.addEventListener("hashchange", (e) => {
let newURLArr = e.newURL.split("/");
let template;
if (newURLArr != undefined) {
template = newURLArr[newURLArr.length -1];
if (template != undefined) {
template = template.split("=")[1];
if (template != undefined) {
if (activeState.templates.includes("")) {
loadNewTemplate(template);
}
}
}
}
});
}
init();

384
js/2.0.3/parseForm.js Normal file
View File

@ -0,0 +1,384 @@
import { clearData, retrieveData } from "./storage.js";
function parseForm(returnDIV = false) {
//get user Inout Data from preset or from file
let dataArray = [];
if (returnDIV) {
dataArray = retrieveData("userInputForce");
clearData("userInputForce");
} else {
dataArray = retrieveData("userInput");
}
//if the decryption went wrong return null
if (dataArray == null) return dataArray;
//if there are no files yet return empty array
if (dataArray == []) return "";
//get original objects from sessionstorage gen from loadTemplate
let objects = activeState.templateObjects;
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = activeState.fullString;
//define output buffer
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
obj.result = "";
//compaire each obj with elements from mainFormObj
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
//if obj is the connected list main selector
if (data.name.split("-")[0] == "clM") {
//if connected list main matches current object
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
//set flag for next iteration of loop
conListFlag = true;
data.name = data.name.substring(4);
//selection is not added to buffer
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
//if field matches current object
if (obj.word.replace(/ /g, "_") == data.name) {
let value = parseDataForResult(obj, data.value);
if (value == "!none") value = "";
obj.result = value;
}
//handle conlist elements for parsing each element
if (conListFlag && obj.type == "conList") {
let value = parseConListForResult(obj, data, dataArray);
if (value == "!none") value = "";
obj.result = value;
continue;
}
}
}
//build final output string by inserting objects
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
let tepos = objects[i].epos;
//skip empty results by skipping the newline char
if (objects[i].result == "") tepos += 1;
b +=
objects[i].result +
fullString.substring(tepos, objects[j].spos);
}
}
//sanitizing final output string
let bHtml = b;
//remove newline
bHtml = bHtml.replace(/!\w{1,2}\n/g, "");
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
bHtml = bHtml.replace(/ /g, "&nbsp;");
bHtml = bHtml.replace(/(?:\r\n|\r|\n)/g, "<br />");
bHtml = bHtml.replace(/<\/div>/g, '<br />');
bHtml = bHtml.replace(/<div>/g, '');
/* if (activeState.settings.enablePell) {
bHtml = bHtml.replace(/!l /g, "");
bHtml = bHtml.replace(/!n /g, "");
bHtml = bHtml.replace(/!ls /g, "");
} else {
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
} */
//creating output div
let divContent = document.createElement("div");
divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
divContent.style.fontSize = activeState.settings.fontSize;
divContent.innerHTML = bHtml;
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.appendChild(divContent);
if (returnDIV) {
return div;
} else {
return bHtml;
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
//parse global linebreak after marked text was already fixed
value = parseGlobalLineBreak(value);
return value;
}
function parseConListForResult(obj, data, dataArray) {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
}
}
return ""
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
if (dataArray[i] == "") continue;
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
continue;
}
//check if list indicator has been set and adjust userInput accordingly
let listIndicator = "";
if (listNumberFlag) {
listIndicator = " " + listNumberFlagNum + ". ";
listNumberFlagNum++;
}
if (listSubFlag && listIndicator == "") listIndicator = " ○ ";
if (listFlag && listIndicator == "") listIndicator = " • ";
//exclude settings if pell is enabled
//if (activeState.settings.enablePell) listIndicator = "";
//handle global linebreak and fit according to indicator according to list indicator
if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function parseGlobalLineBreak(data) {
//parse each line of input with parseLineBreak return condensed string with newlines
let parsedData = '';
for (let line of data.split('\n')) {
let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
if (parsedData != '') {
parsedData = parsedData + '\n' + parsedLine;
} else {
parsedData = parsedLine;
}
}
return parsedData
}
function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
//add 5 chars buffer to fix list intendation issue
//each input field gets parsed line by line twice once for list inputs and a second time for each input
let lines;
if (line.length > lineBreak) {
//create linebreak in between second to last word
let correctedLineBreak;
let newLineStart;
let cLBt = lineBreak-(intendation*2)
//find last space before linebreak
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
//and fix the next lines start
newLineStart = correctedLineBreak+1;
//add to parsed output
lines = line.substring(0, correctedLineBreak);
//delete first parsed output from inputstring
line = line.substring(newLineStart);
let intendationSpaces = '';
//check if an intendation is given if so convert it to correct spaces
if (intendation != 0) intendationSpaces = ' '.repeat(intendation);
//start loop to parse rest of the string
while(line.length > lineBreak) {
let cLBt = lineBreak-(intendation*2)
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
newLineStart = correctedLineBreak+1;
//add to output with intendation if given
lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
//delete from input
line = line.substring(newLineStart);
}
//process rest of the string with correct intendation
lines += "\n" + intendationSpaces + line;
} else {
//if string is within lineBreak just forward input to output
lines = line;
}
return lines;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
export default parseForm;

388
js/2.0.3/parseTemplate.js Normal file
View File

@ -0,0 +1,388 @@
function parseTemplate(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//bugfix if the title of an input has no space in it ex: %test=l:first word;l:second word;%1
let oneWordFlag = false;
if (word.substring(0, 1) == "%" && word.indexOf('=') != -1) {
oneWordFlag = true;
}
//for loop to escape spaces in simple input
for (let j = i+1; j < wordArray.length; j++) {
//if title has no space then go back one word to include "=" ex:
if (oneWordFlag) {
j = i;
oneWordFlag = false;
} else {
w = w + " " + wordArray[j];
}
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseTemplate;

254
js/2.0.3/pell.js Normal file
View File

@ -0,0 +1,254 @@
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? factory(exports)
: typeof define === "function" && define.amd
? define(["exports"], factory)
: factory((globalThis.pell = {}));
})(this, function (exports) {
"use strict";
var _extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var defaultParagraphSeparatorString = "defaultParagraphSeparator";
var formatBlock = "formatBlock";
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
state: function state() {
return queryCommandState("bold");
},
result: function result() {
return exec("bold");
},
},
italic: {
icon: "<i>I</i>",
title: "Italic",
state: function state() {
return queryCommandState("italic");
},
result: function result() {
return exec("italic");
},
},
underline: {
icon: "<u>U</u>",
title: "Underline",
state: function state() {
return queryCommandState("underline");
},
result: function result() {
return exec("underline");
},
},
strikethrough: {
icon: "<strike>S</strike>",
title: "Strike-through",
state: function state() {
return queryCommandState("strikeThrough");
},
result: function result() {
return exec("strikeThrough");
},
},
heading1: {
icon: "<b>H<sub>1</sub></b>",
title: "Heading 1",
result: function result() {
return exec(formatBlock, "<h1>");
},
},
heading2: {
icon: "<b>H<sub>2</sub></b>",
title: "Heading 2",
result: function result() {
return exec(formatBlock, "<h2>");
},
},
paragraph: {
icon: "&#182;",
title: "Paragraph",
result: function result() {
return exec(formatBlock, "<p>");
},
},
quote: {
icon: "&#8220; &#8221;",
title: "Quote",
result: function result() {
return exec(formatBlock, "<blockquote>");
},
},
olist: {
icon: "&#35;",
title: "Ordered List",
result: function result() {
return exec("insertOrderedList");
},
},
ulist: {
icon: "&#8226;",
title: "Unordered List",
result: function result() {
return exec("insertUnorderedList");
},
},
code: {
icon: "&lt;/&gt;",
title: "Code",
result: function result() {
return exec(formatBlock, "<pre>");
},
},
line: {
icon: "&#8213;",
title: "Horizontal Line",
result: function result() {
return exec("insertHorizontalRule");
},
},
link: {
icon: "&#128279;",
title: "Link",
result: function result() {
var url = window.prompt("Enter the link URL");
if (url) exec("createLink", url);
},
},
image: {
icon: "&#128247;",
title: "Image",
result: function result() {
var url = window.prompt("Enter the image URL");
if (url) exec("insertImage", url);
},
},
};
var defaultClasses = {
actionbar: "pell-actionbar",
button: "pell-button",
content: "pell-content",
selected: "pell-button-selected",
};
var init = function init(settings) {
var actions = settings.actions
? settings.actions.map(function (action) {
if (typeof action === "string") return defaultActions[action];
else if (defaultActions[action.name])
return _extends({}, defaultActions[action.name], action);
return action;
})
: Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator =
settings[defaultParagraphSeparatorString] || "div";
var actionbar = createElement("div");
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = (settings.element.content = createElement("div"));
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3)
exec(formatBlock, "<" + defaultParagraphSeparator + ">");
else if (content.innerHTML === "<br>") content.innerHTML = "";
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (
event.key === "Enter" &&
queryCommandValue(formatBlock) === "blockquote"
) {
setTimeout(function () {
return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement("button");
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute("type", "button");
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? "add" : "remove"](
classes.selected
);
};
addEventListener(content, "keyup", handler);
addEventListener(content, "mouseup", handler);
addEventListener(button, "click", handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec("styleWithCSS");
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports["default"] = pell;
Object.defineProperty(exports, "__esModule", { value: true });
});
export default pell;

213
js/2.0.3/scripts.js Normal file
View File

@ -0,0 +1,213 @@
import { createStorageObj, retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
import { wrongPwAlert } from "./evts.js";
export const passwordHash = {
name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
toString: function () {
let token = window.activeState.sessionToken;
if (token == null) return "";
if (token == "") return "";
return XORCipher.decode(this.name, token);
},
set: function (pw) {
if (pw == "") return;
activeState.sessionToken = XORCipher.encode(this.name, sha256(pw));
},
initHash: function () {
//check if cookie exists
if (getCookie(this.name) != null) {
if (getCookie(this.name) != "") {
this.set(XORCipher.decode(this.name, getCookie(this.name)));
}
}
if (retrieveData("templateFiles") != null) {
//set user id
activeState.userId = passwordHash.name;
setCookie(this.name, XORCipher.encode(this.name, this), 10);
}
},
verify: function () {
if (passwordHash == "") return false;
return (retrieveData("templateFiles") != null) ? true : false;
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = sanitize(x.elements[0].value);
if (pw != "" || pw !== "undefined") {
passwordHash.set(pw);
let tF = retrieveData("templateFiles");
if (tF == null) {
wrongPwAlert();
passwordHash.set("");
x.elements[0].value = "";
return;
}
//user logged in
//make sure to bring back persistent stat after logout
activeState.settings.persistentStorage = "true";
tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
activeState.settings.persistentStorage = "false";
}
activeState.userId = passwordHash.name;
document.getElementById("login").style.display = "none";
setCookie(passwordHash.name, XORCipher.encode(passwordHash.name, passwordHash), 10)
}
}
export function cyrb53(str, seed = 21) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Lax";
}
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
export function logout() {
let id = passwordHash.name;
activeState.sessionToken = "";
setCookie(passwordHash.name, "", 10);
document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.getElementById("passwordField").value = "";
document.getElementById("login").style.display = "block";
}
export function sanitize(string) {
const map = {
'&': '_',
'<': '_',
'>': '_',
'"': '_',
"'": '_',
'/': '_',
'`': '_',
'=': '_'
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
export function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
export const inputRead = {
init: function () {
this.event = "";
this.inputString = "";
this.source = "";
this.inputContent = "";
this.lastRunTime = new Date();
this.target = document.getElementById("toggleFilesMenu");
this.lastExecId = "";
},
read: function (event) {
this.event = event;
this.source = event.srcElement.id;
if (event.target.className == "pell-content") {
this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
}
let previousContent = this.inputContent;
let key = (event.key !=undefined) ? event.key : "";
let contentElement = document.getElementById(this.source);
this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
if (this.inputContent == "" || key == "") return;
if (key.length > 1 && key != "Backspace" && key != "Delete" && key != "Enter") return;
if (event.ctrlKey) return;
if (this.inputContent == previousContent) return;
this.lastRunTime = new Date();
clearTimeout(this.lastExecId);
this.target.style.borderBottom = "3px solid #c0392b";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-save");
this.target.appendChild(i);
this.lastExecId = setTimeout(() => {
createStorageObj("save");
this.target.style.borderBottom = "none";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
this.target.appendChild(i);
}, 1000);
},
}
export function getCurrentDate() {
let date = new Date();
let uts = Date.now();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
let current_second = date.getSeconds();
current_second = current_second <= 9 ? "0" + current_second : current_second;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_day = date.getDate();
current_day = current_day <= 9 ? "0" + current_day : current_day;
let current_year = date.getFullYear();
let current_time = current_hour + ":" + current_minute;
let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
let current_date = current_day + "." + current_month;
return {
current_time: current_time,
current_time_long: current_time_long,
current_date: current_date,
current_year: current_year,
uts: uts
};
}
export default setPassword;

198
js/2.0.3/settings.js Normal file
View File

@ -0,0 +1,198 @@
import { hideMenus, modalNotifier, printVersion, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
import { retrieveData, storeData, storeSettings } from "./storage.js";
const buildSettings = () => {
//set current page value in activeState object
activeState.activePage = "settings";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Settings";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
resetPage();
addSidebar();
buildForm();
//add events
formEvts();
};
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
saveSettings();
modalNotifier(
"Settings saved!",
activeState.settings.notifierPause
);
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-nephritis"
);
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-nephritis",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
}
function buildForm() {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let settings = storeSettings("get", true);
if (settings == "") settings = activeState.settings;
for (let setting of Object.entries(settings)) {
buildField(setting, form);
}
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
}
function buildField(obj, form) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj[0]);
input.setAttribute("id", obj[0]);
input.classList.add("w3-input");
input.id = obj[0];
input.value = obj[1];
label.innerHTML = obj[0];
div.appendChild(label);
div.appendChild(input);
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
}
function addSidebar() {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Edit Settings"
sidebarList.appendChild(sidebarListItem);
document.getElementById("sidebar").appendChild(sidebarList);
}
function saveSettings() {
let x = document.getElementById("mainFormObj");
let obj = {};
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
let name = x.elements[i].name;
let value = x.elements[i].value;
obj[name] = sanitize(value);
}
for (let setting of Object.entries(obj)) {
if (activeState.settings[setting[0]] != setting[1]) {
//change detected
if (setting[0] == "persistentStorage") {
//get tF from old storage
let tF = retrieveData("templateFiles");
//get previous settings
let settings = storeSettings("get", true);
//store the new settings in old storage
storeSettings(obj);
//apply the new setting
activeState.settings[setting[0]] = setting[1];
//store the new settings in the new storage
if (settings != "") storeSettings(obj);
//transfer tF
if (tF != null) storeData("templateFiles", tF);
let msg = (!activeState.settings.persistentStorage) ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
}
}
activeState.settings[setting[0]] = setting[1];
}
storeSettings(obj);
}
export default buildSettings;

3
js/2.0.3/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

369
js/2.0.3/storage.js Normal file
View File

@ -0,0 +1,369 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { cyrb53, getCurrentDate, passwordHash, sanitize } from "./scripts.js";
const store = {
getItem: function (key) {
return debug("GET", key, getStor().getItem(sha256(key + activeState.userId)));
},
setItem: function (key, data) {
debug("SET", key, "setItem: "+data);
getStor().setItem(sha256(key + activeState.userId), data);
},
removeItem: function (key) {
debug("REMOVE", key);
getStor().removeItem(sha256(key + activeState.userId));
},
clear: function () {
debug("CLEARALL", "");
getStor().clear();
},
};
const tempStore = {
setItem: function (key, data) {
globalThis.activeState.storage[key] = data;
},
getItem: function (key) {
return globalThis.activeState.storage[key];
},
removeItem: function (key) {
globalThis.activeState.storage[key] = "";
},
clear: function () {
globalThis.activeState.storage = [];
},
};
function getStor() {
if (window.activeState.settings.persistentStorage) {
return window.localStorage;
} else {
return tempStore;
}
}
function debug(mode, key, data) {
if (activeState.settings.debug == "false") return data;
if (activeState.settings.debug == false) return data;
console.log({
mode: mode,
key: key,
data: (data != null) ? data.substring(0,10): "",
persistent: activeState.settings.persistentStorage
});
return data;
}
function createStorageObj(ref = "none") {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
if (x.elements[i].name == "") continue;
let parsedContent = x.elements[i].value;
parsedContent = parsedContent.replace(/<div>/g, "");
parsedContent = parsedContent.replace(/<\/div>/g, "\n");
if (ref == "setform") {
//parse pell content remove html tags
parsedContent = parsedContent.replace(/<.{1,4}>/g, "");
}
x.elements[i].value = parsedContent;
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//set current filename according to filenamefield
setCurrentFileName();
//set savetime in templateFiles
setTimeStamp(ref);
//store files with preset filename
storeData("userInput", dataArray);
}
function storeData(name, data) {
if (passwordHash == "") return;
data = JSON.stringify(data);
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName();
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
store.setItem(key, obfuscate(data));
}
function retrieveData(name, template = "none") {
if (passwordHash == "") return null;
if (name == "userInput") {
if (activeState.fileName != "") {
name = activeState.fileName;
} else {
return [];
}
}
if (name == "userInputForce") {
name = "userInput";
}
let cdata;
let key;
if (template == "none") {
let lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
key = name + "_m21_" + template;
}
cdata = store.getItem(key);
if (cdata != null) {
cdata = obfuscate(cdata, false);
let data;
try {
data = JSON.parse(cdata);
} catch (e) {
data = null;
}
return data;
} else {
return [];
}
}
function clearData(name, template = "none") {
let lT;
let key;
if (name == "userInputForce") name = "userInput";
if (template == "none") {
lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
lT = template;
key = name + "_m21_" + template;
}
store.removeItem(key);
}
function getFileName() {
let currentFileName = activeState.fileName;
let lT = activeState.loadedTemplate;
if (currentFileName == "none" || currentFileName == "") {
let date = getCurrentDate();
currentFileName = date.current_time + "_" + date.current_date + " " + lT;
//console.log(currentFileName);
}
let tF = retrieveData("templateFiles");
const metadata = {
ts_create: getCurrentDate(),
ts_save: "",
ts_copy: "",
ts_edit: "",
id: cyrb53(currentFileName),
editor: (activeState.settings.enablePell) ? "pell": "textarea"
};
if (tF.length != 0) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {
return currentFileName;
}
}
tF.push({
fileName: currentFileName,
template: lT,
metadata: metadata,
pos: tF.length,
});
} else {
tF = [
{ fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
];
}
storeData("templateFiles", tF);
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if ((data == null) | (data == "")) return "";
if (mode) {
return XORCipher.encode(passwordHash, data);
} else {
return XORCipher.decode(passwordHash, data);
}
}
function popFromTemplateFiles(fileName) {
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
}
function createBookShelf() {
let tF = retrieveData("templateFiles");
let bookShelf = {};
let date = getCurrentDate();
let saveFileName = date.current_time + "_" + date.current_date;
if (tF != null) {
bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
if (activeState.settings.localOnly == "true") {
bookShelf[i].data = data;
} else {
bookShelf[i].data = obfuscate(data);
}
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
store.setItem(file.name, file.data);
templateFilesArray.push({
fileName: file.name.split("_m21_")[0],
template: file.name.split("_m21_")[1],
});
}
store.setItem(
"templateFiles_m21_" + activeState.userId,
obfuscate(JSON.stringify(templateFilesArray))
);
}
}
};
xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
xhttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhttp.send();
}
function storeSettings(data, get = false) {
let key = "settings_m21_" + activeState.userId;
if (get) {
let cdata = "";
if (data == "getInit") {
activeState.settings.persistentStorage = "true";
}
try {
cdata = JSON.parse(obfuscate(store.getItem(key), false));
} catch (e) {
cdata = "";
}
if (data == "getInit") {
activeState.settings.persistentStorage = "false";
}
return cdata;
} else {
store.setItem(key, obfuscate(JSON.stringify(data)));
}
}
function clearStorage() {
store.clear();
}
function setCurrentFileName() {
activeState.fileName = "";
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
}
function setTimeStamp(type) {
if (activeState.fileName != "") {
let tF = retrieveData("templateFiles");
if (tF.length != 0) {
let c = 0;
for (let tFi of tF) {
if (tFi.fileName == activeState.fileName) {
switch (type) {
case "save":
tF[c].metadata.ts_save = getCurrentDate();
break;
case "copy":
tF[c].metadata.ts_copy = getCurrentDate();
break;
case "edit":
tF[c].metadata.ts_edit = getCurrentDate();
break;
}
storeData("templateFiles", tF);
}
c += 1;
}
}
}
}
export {
createStorageObj,
storeData,
retrieveData,
clearData,
getFileName,
createBookShelf,
importBookShelf,
storeSettings,
clearStorage,
setCurrentFileName,
setTimeStamp
};

386
js/2.0.3/web.js Normal file
View File

@ -0,0 +1,386 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName } from "./storage.js";
import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { logout, passwordHash } from "./scripts.js";
import buildSettings from "./settings.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
clearData("userInputForce");
}
if (cdata != "") {
if (cdata != null) {
retrieveForm(cdata);
}
}
//select first object and focus on it
let obj = activeState.templateObjectsPurified;
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//reset navbar above all else
resetNavBar();
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText);
return;
}
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "javascript:void(0)");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!settings");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Settings";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!logout");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
createEntry.innerHTML = "Logout";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
e.preventDefault;
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "!createNew") {
createTemplate();
return;
}
if (template == "!logout") {
logout();
return;
}
if (template == "!settings") {
buildSettings();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText)
return;
}
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
if (res[x][1].length < 1) continue;
let aReg = document.createElement("a");
aReg.setAttribute("href", "javascript:void(0)");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: JSON.stringify(formData),
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].name == "") continue;
let e = document.getElementById(arr[i].name);
if (e === null) {
//parse connected list
let id = arr[i].name.split("cl-")[1];
//escape cl-text:!ls
if (id != undefined) id = id.split(":")[0];
e = document.getElementById(id);
if (e === null) {
//parse connected list main
let id = arr[i].name.split("clM-")[1];
e = document.getElementById(id);
if (e === null) continue;
}
}
//handle connected list Main item button or list
if (e.name.substr(0, 4) == "clM-") {
if (arr[i].value != "!none") {
let clElement = document.getElementById(e.dataset.word);
if (clElement === null) {
clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
}
//make shure it is visible if selected before
if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
e.value = arr[i].value;
}
continue;
}
switch (e.nodeName) {
case "TEXTAREA":
//clean pell attributes for raw input in textarea
arr[i].value = arr[i].value.replace(/<div>/g, "");
arr[i].value = arr[i].value.replace(/<\/div>/g, "\n");
arr[i].value = arr[i].value.replace(/<.{1,4}>/g, "");
//check if pell was used
if (e.parentElement != undefined) {
if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
let contentArray = arr[i].value.split("\n");
let parsedContent = "";
if (contentArray.length != 0) {
for (let contentLine of contentArray) {
if (contentLine != "") {
contentLine = "<div>" + contentLine + "</div>";
}
parsedContent += contentLine;
}
} else {
parsedContent = arr[i].value;
}
e.innerHTML = arr[i].value;
arr[i].value = parsedContent;
e = e.parentElement.getElementsByClassName("pell-content")[0];
}
}
//append raw input to textarea or parsed content to pell content
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

187
js/2.0.3/xorc.js Normal file
View File

@ -0,0 +1,187 @@
const XORCipher = {
encode: function (key, data, seed) {
data = xor_encrypt(key, data, seed);
return b64_encode(data);
},
decode: function (key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
},
seed: function (n) {
return randString(n);
},
};
function stringToUtf8ByteArray(str) {
var out = [],
p = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) == 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return out;
}
function utf8ByteArrayToString(bytes) {
// array of bytes
var out = [],
pos = 0,
c = 0;
while (pos < bytes.length) {
var c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
var c2 = bytes[pos++];
out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
} else if (c1 > 239 && c1 < 365) {
// Surrogate Pair
var c2 = bytes[pos++];
var c3 = bytes[pos++];
var c4 = bytes[pos++];
var u =
(((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
0x10000;
out[c++] = String.fromCharCode(0xd800 + (u >> 10));
out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
} else {
var c2 = bytes[pos++];
var c3 = bytes[pos++];
out[c++] = String.fromCharCode(
((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
}
}
return out.join("");
}
var b64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function b64_encode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = (o1 << 16) | (o2 << 8) | o3;
h1 = (bits >> 18) & 0x3f;
h2 = (bits >> 12) & 0x3f;
h3 = (bits >> 6) & 0x3f;
h4 = bits & 0x3f;
enc +=
b64_table.charAt(h1) +
b64_table.charAt(h2) +
b64_table.charAt(h3) +
b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
}
function b64_decode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = b64_table.indexOf(data.charAt(i++));
h2 = b64_table.indexOf(data.charAt(i++));
h3 = b64_table.indexOf(data.charAt(i++));
h4 = b64_table.indexOf(data.charAt(i++));
bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
o1 = (bits >> 16) & 0xff;
o2 = (bits >> 8) & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randString(n) {
var r = "";
for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
return r;
}
function xor_encrypt(key, data, seed) {
if (typeof seed == "undefined") seed = randString(32);
var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
return r;
}
function xor_decrypt(key, data) {
var d = data,
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
r.splice(0, r.indexOf(0) + 1);
return utf8ByteArrayToString(r);
}
export default XORCipher;

493
js/2.0.4/buildHtmlForm.js Normal file
View File

@ -0,0 +1,493 @@
import { getFileName } from "./storage.js";
import pell from "./pell.js"
function buildHtmlForm(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//create sidebar set form button
let sidebarSetFormButton = document.createElement("li");
sidebarSetFormButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSetFormButton.style.borderTop = "2px solid #ddd";
sidebarSetFormButton.id = "sb-setform";
sidebarSetFormButton.innerHTML = "Set input as preset";
sidebarList.appendChild(sidebarSetFormButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
copyBtn.id = "fromCopyBtn";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align", "w3-padding-16");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = connectedListsArray[0].word;
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
label = document.createElement("LABEL");
label.innerHTML = '';
//div.classList.add("w3-center");
div.classList.replace("w3-flat-silver", "w3-flat-clouds");
div.appendChild(label);
div.appendChild(select3);
} else {
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
}
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
buildLongTextInput(div, textarea, label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
case "title":
let title = document.createElement("p");
title.classList.add("w3-xxlarge");
title.innerHTML = obj.word;
title.id = obj.word.replace(/ /g, "_");
title.setAttribute("tabindex", "-1");
title.style.cssText = "margin: 20px 0 0 0";
divContainer.className = "w3-container";
div.style.cssText = "padding: 0 10px";
div.appendChild(title);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
divContainer.classList.add("w3-animate-opacity")
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
if (obj.type == "title") {
sidebarListItem.setAttribute("data-item", "_title");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML = "<b>"+obj.word+"</b>";
}
sidebarList.appendChild(sidebarListItem);
}
function buildLongTextInput(source, textarea, label) {
if (!activeState.settings.enablePell) return;
//hide default textarea
textarea.style.display = "none";
label.style.display = "none";
let title = document.createElement("b");
title.innerText = label.innerText;
const editor = pell.init({
element: source,
defaultParagraphSeparator: "div",
actions: [
"bold",
"italic",
"underline",
"strikethrough",
"paragraph",
"heading1",
"heading2",
//{
// name: 'ulist',
// icon: '<b>•</b>'
//},
//"olist"
],
onChange: function (html) {
//correct lastElement
activeState.lastElement = textarea.id;
textarea.value = html;
},
});
let actionBar = editor.getElementsByClassName("pell-actionbar")[0];
let content = editor.getElementsByClassName("pell-content")[0];
let actionBarElements = actionBar.getElementsByClassName("pell-button");
let newActionBarElements = [];
for (let actionBarElement of actionBarElements ) {
actionBarElement.classList.add("w3-right");
actionBarElement.setAttribute("tabindex","-1");
newActionBarElements.push(actionBarElement);
}
//reverse actionbar back to org order
actionBar.innerHTML = "";
for (let newActionBarElement of newActionBarElements.reverse()) {
actionBar.appendChild(newActionBarElement);
}
actionBar.classList.add("w3-container");
actionBar.style.paddingLeft = "0px";
actionBar.appendChild(title);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default buildHtmlForm;

196
js/2.0.4/createTemplate.js Normal file
View File

@ -0,0 +1,196 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { hideMenus, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus("force");
resetPage();
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
if (!templates.includes('_textBlocks')) {
templates.push('_textBlocks');
}
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", activeState.settings.notifierPause);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

332
js/2.0.4/evts.js Normal file
View File

@ -0,0 +1,332 @@
import { createBookShelf, importBookShelf } from "./storage.js";
import {
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer,
} from "./web.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += " " + insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
if (element.parentElement != undefined) {
if (
element.parentElement.getElementsByClassName("pell-content")[0] !=
undefined
) {
element.parentElement.getElementsByClassName(
"pell-content"
)[0].innerHTML = element.value;
element = element.parentElement.getElementsByClassName("pell-content")[0];
}
}
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
}
function hideMenus(evt) {
if (evt === undefined) return;
if (evt != "force" && evt.target.parentElement != null) {
if (evt.target.parentElement.id == "navMob") return;
if (evt.target.parentElement.id == "navReg") return;
if (evt.target.parentElement.parentElement != null) {
if (evt.target.parentElement.parentElement.id == "navMob") return;
if (evt.target.parentElement.parentElement.id == "navReg") return;
}
}
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout = 3, closeable = true) {
let modalElement = document.getElementById("modalNotifier");
let modalElementCloseBtn = document.getElementById("modalNotifierClose");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
if (!closeable) modalElementCloseBtn.style.display = "none";
msgElement.innerHTML = msg;
if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function printVersion(msg = "") {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length - 2];
//add it to document footer currentVersion
versionSpan.textContent = msg + " version: " + pathVersion;
}
}
}
function clickImportFiles() {
if (activeState.settings.localOnly) {
createBookShelfDownload();
return;
}
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Imported!",
activeState.settings.notifierPause
);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display =
"none";
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: " +
activeState.serverFilesTs.replace("_", " - ") +
"<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0
);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
activeState.userId +
".txt' style='text-decoration: underline;' download>download</a> them?",
0
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0
);
}
function createBookShelfDownload() {
let data = createBookShelf();
let filename = data[0]["data"] + ".txt";
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," +
encodeURIComponent(JSON.stringify(data))
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
});
modalNotifier(
"Since you are in local only mode you can only export a backup of your files \
<br><br> \
<div class='w3-container'> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Export</button></div>",
0
);
}
function resetNavBar() {
//enable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "";
//enable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "block";
}
function wrongPwAlert() {
let wrongPWAlert = document.getElementById("wrongPWAlert");
wrongPWAlert.style.display = "block";
wrongPWAlert.addEventListener("click", (e) => {
if (e.target && e.target.tagName === "A") {
clearStorage();
document.getElementById("wrongPWAlert").innerHTML =
"<p>all files cleared - set new password</p>";
}
});
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function resetPage() {
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
let fileInfoDiv = document.getElementById("outputInfo");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
fileInfoDiv.innerHTML = "";
fileInfoDiv.replaceWith(fileInfoDiv.cloneNode(true));
fileInfoDiv.style.display = "none";
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
modalNotifier,
clickImportFiles,
resetNavBar,
printVersion,
wrongPwAlert,
copyToClipBoard,
resetPage
};

515
js/2.0.4/files.js Normal file
View File

@ -0,0 +1,515 @@
import { storeData, clearData, retrieveData, setTimeStamp } from "./storage.js";
import { loadTemplate } from "./web.js";
import parseForm from "./parseForm.js";
import { copyToClipBoard, modalNotifier, resetNavBar, resetPage } from "./evts.js";
import { passwordHash } from "./scripts.js";
function buildFile() {
//set current page value in activeState object
activeState.activePage = "files";
//set templateFiles array
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
//console.log("none yet");
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Saved files";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//disable toggleFiles Button
let target = document.getElementById("toggleFilesMenu");
target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
//target.classList.add("w3-disabled");
target.appendChild(i);
target.style.cssText = "background-color:#9e9e9e !important";
target.style.borderBottom = "4px solid #9e9e9e";
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
resetPage();
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
let target = e.target.parentElement;
if (e.target.matches("li.w3-bar-item")) target = e.target;
if (target.classList.contains("w3-bar-item")) {
let fileName = target.dataset.file;
let template = target.dataset.template;
let pos = target.dataset.tfpos;
clickLoadFileDiv(fileName, template, pos);
}
});
}
function loadFileDiv(fileName, template, pos) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
pos = parseInt(pos) + 1;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
}
function loadFileDivCallBack() {
let tF = retrieveData("templateFiles");
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "_m21_" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-flat-pomegranate");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
let parsedTemplate = parseForm(true);
if (parsedTemplate == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
if (parsedTemplate == "") {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder("File empty");
let div = wrapper.firstChild;
parsedTemplate = div;
}
div.appendChild(parsedTemplate);
fileDisplay.appendChild(div);
document.getElementById("mainForm").appendChild(fileDisplay);
//append TS info
let fileInfoDiv = document.getElementById("outputInfo");
let pos = "";
tF = retrieveData("templateFiles");
for (let tFi of tF) {
if (tFi.fileName == fN) {
pos = parseInt(tFi.pos);
}
}
let tsCreate = tF[pos].metadata.ts_create;
let created = "";
if (tsCreate != "") {
tsCreate =
tsCreate.current_time_long +
" " +
tsCreate.current_date +
"." +
tsCreate.current_year;
created = "";
created = "<tr><td>Created at</td><td>" + tsCreate + "</td></tr>";
}
let tsSave = tF[pos].metadata.ts_save;
let lastSaved = "";
if (tsSave != "") {
tsSave =
tsSave.current_time_long +
" " +
tsSave.current_date +
"." +
tsSave.current_year;
lastSaved = "";
lastSaved = "<tr><td>Last saved at</td><td>" + tsSave + "</td></tr>";
}
let tsCopy = tF[pos].metadata.ts_copy;
let lastCopy = "";
if (tsCopy != "") {
tsCopy =
tsCopy.current_time_long +
" " +
tsCopy.current_date +
"." +
tsCopy.current_year;
lastCopy = "";
lastCopy = "<tr><td>Last copied at</td><td>" + tsCopy + "</td></tr>";
}
let tsEdit = tF[pos].metadata.ts_edit;
let lastEdit = "";
if (tsEdit != "") {
tsEdit =
tsEdit.current_time_long +
" " +
tsEdit.current_date +
"." +
tsEdit.current_year;
lastEdit = "";
lastEdit = "<tr><td>Last edited at</td><td>" + tsEdit + "</td></tr>";
}
fileInfoDiv.innerHTML =
"<p><b>Fileinformation:</b></p>" +
"<table class='w3-table w3-bordered'>" +
"<tr><td>Template</td><td>" +
lT +
"</td></tr>" +
"<tr><td>ID</td><td>" +
pos + "." +
tF[pos].metadata.id +
"</td></tr>" +
created +
lastSaved +
lastCopy +
lastEdit +
"</table>"
fileInfoDiv.style.display = "block";
fileInfoDiv.classList.add("w3-third");
//fix min height of file display
try {
document.getElementById("fileDisplay").style.cssText = "min-height: 300px;";
} catch (e) {}
//fix fontsize for display
try {
document.getElementById("fileDisplay").firstChild.style.fontSize = "1em";
} catch (e) {}
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template, pos) {
if (fileName == "_overflow") return;
if (fileName == "_clearAll") {
clickClearAllFiles();
return;
}
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template, pos);
}
function clearFileData(storData) {
let fileName = storData.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
clearData(fileName);
clearData("userInputForce");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("outputInfo").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-padding-large");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Saved Files:";
sidebarList.appendChild(sidebarListItem);
let c = 0;
let sidebarItemsAmount = 6;
for (let obj of tF.reverse()) {
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
//handle to many files on screen and display hidden files amount
if (c > sidebarItemsAmount) {
sidebarListItem.setAttribute("data-template", "_overflow");
sidebarListItem.setAttribute("data-file", "_overflow");
sidebarListItem.style.backgroundColor = "#e3e7e8";
sidebarListItem.classList.remove("w3-button");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.innerHTML =
tF.length - sidebarItemsAmount + " files not shown";
sidebarList.appendChild(sidebarListItem);
break;
}
let sidebarListItemTitle = document.createElement("p");
sidebarListItemTitle.innerText = obj.fileName.replace(/_/g, " ");
sidebarListItemTitle.style.cssText = "margin: 0;";
let sidebarListItemInfo = document.createElement("span");
sidebarListItemInfo.classList.add("w3-small");
sidebarListItemInfo.innerText =
"created at: " +
obj.metadata.ts_create.current_time +
" - " +
obj.metadata.ts_create.current_date;
sidebarListItem.appendChild(sidebarListItemTitle);
sidebarListItem.append(sidebarListItemInfo);
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarListItem.setAttribute("data-tFPos", obj.pos);
sidebarList.appendChild(sidebarListItem);
c++;
}
//clear all files button
sidebarListItem = document.createElement("li");
sidebarListItem.classList.add("w3-bar-item", "w3-padding-large", "w3-button");
sidebarListItem.setAttribute("data-template", "_clearAll");
sidebarListItem.setAttribute("data-file", "_clearAll");
sidebarListItem.classList.add("w3-hover-flat-pomegranate", "w3-bottom");
sidebarListItem.style.borderTop = "1px solid rgb(221, 221, 221)";
sidebarListItem.style.width = "300px";
sidebarListItem.innerHTML = "Clear all files";
sidebarList.appendChild(sidebarListItem);
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return (
"<div id='fileDisplay' class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" +
msg +
"</p><br><br><br><br><br><br><br><br><br><br><br></div></div>"
);
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
editSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-carrot"
);
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-carrot",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
modalNotifier(
activeState.fileName + " copied to clipboard",
activeState.settings.notifierPause
);
break;
case "Delete":
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
let delFileName = activeState.fileName;
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(
previousFile.fileName,
previousFile.template,
previousFile.pos
);
} else {
document.getElementById("mainForm").innerHTML =
mainFormPlaceholder("No file yet");
}
modalNotifier(
delFileName + " deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
}
function editSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("_m21_")[0], storageName.split("_m21_")[1])
);
//reset sidebar to clear events
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
//reset navbar above all else
resetNavBar();
//reset correct activePage
activeState.activePage = "template";
//set edit timestamp
setTimeStamp("edit");
loadTemplate(storageName.split("_m21_")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("_m21_")[0];
let tF = retrieveData("templateFiles");
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i - 1];
if (previousFile === undefined) {
//get the next one if there is no previous one
previousFile = tF[i + 1];
}
break;
}
i++;
}
return previousFile != undefined ? previousFile : false;
}
function clickClearAllFiles() {
let modal = document.getElementById("modalMsg");
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Delete":
clearAllFiles();
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"All files deleted!",
activeState.settings.notifierPause
);
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"<div class='w3-container'> \
<p>Would you really like to delete all stored files?</p> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button>",
0
);
}
function clearAllFiles() {
let tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
modalNotifier(
"there are no saved texts yet",
activeState.settings.notifierPause
);
return;
}
for (let storageName of tF) {
clearFileData(storageName.fileName);
}
}
export { buildFile, loadFileDivCallBack };

296
js/2.0.4/form.js Normal file
View File

@ -0,0 +1,296 @@
import { retrieveData, storeData, createStorageObj } from "./storage.js";
import parseTemplate from "./parseTemplate.js";
import buildHtmlForm from "./buildHtmlForm.js";
import { copyToClipBoard, handleOnBlur, modalNotifier, resetPage } from "./evts.js";
import parseForm, { parseTextMarkups } from "./parseForm.js";
import { setTemplatePreset } from "./web.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
let placeholder;
try {
placeholder = JSON.parse(jsonPlaceholder);
} catch (e) {
placeholder = ""
}
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", placeholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseTemplate Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseTemplate(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
activeState.templateObjects = objects;
activeState.fullString = templateInput;
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
activeState.templateObjectsPurified = objectsPurified;
//reset page and event listeners
resetPage();
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) return;
buildHtmlForm(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj("copy");
copyToClipBoard(parseForm());
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
e.target.value = "Copied";
modalNotifier(activeState.fileName + " copied to clipboard", activeState.settings.notifierPause);
const timeoutCopy = setTimeout(() => {
//e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
//e.target.value = "Copy";
e.target.style.pointerEvents = "auto";
}, 5000);
break;
case "Save":
createStorageObj("save");
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
modalNotifier(activeState.fileName + " saved", activeState.settings.notifierPause);
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File saved and copied to clipboard", activeState.settings.notifierPause);
}
if (e.target.id == "sb-setform") {
createStorageObj("setform");
let dataArray = retrieveData("userInput");
let lT = activeState.loadedTemplate;
//console.log(lT, dataArray);
setTemplatePreset(lT, dataArray);
modalNotifier("Input saved as preset", activeState.settings.notifierPause);
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener to each form object
let mainForm = document.getElementById("mainFormObj");
for (let formElement of mainForm.children) {
if (formElement.firstChild.lastChild == null) continue;
let id = formElement.firstChild.lastChild.id;
document.getElementById(id).addEventListener("blur", (e) => {
e.preventDefault;
handleOnBlur(e.target);
});
}
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
if (targetElement == null) return;
//handle pell content focus
if (targetElement.parentElement != undefined) {
if (targetElement.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
targetElement = targetElement.parentElement.getElementsByClassName("pell-content")[0];
}
}
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/2.0.4/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

182
js/2.0.4/init.js Normal file
View File

@ -0,0 +1,182 @@
import {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
clickImportFiles,
modalNotifier,
printVersion,
copyToClipBoard
} from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, {
passwordHash,
inputRead
} from "./scripts.js";
import parseForm from "./parseForm.js";
import { createStorageObj, retrieveData, storeSettings } from "./storage.js";
import { loadNavBar, initTextBlocks, loadNewTemplate } from "./web.js";
window.activeState = {
userId: "",
sessionToken: "",
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
settings: {
localOnly: true,
lineBreak: 120,
font: "Arial",
fontSize: "10px",
notifierPause: 1,
persistentStorage: false,
enablePell: false,
debug: false
},
templates: [],
templateObjectsPurified: [],
templateObjects: [],
fullString: "",
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
"title",
],
markups: ["title", "link", "italic", "green_highlighted", "highlighted"],
storage: [],
orgPage: {
main: {},
sidebar: {}
}
};
function init() {
//init passwordhash to retrieve cookie info and set passwordHash
passwordHash.initHash();
//check if user is logged in
if (passwordHash.verify()) {
//user logged in
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load settings from storage and apply
let settings = storeSettings("getInit", true);
if (settings != null) {
for (let setting of Object.entries(settings)) {
if (typeof(setting[1]) == "string" && setting[1].toLowerCase() === "true") setting[1] = true;
if (typeof(setting[1]) == "string" && setting[1].toLowerCase() === "false") setting[1] = false;
activeState.settings[setting[0]] = setting[1];
}
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version and storage mode to footer
let msg = (activeState.settings.persistentStorage) ? "persistent" : "temporary";
printVersion("storage mode: "+msg+" |");
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
//backup landing page
activeState.orgPage.sidebar = document.getElementById("sidebar").childNodes;
activeState.orgPage.main = document.getElementById("mainForm").childNodes;
}
function eventListeners() {
//add hideMenu to Body
document
.body
.addEventListener("click", (e) => hideMenus(e));
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
/* document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu); */
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
inputRead.init();
window.addEventListener("keydown", (e) => {
if (activeState.activePage == "template") {
inputRead.read(e);
if (e.ctrlKey && e.key == "s") {
createStorageObj("copy");
copyToClipBoard(parseForm());
modalNotifier("File copied to clipboard", activeState.settings.notifierPause);
let copyButton = document.getElementById("fromCopyBtn");
copyButton.className = "w3-button w3-flat-carrot";
copyButton.value = "Copied";
e.preventDefault();
}
}
});
//add url listener
window.addEventListener("hashchange", (e) => {
let newURLArr = e.newURL.split("/");
let template;
if (newURLArr != undefined) {
template = newURLArr[newURLArr.length -1];
if (template != undefined) {
template = template.split("=")[1];
if (template != undefined) {
if (activeState.templates.includes("")) {
loadNewTemplate(template);
}
}
}
}
});
}
init();

384
js/2.0.4/parseForm.js Normal file
View File

@ -0,0 +1,384 @@
import { clearData, retrieveData } from "./storage.js";
function parseForm(returnDIV = false) {
//get user Inout Data from preset or from file
let dataArray = [];
if (returnDIV) {
dataArray = retrieveData("userInputForce");
clearData("userInputForce");
} else {
dataArray = retrieveData("userInput");
}
//if the decryption went wrong return null
if (dataArray == null) return dataArray;
//if there are no files yet return empty array
if (dataArray == []) return "";
//get original objects from sessionstorage gen from loadTemplate
let objects = activeState.templateObjects;
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = activeState.fullString;
//define output buffer
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
obj.result = "";
//compaire each obj with elements from mainFormObj
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
//if obj is the connected list main selector
if (data.name.split("-")[0] == "clM") {
//if connected list main matches current object
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
//set flag for next iteration of loop
conListFlag = true;
data.name = data.name.substring(4);
//selection is not added to buffer
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
//if field matches current object
if (obj.word.replace(/ /g, "_") == data.name) {
let value = parseDataForResult(obj, data.value);
if (value == "!none") value = "";
obj.result = value;
}
//handle conlist elements for parsing each element
if (conListFlag && obj.type == "conList") {
let value = parseConListForResult(obj, data, dataArray);
if (value == "!none") value = "";
obj.result = value;
continue;
}
}
}
//build final output string by inserting objects
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
let tepos = objects[i].epos;
//skip empty results by skipping the newline char
if (objects[i].result == "") tepos += 1;
b +=
objects[i].result +
fullString.substring(tepos, objects[j].spos);
}
}
//sanitizing final output string
let bHtml = b;
//remove newline
bHtml = bHtml.replace(/!\w{1,2}\n/g, "");
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
bHtml = bHtml.replace(/ /g, "&nbsp;");
bHtml = bHtml.replace(/(?:\r\n|\r|\n)/g, "<br />");
bHtml = bHtml.replace(/<\/div>/g, '<br />');
bHtml = bHtml.replace(/<div>/g, '');
/* if (activeState.settings.enablePell) {
bHtml = bHtml.replace(/!l /g, "");
bHtml = bHtml.replace(/!n /g, "");
bHtml = bHtml.replace(/!ls /g, "");
} else {
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
} */
//creating output div
let divContent = document.createElement("div");
divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
divContent.style.fontSize = activeState.settings.fontSize;
divContent.innerHTML = bHtml;
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.appendChild(divContent);
if (returnDIV) {
return div;
} else {
return bHtml;
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
//parse global linebreak after marked text was already fixed
value = parseGlobalLineBreak(value);
return value;
}
function parseConListForResult(obj, data, dataArray) {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
return obj.result + "\n" + value;
}
}
}
}
}
return ""
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
if (dataArray[i] == "") continue;
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
continue;
}
//check if list indicator has been set and adjust userInput accordingly
let listIndicator = "";
if (listNumberFlag) {
listIndicator = " " + listNumberFlagNum + ". ";
listNumberFlagNum++;
}
if (listSubFlag && listIndicator == "") listIndicator = " ○ ";
if (listFlag && listIndicator == "") listIndicator = " • ";
//exclude settings if pell is enabled
//if (activeState.settings.enablePell) listIndicator = "";
//handle global linebreak and fit according to indicator according to list indicator
if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function parseGlobalLineBreak(data) {
//parse each line of input with parseLineBreak return condensed string with newlines
let parsedData = '';
for (let line of data.split('\n')) {
let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
if (parsedData != '') {
parsedData = parsedData + '\n' + parsedLine;
} else {
parsedData = parsedLine;
}
}
return parsedData
}
function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
//add 5 chars buffer to fix list intendation issue
//each input field gets parsed line by line twice once for list inputs and a second time for each input
let lines;
if (line.length > lineBreak) {
//create linebreak in between second to last word
let correctedLineBreak;
let newLineStart;
let cLBt = lineBreak-(intendation*2)
//find last space before linebreak
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
//and fix the next lines start
newLineStart = correctedLineBreak+1;
//add to parsed output
lines = line.substring(0, correctedLineBreak);
//delete first parsed output from inputstring
line = line.substring(newLineStart);
let intendationSpaces = '';
//check if an intendation is given if so convert it to correct spaces
if (intendation != 0) intendationSpaces = ' '.repeat(intendation);
//start loop to parse rest of the string
while(line.length > lineBreak) {
let cLBt = lineBreak-(intendation*2)
correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
newLineStart = correctedLineBreak+1;
//add to output with intendation if given
lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
//delete from input
line = line.substring(newLineStart);
}
//process rest of the string with correct intendation
lines += "\n" + intendationSpaces + line;
} else {
//if string is within lineBreak just forward input to output
lines = line;
}
return lines;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
export default parseForm;

388
js/2.0.4/parseTemplate.js Normal file
View File

@ -0,0 +1,388 @@
function parseTemplate(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//bugfix if the title of an input has no space in it ex: %test=l:first word;l:second word;%1
let oneWordFlag = false;
if (word.substring(0, 1) == "%" && word.indexOf('=') != -1) {
oneWordFlag = true;
}
//for loop to escape spaces in simple input
for (let j = i+1; j < wordArray.length; j++) {
//if title has no space then go back one word to include "=" ex:
if (oneWordFlag) {
j = i;
oneWordFlag = false;
} else {
w = w + " " + wordArray[j];
}
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseTemplate;

254
js/2.0.4/pell.js Normal file
View File

@ -0,0 +1,254 @@
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? factory(exports)
: typeof define === "function" && define.amd
? define(["exports"], factory)
: factory((globalThis.pell = {}));
})(this, function (exports) {
"use strict";
var _extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var defaultParagraphSeparatorString = "defaultParagraphSeparator";
var formatBlock = "formatBlock";
var addEventListener = function addEventListener(parent, type, listener) {
return parent.addEventListener(type, listener);
};
var appendChild = function appendChild(parent, child) {
return parent.appendChild(child);
};
var createElement = function createElement(tag) {
return document.createElement(tag);
};
var queryCommandState = function queryCommandState(command) {
return document.queryCommandState(command);
};
var queryCommandValue = function queryCommandValue(command) {
return document.queryCommandValue(command);
};
var exec = function exec(command) {
var value =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return document.execCommand(command, false, value);
};
var defaultActions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
state: function state() {
return queryCommandState("bold");
},
result: function result() {
return exec("bold");
},
},
italic: {
icon: "<i>I</i>",
title: "Italic",
state: function state() {
return queryCommandState("italic");
},
result: function result() {
return exec("italic");
},
},
underline: {
icon: "<u>U</u>",
title: "Underline",
state: function state() {
return queryCommandState("underline");
},
result: function result() {
return exec("underline");
},
},
strikethrough: {
icon: "<strike>S</strike>",
title: "Strike-through",
state: function state() {
return queryCommandState("strikeThrough");
},
result: function result() {
return exec("strikeThrough");
},
},
heading1: {
icon: "<b>H<sub>1</sub></b>",
title: "Heading 1",
result: function result() {
return exec(formatBlock, "<h1>");
},
},
heading2: {
icon: "<b>H<sub>2</sub></b>",
title: "Heading 2",
result: function result() {
return exec(formatBlock, "<h2>");
},
},
paragraph: {
icon: "&#182;",
title: "Paragraph",
result: function result() {
return exec(formatBlock, "<p>");
},
},
quote: {
icon: "&#8220; &#8221;",
title: "Quote",
result: function result() {
return exec(formatBlock, "<blockquote>");
},
},
olist: {
icon: "&#35;",
title: "Ordered List",
result: function result() {
return exec("insertOrderedList");
},
},
ulist: {
icon: "&#8226;",
title: "Unordered List",
result: function result() {
return exec("insertUnorderedList");
},
},
code: {
icon: "&lt;/&gt;",
title: "Code",
result: function result() {
return exec(formatBlock, "<pre>");
},
},
line: {
icon: "&#8213;",
title: "Horizontal Line",
result: function result() {
return exec("insertHorizontalRule");
},
},
link: {
icon: "&#128279;",
title: "Link",
result: function result() {
var url = window.prompt("Enter the link URL");
if (url) exec("createLink", url);
},
},
image: {
icon: "&#128247;",
title: "Image",
result: function result() {
var url = window.prompt("Enter the image URL");
if (url) exec("insertImage", url);
},
},
};
var defaultClasses = {
actionbar: "pell-actionbar",
button: "pell-button",
content: "pell-content",
selected: "pell-button-selected",
};
var init = function init(settings) {
var actions = settings.actions
? settings.actions.map(function (action) {
if (typeof action === "string") return defaultActions[action];
else if (defaultActions[action.name])
return _extends({}, defaultActions[action.name], action);
return action;
})
: Object.keys(defaultActions).map(function (action) {
return defaultActions[action];
});
var classes = _extends({}, defaultClasses, settings.classes);
var defaultParagraphSeparator =
settings[defaultParagraphSeparatorString] || "div";
var actionbar = createElement("div");
actionbar.className = classes.actionbar;
appendChild(settings.element, actionbar);
var content = (settings.element.content = createElement("div"));
content.contentEditable = true;
content.className = classes.content;
content.oninput = function (_ref) {
var firstChild = _ref.target.firstChild;
if (firstChild && firstChild.nodeType === 3)
exec(formatBlock, "<" + defaultParagraphSeparator + ">");
else if (content.innerHTML === "<br>") content.innerHTML = "";
settings.onChange(content.innerHTML);
};
content.onkeydown = function (event) {
if (
event.key === "Enter" &&
queryCommandValue(formatBlock) === "blockquote"
) {
setTimeout(function () {
return exec(formatBlock, "<" + defaultParagraphSeparator + ">");
}, 0);
}
};
appendChild(settings.element, content);
actions.forEach(function (action) {
var button = createElement("button");
button.className = classes.button;
button.innerHTML = action.icon;
button.title = action.title;
button.setAttribute("type", "button");
button.onclick = function () {
return action.result() && content.focus();
};
if (action.state) {
var handler = function handler() {
return button.classList[action.state() ? "add" : "remove"](
classes.selected
);
};
addEventListener(content, "keyup", handler);
addEventListener(content, "mouseup", handler);
addEventListener(button, "click", handler);
}
appendChild(actionbar, button);
});
if (settings.styleWithCSS) exec("styleWithCSS");
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
return settings.element;
};
var pell = { exec: exec, init: init };
exports.exec = exec;
exports.init = init;
exports["default"] = pell;
Object.defineProperty(exports, "__esModule", { value: true });
});
export default pell;

213
js/2.0.4/scripts.js Normal file
View File

@ -0,0 +1,213 @@
import { createStorageObj, retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
import { wrongPwAlert } from "./evts.js";
export const passwordHash = {
name: cyrb53("m21_"+getBrowserFingerprint( { hardwareOnly: true } )),
toString: function () {
let token = window.activeState.sessionToken;
if (token == null) return "";
if (token == "") return "";
return XORCipher.decode(this.name, token);
},
set: function (pw) {
if (pw == "") return;
activeState.sessionToken = XORCipher.encode(this.name, sha256(pw));
},
initHash: function () {
//check if cookie exists
if (getCookie(this.name) != null) {
if (getCookie(this.name) != "") {
this.set(XORCipher.decode(this.name, getCookie(this.name)));
}
}
if (retrieveData("templateFiles") != null) {
//set user id
activeState.userId = passwordHash.name;
setCookie(this.name, XORCipher.encode(this.name, this), 10);
}
},
verify: function () {
if (passwordHash == "") return false;
return (retrieveData("templateFiles") != null) ? true : false;
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = sanitize(x.elements[0].value);
if (pw != "" || pw !== "undefined") {
passwordHash.set(pw);
let tF = retrieveData("templateFiles");
if (tF == null) {
wrongPwAlert();
passwordHash.set("");
x.elements[0].value = "";
return;
}
//user logged in
//make sure to bring back persistent stat after logout
activeState.settings.persistentStorage = "true";
tF = retrieveData("templateFiles");
if (tF == null || tF.length == 0) {
activeState.settings.persistentStorage = "false";
}
activeState.userId = passwordHash.name;
document.getElementById("login").style.display = "none";
setCookie(passwordHash.name, XORCipher.encode(passwordHash.name, passwordHash), 10)
}
}
export function cyrb53(str, seed = 21) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Lax";
}
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
export function logout() {
let id = passwordHash.name;
activeState.sessionToken = "";
setCookie(passwordHash.name, "", 10);
document.cookie = id + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.getElementById("passwordField").value = "";
document.getElementById("login").style.display = "block";
}
export function sanitize(string) {
const map = {
'&': '_',
'<': '_',
'>': '_',
'"': '_',
"'": '_',
'/': '_',
'`': '_',
'=': '_'
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
export function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
export const inputRead = {
init: function () {
this.event = "";
this.inputString = "";
this.source = "";
this.inputContent = "";
this.lastRunTime = new Date();
this.target = document.getElementById("toggleFilesMenu");
this.lastExecId = "";
},
read: function (event) {
this.event = event;
this.source = event.srcElement.id;
if (event.target.className == "pell-content") {
this.source = event.target.parentElement.getElementsByTagName("textarea")[0].id;
}
let previousContent = this.inputContent;
let key = (event.key !=undefined) ? event.key : "";
let contentElement = document.getElementById(this.source);
this.inputContent = (contentElement != undefined) ? contentElement.value + key : "";
if (this.inputContent == "" || key == "") return;
if (key.length > 1 && key != "Backspace" && key != "Delete" && key != "Enter") return;
if (event.ctrlKey) return;
if (this.inputContent == previousContent) return;
this.lastRunTime = new Date();
clearTimeout(this.lastExecId);
this.target.style.borderBottom = "3px solid #c0392b";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-save");
this.target.appendChild(i);
this.lastExecId = setTimeout(() => {
createStorageObj("save");
this.target.style.borderBottom = "none";
this.target.innerHTML = "";
let i = document.createElement("i");
i.classList.add("fa", "fa-file");
this.target.appendChild(i);
}, 1000);
},
}
export function getCurrentDate() {
let date = new Date();
let uts = Date.now();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute = current_minute <= 9 ? "0" + current_minute : current_minute;
let current_second = date.getSeconds();
current_second = current_second <= 9 ? "0" + current_second : current_second;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_day = date.getDate();
current_day = current_day <= 9 ? "0" + current_day : current_day;
let current_year = date.getFullYear();
let current_time = current_hour + ":" + current_minute;
let current_time_long = current_hour + ":" + current_minute + ":" + current_second;
let current_date = current_day + "." + current_month;
return {
current_time: current_time,
current_time_long: current_time_long,
current_date: current_date,
current_year: current_year,
uts: uts
};
}
export default setPassword;

198
js/2.0.4/settings.js Normal file
View File

@ -0,0 +1,198 @@
import { hideMenus, modalNotifier, printVersion, resetNavBar, resetPage } from "./evts.js";
import { passwordHash, sanitize } from "./scripts.js";
import { retrieveData, storeData, storeSettings } from "./storage.js";
const buildSettings = () => {
//set current page value in activeState object
activeState.activePage = "settings";
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Settings";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//reset navbar if files was used
resetNavBar();
//disable toggleTestBlocksMenu
document.getElementById("toggleTestBlocksMenu").style.display = "none";
//reset page and event listeners
hideMenus("force");
resetPage();
addSidebar();
buildForm();
//add events
formEvts();
};
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
saveSettings();
modalNotifier(
"Settings saved!",
activeState.settings.notifierPause
);
e.target.className = e.target.className.replace(
" w3-grey",
" w3-flat-nephritis"
);
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(
" w3-flat-nephritis",
" w3-grey"
);
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
}
function buildForm() {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let settings = storeSettings("get", true);
if (settings == "") settings = activeState.settings;
for (let setting of Object.entries(settings)) {
buildField(setting, form);
}
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
}
function buildField(obj, form) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-left-align");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
label.style.display = "inline-block";
label.style.width = "100%";
label.style.paddingBottom = "5px";
label.style.borderBottom = "thin solid #9e9e9e";
label.style.fontWeight = "800";
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj[0]);
input.setAttribute("id", obj[0]);
input.classList.add("w3-input");
input.id = obj[0];
input.value = obj[1];
label.innerHTML = obj[0];
div.appendChild(label);
div.appendChild(input);
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
}
function addSidebar() {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-title";
sidebarListItem.innerHTML = "Edit Settings"
sidebarList.appendChild(sidebarListItem);
document.getElementById("sidebar").appendChild(sidebarList);
}
function saveSettings() {
let x = document.getElementById("mainFormObj");
let obj = {};
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
let name = x.elements[i].name;
let value = x.elements[i].value;
obj[name] = sanitize(value);
}
for (let setting of Object.entries(obj)) {
if (activeState.settings[setting[0]] != setting[1]) {
//change detected
if (setting[0] == "persistentStorage") {
//get tF from old storage
let tF = retrieveData("templateFiles");
//get previous settings
let settings = storeSettings("get", true);
//store the new settings in old storage
storeSettings(obj);
//apply the new setting
activeState.settings[setting[0]] = setting[1];
//store the new settings in the new storage
if (settings != "") storeSettings(obj);
//transfer tF
if (tF != null) storeData("templateFiles", tF);
let msg = (!activeState.settings.persistentStorage) ? "temporary" : "persistent";
printVersion("storage mode: "+msg+" |");
}
}
activeState.settings[setting[0]] = setting[1];
}
storeSettings(obj);
}
export default buildSettings;

3
js/2.0.4/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

369
js/2.0.4/storage.js Normal file
View File

@ -0,0 +1,369 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { cyrb53, getCurrentDate, passwordHash, sanitize } from "./scripts.js";
const store = {
getItem: function (key) {
return debug("GET", key, getStor().getItem(sha256(key + activeState.userId)));
},
setItem: function (key, data) {
debug("SET", key, "setItem: "+data);
getStor().setItem(sha256(key + activeState.userId), data);
},
removeItem: function (key) {
debug("REMOVE", key);
getStor().removeItem(sha256(key + activeState.userId));
},
clear: function () {
debug("CLEARALL", "");
getStor().clear();
},
};
const tempStore = {
setItem: function (key, data) {
globalThis.activeState.storage[key] = data;
},
getItem: function (key) {
return globalThis.activeState.storage[key];
},
removeItem: function (key) {
globalThis.activeState.storage[key] = "";
},
clear: function () {
globalThis.activeState.storage = [];
},
};
function getStor() {
if (window.activeState.settings.persistentStorage) {
return window.localStorage;
} else {
return tempStore;
}
}
function debug(mode, key, data) {
if (activeState.settings.debug == "false") return data;
if (activeState.settings.debug == false) return data;
console.log({
mode: mode,
key: key,
data: (data != null) ? data.substring(0,10): "",
persistent: activeState.settings.persistentStorage
});
return data;
}
function createStorageObj(ref = "none") {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
if (x.elements[i].name == "") continue;
let parsedContent = x.elements[i].value;
parsedContent = parsedContent.replace(/<div>/g, "");
parsedContent = parsedContent.replace(/<\/div>/g, "\n");
if (ref == "setform") {
//parse pell content remove html tags
parsedContent = parsedContent.replace(/<.{1,4}>/g, "");
}
x.elements[i].value = parsedContent;
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//set current filename according to filenamefield
setCurrentFileName();
//set savetime in templateFiles
setTimeStamp(ref);
//store files with preset filename
storeData("userInput", dataArray);
}
function storeData(name, data) {
if (passwordHash == "") return;
data = JSON.stringify(data);
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName();
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
store.setItem(key, obfuscate(data));
}
function retrieveData(name, template = "none") {
if (passwordHash == "") return null;
if (name == "userInput") {
if (activeState.fileName != "") {
name = activeState.fileName;
} else {
return [];
}
}
if (name == "userInputForce") {
name = "userInput";
}
let cdata;
let key;
if (template == "none") {
let lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
key = name + "_m21_" + template;
}
cdata = store.getItem(key);
if (cdata != null) {
cdata = obfuscate(cdata, false);
let data;
try {
data = JSON.parse(cdata);
} catch (e) {
data = null;
}
return data;
} else {
return [];
}
}
function clearData(name, template = "none") {
let lT;
let key;
if (name == "userInputForce") name = "userInput";
if (template == "none") {
lT = activeState.loadedTemplate;
key = name + "_m21_" + lT;
if (name == "templateFiles") {
key = name + "_m21_" + activeState.userId;
}
} else {
lT = template;
key = name + "_m21_" + template;
}
store.removeItem(key);
}
function getFileName() {
let currentFileName = activeState.fileName;
let lT = activeState.loadedTemplate;
if (currentFileName == "none" || currentFileName == "") {
let date = getCurrentDate();
currentFileName = date.current_time + "_" + date.current_date + " " + lT;
//console.log(currentFileName);
}
let tF = retrieveData("templateFiles");
const metadata = {
ts_create: getCurrentDate(),
ts_save: "",
ts_copy: "",
ts_edit: "",
id: cyrb53(currentFileName),
editor: (activeState.settings.enablePell) ? "pell": "textarea"
};
if (tF.length != 0) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {
return currentFileName;
}
}
tF.push({
fileName: currentFileName,
template: lT,
metadata: metadata,
pos: tF.length,
});
} else {
tF = [
{ fileName: currentFileName, template: lT, metadata: metadata, pos: 0 },
];
}
storeData("templateFiles", tF);
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if ((data == null) | (data == "")) return "";
if (mode) {
return XORCipher.encode(passwordHash, data);
} else {
return XORCipher.decode(passwordHash, data);
}
}
function popFromTemplateFiles(fileName) {
let tF = retrieveData("templateFiles");
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", newArray);
}
function createBookShelf() {
let tF = retrieveData("templateFiles");
let bookShelf = {};
let date = getCurrentDate();
let saveFileName = date.current_time + "_" + date.current_date;
if (tF != null) {
bookShelf[0] = { name: "hash", data: activeState.userId, ts: saveFileName };
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "_m21_" + tFi.template;
if (activeState.settings.localOnly == "true") {
bookShelf[i].data = data;
} else {
bookShelf[i].data = obfuscate(data);
}
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
store.setItem(file.name, file.data);
templateFilesArray.push({
fileName: file.name.split("_m21_")[0],
template: file.name.split("_m21_")[1],
});
}
store.setItem(
"templateFiles_m21_" + activeState.userId,
obfuscate(JSON.stringify(templateFilesArray))
);
}
}
};
xhttp.open("GET", "php/?getStoredFiles=" + activeState.userId, true);
xhttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhttp.send();
}
function storeSettings(data, get = false) {
let key = "settings_m21_" + activeState.userId;
if (get) {
let cdata = "";
if (data == "getInit") {
activeState.settings.persistentStorage = "true";
}
try {
cdata = JSON.parse(obfuscate(store.getItem(key), false));
} catch (e) {
cdata = "";
}
if (data == "getInit") {
activeState.settings.persistentStorage = "false";
}
return cdata;
} else {
store.setItem(key, obfuscate(JSON.stringify(data)));
}
}
function clearStorage() {
store.clear();
}
function setCurrentFileName() {
activeState.fileName = "";
let userFileNameField = document.getElementById("userFileName");
let userFileName = sanitize(userFileNameField.value);
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
}
function setTimeStamp(type) {
if (activeState.fileName != "") {
let tF = retrieveData("templateFiles");
if (tF.length != 0) {
let c = 0;
for (let tFi of tF) {
if (tFi.fileName == activeState.fileName) {
switch (type) {
case "save":
tF[c].metadata.ts_save = getCurrentDate();
break;
case "copy":
tF[c].metadata.ts_copy = getCurrentDate();
break;
case "edit":
tF[c].metadata.ts_edit = getCurrentDate();
break;
}
storeData("templateFiles", tF);
}
c += 1;
}
}
}
}
export {
createStorageObj,
storeData,
retrieveData,
clearData,
getFileName,
createBookShelf,
importBookShelf,
storeSettings,
clearStorage,
setCurrentFileName,
setTimeStamp
};

386
js/2.0.4/web.js Normal file
View File

@ -0,0 +1,386 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName } from "./storage.js";
import { insertTextBlocks, modalNotifier, resetNavBar } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { logout, passwordHash } from "./scripts.js";
import buildSettings from "./settings.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
document.getElementById("logo").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
clearData("userInputForce");
}
if (cdata != "") {
if (cdata != null) {
retrieveForm(cdata);
}
}
//select first object and focus on it
let obj = activeState.templateObjectsPurified;
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//reset navbar above all else
resetNavBar();
//sessionVerfication check
if (!passwordHash.verify()) {
modalNotifier("Error: Session is not authenticated...", 0, false);
}
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText);
return;
}
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "javascript:void(0)");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.style.borderTop = "2px solid rgb(221, 221, 221)";
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!settings");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Settings";
divMob.appendChild(createEntry);
createEntry = document.createElement("a");
createEntry.setAttribute("href", "javascript:void(0)");
createEntry.setAttribute("data-template", "!logout");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large", "w3-flat-pomegranate");
createEntry.innerHTML = "Logout";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
e.preventDefault;
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "!createNew") {
createTemplate();
return;
}
if (template == "!logout") {
logout();
return;
}
if (template == "!settings") {
buildSettings();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = "";
try {
res = JSON.parse(this.responseText);
} catch (e) {
console.log("error", this.responseText)
return;
}
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
if (res[x][1].length < 1) continue;
let aReg = document.createElement("a");
aReg.setAttribute("href", "javascript:void(0)");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: JSON.stringify(formData),
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+activeState.userId+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].name == "") continue;
let e = document.getElementById(arr[i].name);
if (e === null) {
//parse connected list
let id = arr[i].name.split("cl-")[1];
//escape cl-text:!ls
if (id != undefined) id = id.split(":")[0];
e = document.getElementById(id);
if (e === null) {
//parse connected list main
let id = arr[i].name.split("clM-")[1];
e = document.getElementById(id);
if (e === null) continue;
}
}
//handle connected list Main item button or list
if (e.name.substr(0, 4) == "clM-") {
if (arr[i].value != "!none") {
let clElement = document.getElementById(e.dataset.word);
if (clElement === null) {
clElement = document.getElementById(arr[i].value.replace(/ /g, "_"));
}
//make shure it is visible if selected before
if (clElement != undefined) clElement.parentElement.parentElement.classList.remove("hidden");
e.value = arr[i].value;
}
continue;
}
switch (e.nodeName) {
case "TEXTAREA":
//clean pell attributes for raw input in textarea
arr[i].value = arr[i].value.replace(/<div>/g, "");
arr[i].value = arr[i].value.replace(/<\/div>/g, "\n");
arr[i].value = arr[i].value.replace(/<.{1,4}>/g, "");
//check if pell was used
if (e.parentElement != undefined) {
if (e.parentElement.getElementsByClassName("pell-content")[0] != undefined) {
let contentArray = arr[i].value.split("\n");
let parsedContent = "";
if (contentArray.length != 0) {
for (let contentLine of contentArray) {
if (contentLine != "") {
contentLine = "<div>" + contentLine + "</div>";
}
parsedContent += contentLine;
}
} else {
parsedContent = arr[i].value;
}
e.innerHTML = arr[i].value;
arr[i].value = parsedContent;
e = e.parentElement.getElementsByClassName("pell-content")[0];
}
}
//append raw input to textarea or parsed content to pell content
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

187
js/2.0.4/xorc.js Normal file
View File

@ -0,0 +1,187 @@
const XORCipher = {
encode: function (key, data, seed) {
data = xor_encrypt(key, data, seed);
return b64_encode(data);
},
decode: function (key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
},
seed: function (n) {
return randString(n);
},
};
function stringToUtf8ByteArray(str) {
var out = [],
p = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charCodeAt(i);
if (c < 128) {
out[p++] = c;
} else if (c < 2048) {
out[p++] = (c >> 6) | 192;
out[p++] = (c & 63) | 128;
} else if (
(c & 0xfc00) == 0xd800 &&
i + 1 < str.length &&
(str.charCodeAt(i + 1) & 0xfc00) == 0xdc00
) {
// Surrogate Pair
c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
out[p++] = (c >> 18) | 240;
out[p++] = ((c >> 12) & 63) | 128;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
} else {
out[p++] = (c >> 12) | 224;
out[p++] = ((c >> 6) & 63) | 128;
out[p++] = (c & 63) | 128;
}
}
return out;
}
function utf8ByteArrayToString(bytes) {
// array of bytes
var out = [],
pos = 0,
c = 0;
while (pos < bytes.length) {
var c1 = bytes[pos++];
if (c1 < 128) {
out[c++] = String.fromCharCode(c1);
} else if (c1 > 191 && c1 < 224) {
var c2 = bytes[pos++];
out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
} else if (c1 > 239 && c1 < 365) {
// Surrogate Pair
var c2 = bytes[pos++];
var c3 = bytes[pos++];
var c4 = bytes[pos++];
var u =
(((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
0x10000;
out[c++] = String.fromCharCode(0xd800 + (u >> 10));
out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
} else {
var c2 = bytes[pos++];
var c3 = bytes[pos++];
out[c++] = String.fromCharCode(
((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
}
}
return out.join("");
}
var b64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function b64_encode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = (o1 << 16) | (o2 << 8) | o3;
h1 = (bits >> 18) & 0x3f;
h2 = (bits >> 12) & 0x3f;
h3 = (bits >> 6) & 0x3f;
h4 = bits & 0x3f;
enc +=
b64_table.charAt(h1) +
b64_table.charAt(h2) +
b64_table.charAt(h3) +
b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
}
function b64_decode(data) {
var o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = b64_table.indexOf(data.charAt(i++));
h2 = b64_table.indexOf(data.charAt(i++));
h3 = b64_table.indexOf(data.charAt(i++));
h4 = b64_table.indexOf(data.charAt(i++));
bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4;
o1 = (bits >> 16) & 0xff;
o2 = (bits >> 8) & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randString(n) {
var r = "";
for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535));
return r;
}
function xor_encrypt(key, data, seed) {
if (typeof seed == "undefined") seed = randString(32);
var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data),
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
return r;
}
function xor_decrypt(key, data) {
var d = data,
k = stringToUtf8ByteArray(key),
r = [];
for (var i = 0; i < d.length; i++)
r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)];
r.splice(0, r.indexOf(0) + 1);
return utf8ByteArrayToString(r);
}
export default XORCipher;

393
js/9.2/buildForm.js Normal file
View File

@ -0,0 +1,393 @@
import { getFileName } from "./storage.js";
function transformTemplateObject(objects) {
let form = document.createElement("FORM");
form.setAttribute("method", "post");
form.setAttribute("action", "javascript:void(0)");
form.setAttribute("id", "mainFormObj");
form.classList.add("w3-row");
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let i = 0; i < objects.length; i++) {
buildField(objects[i], form, sidebarList);
}
//console.log(objects);
//create sidebar submit button
let sidebarSubmitButton = document.createElement("li");
sidebarSubmitButton.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarSubmitButton.style.borderTop = "2px solid #ddd";
sidebarSubmitButton.id = "sb-submit";
sidebarSubmitButton.innerHTML = "Save & Copy";
sidebarList.appendChild(sidebarSubmitButton);
//add sidebar elemnts to sidebar
document.getElementById("sidebar").appendChild(sidebarList);
//add form to mainForm Div
document.getElementById("mainForm").appendChild(form);
//create username and append field to site
let fileName = getFileName();
document.getElementById("submitContainer").appendChild(userFileNameDiv(fileName));
// create a Save button
let saveBtn = document.createElement("input");
saveBtn.setAttribute("type", "submit");
saveBtn.setAttribute("value", "Save");
saveBtn.classList.add("w3-button");
saveBtn.classList.add("w3-grey");
saveBtn.style.margin = "20px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(saveBtn);
// create a Copy button
let copyBtn = document.createElement("input");
copyBtn.setAttribute("type", "submit");
copyBtn.setAttribute("value", "Copy");
copyBtn.classList.add("w3-button");
copyBtn.classList.add("w3-grey");
copyBtn.style.margin = "20px 0px";
//append submit button to submitContainer
document.getElementById("submitContainer").appendChild(copyBtn);
}
function buildField(obj, form, sidebarList) {
//create template Input fields
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-half");
divContainer.classList.add("w3-container");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let label = document.createElement("LABEL");
let connectedListsArray = [];
let ltPlaceholder;
//check for longtext:!li and convert it to standard longText
if (obj.type.indexOf("longText") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("id", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(textarea);
}
}
}
if (obj.type.indexOf("simpleInput") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.setAttribute("id", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
//check for markup:title and display it as none
if (obj.type.indexOf("markup") !== -1) {
if (obj.type.indexOf(":") !== -1) {
ltPlaceholder = obj.type.split(":")[1];
if (ltPlaceholder !== undefined) {
divContainer.classList.add("hidden");
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.id = obj.word.replace(/ /g, "_");
input.value = obj.word;
divContainer.style.display = "none";
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
}
}
}
switch (obj.type) {
case "genderSpecific":
let select = document.createElement("select");
select.setAttribute("name", obj.word.replace(/ /g, "_"));
select.id = obj.word.replace(/ /g, "_");
select.classList.add("w3-select");
if (typeof obj.m !== "undefined") {
let optionM = document.createElement("option");
optionM.value = obj.m;
optionM.text = obj.m;
select.appendChild(optionM);
}
if (typeof obj.w !== "undefined") {
let optionW = document.createElement("option");
optionW.value = obj.w;
optionW.text = obj.w;
select.appendChild(optionW);
}
if (typeof obj.d !== "undefined") {
let optionD = document.createElement("option");
optionD.value = obj.d;
optionD.text = obj.d;
select.appendChild(optionD);
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select);
break;
case "list":
let select2 = document.createElement("select");
select2.setAttribute("name", obj.word.replace(/ /g, "_"));
select2.classList.add("w3-select");
select2.id = obj.word.replace(/ /g, "_");
select2.setAttribute("id", obj.word.replace(/ /g, "_"));
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
optionL.value = obj[listItem];
optionL.text = obj[listItem];
select2.appendChild(optionL);
}
}
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(select2);
break;
case "conList":
let select3 = document.createElement("select");
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.classList.add("w3-select");
select3.id = obj.word.replace(/ /g, "_");
let optionDefault = document.createElement("option");
optionDefault.value = "!none";
optionDefault.text = "Choose one";
select3.appendChild(optionDefault);
for (let listItem = 0; listItem < obj.listCount + 1; listItem++) {
//console.log(obj[listItem]);
if (typeof obj[listItem] !== "undefined") {
let optionL = document.createElement("option");
let item = obj[listItem];
optionL.value = item;
optionL.text = item;
select3.appendChild(optionL);
connectedListsArray.push({
word: item,
type: obj["clType-"+item],
cl: obj.word
});
}
}
label.innerHTML = obj.word;
if (obj.listCount == 0) {
select3 = document.createElement("button");
select3.setAttribute("value", "!none");
select3.classList.add("w3-button", "w3-grey", "w3-left-align");
select3.id = obj.word.replace(/ /g, "_");
select3.innerHTML = "Show";
select3.setAttribute("name", "clM-"+obj.word.replace(/ /g, "_"));
select3.setAttribute("data-word", connectedListsArray[0].word);
}
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(select3);
break;
case "simpleInput":
let input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", obj.word.replace(/ /g, "_"));
input.classList.add("w3-input");
input.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input);
break;
case "longText":
let textarea = document.createElement("textarea");
textarea.setAttribute("name", obj.word.replace(/ /g, "_"));
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "15");
textarea.classList.add("w3-input");
textarea.id = obj.word.replace(/ /g, "_");
label.innerHTML = obj.word;
divContainer.classList.remove("w3-half");
divContainer.classList.add("w3-center");
div.appendChild(label);
div.appendChild(textarea);
break;
case "current_time":
let input2 = document.createElement("input");
let today = new Date();
let currentTime =
today.getHours() + ":" + ("0" + today.getMinutes()).slice(-2);
//console.log(currentTime);
input2.setAttribute("type", "text");
input2.setAttribute("name", obj.word.replace(/ /g, "_"));
input2.setAttribute("value", currentTime);
input2.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input2.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input2);
break;
case "current_date":
let input3 = document.createElement("input");
var today2 = new Date();
var dd = String(today2.getDate()).padStart(2, "0");
var mm = String(today2.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today2.getFullYear();
currentDate = dd + "." + mm + "." + yyyy;
input3.setAttribute("type", "text");
input3.setAttribute("name", obj.word.replace(/ /g, "_"));
input3.setAttribute("value", currentDate);
input3.id = obj.word.replace(/ /g, "_");
div.setAttribute("style", "display: none;");
input3.classList.add("w3-input");
label.innerHTML = obj.word;
div.appendChild(label);
div.appendChild(input3);
break;
}
//check if item is connected list item cl
if (obj.cl !== undefined) divContainer.classList.add("hidden");
if (obj.cl !== undefined) {
div.lastChild.setAttribute("name",
(ltPlaceholder !== undefined) ? "cl-"+obj.word.replace(/ /g, "_") +":"+ltPlaceholder : "cl-"+obj.word.replace(/ /g, "_"));
}
//append field to wrapper and add to mainForm
divContainer.appendChild(div);
form.appendChild(divContainer);
buildSidebarList(obj, sidebarList)
//handle conList items
if (obj.type == "conList") {
//build connected list fields according to obj
for (let conObj of connectedListsArray) {
buildField(conObj, form, sidebarList);
}
//set formEvent for selection detection to mainForm
if (obj.listCount == 0) {
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("button#"+obj.word.replace(/ /g, "_"))) {
let button = document.getElementById(obj.word.replace(/ /g, "_"));
let con = button.dataset.word;
let conElement = document.getElementById(con);
if (conElement.parentElement.parentElement.classList.contains("hidden")) {
conElement.parentElement.parentElement.classList.remove("hidden");
button.value = "!selected";
} else {
conElement.parentElement.parentElement.classList.add("hidden");
button.value = "!none";
}
}
});
} else {
document.getElementById("mainForm").addEventListener("change", (e) => {
if (e.target && e.target.matches("select#"+obj.word.replace(/ /g, "_"))) {
let select = document.getElementById(obj.word.replace(/ /g, "_"));
for (let opt of select.options) {
if (opt.value == "!none") continue;
if (opt.innerHTML != select.value) {
document.getElementById(opt.innerHTML.replace(/ /g, "_")).parentElement.parentElement.classList.add("hidden");
} else {
document.getElementById(select.value.replace(/ /g, "_")).parentElement.parentElement.classList.remove("hidden");
}
}
for (let hiddenItems of document.getElementsByClassName("cl")) {
if (hiddenItems.innerHTML != select.value) {
hiddenItems.classList.add("hidden");
} else {
hiddenItems.classList.remove("hidden");
}
}
}
});
}
}
}
function buildSidebarList(obj, sidebarList) {
//build sidebarlist item and append
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button",
"sb-item"
);
if (obj.cl !== undefined) sidebarListItem.classList.add("hidden", "cl");
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-item", obj.word.replace(/ /g, "_"));
sidebarListItem.innerHTML = obj.word;
sidebarListItem;
sidebarList.appendChild(sidebarListItem);
}
function userFileNameDiv(fileName) {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-flat-silver");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", fileName);
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export default transformTemplateObject;

209
js/9.2/createTemplate.js Normal file
View File

@ -0,0 +1,209 @@
import {setNewTemplate, loadTemplate} from "./web.js";
import { retrieveData } from "./storage.js";
import { hideMenus, modalNotifier } from "./evts.js";
function createTemplate(template = false) {
//set current page value in activeState object
activeState.activePage = "createTemplate";
//check if user is authenticated and templateFilesArray is decryptable
let tF = retrieveData("templateFiles");
if (tF != "") {
try {
tF = JSON.parse(tF);
} catch (e) {
alert("Decryption failed; are you authenticated?");
window.location.reload();
return;
}
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Manage templates";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
//hide set Form button
document.getElementById("setFormButton").style.display = "none";
if (template) {
document.getElementById("templateInput").value = loadTemplate(template, false, "createTemplate");
return;
}
//reset page and event listeners
hideMenus();
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
document.getElementById("mainForm").appendChild(createTemplateInput());
document.getElementById("sidebar").appendChild(loadTemplateSidebar(activeState.templates));
//add events
if (!template) formEvts();
}
function createTemplateCallBack(fileName, data) {
document.getElementById("templateInput").value = data;
document.getElementById("userFileName").setAttribute("placeholder", fileName);
}
function loadTemplateSidebar(templates) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let template of templates) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-item";
sidebarListItem.setAttribute("data-template", template);
sidebarListItem.innerHTML = template.replace(/_/g, " ");
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function createTemplateInput() {
let createTemplateDisplay = document.createElement("DIV");
createTemplateDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
createTemplateDisplay.id = "createTemplateDisplayWrapper";
//start building submitContainer with save and filename
document.getElementById("submitContainer").appendChild(userFileNameDiv());
let saveButton = document.createElement("input");
saveButton.setAttribute("type", "submit");
saveButton.setAttribute("value", "Save");
saveButton.classList.add("w3-button");
saveButton.classList.add("w3-grey");
saveButton.style.margin = "20px";
document.getElementById("submitContainer").appendChild(saveButton);
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-container", "w3-center");
let div = document.createElement("DIV");
div.classList.add("w3-section");
div.classList.add("w3-flat-silver");
div.setAttribute("style", "padding: 10px");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "templateInput");
textarea.setAttribute("id", "templateInput");
textarea.setAttribute("cols", "100");
textarea.setAttribute("rows", "30");
textarea.classList.add("w3-input");
div.appendChild(textarea);
divContainer.appendChild(div);
createTemplateDisplay.appendChild(divContainer);
return createTemplateDisplay;
}
function formEvts() {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Save":
let fileName;
let userFileNameField = document.getElementById("userFileName");
let userFileName = userFileNameField.value;
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
fileName = userFileName;
//clear old data as file switches to new filename
} else if (userFileNamePH.length != 0) {
fileName = userFileNamePH;
}
let data = document.getElementById("templateInput").value;
setNewTemplate(fileName, data);
modalNotifier(fileName+" saved!", 1);
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
e.preventDefault;
break;
default:
e.preventDefault;
}
}
});
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let template = e.target.dataset.template;
createTemplate(template);
}
});
}
function userFileNameDiv() {
let divContainer = document.createElement("DIV");
divContainer.classList.add("w3-third", "w3-container");
divContainer.setAttribute("style", "padding: 0px");
let div = document.createElement("DIV");
div.classList.add("w3-section", "w3-flat-silver", "w3-margin-left");
div.setAttribute("style", "padding: 5px");
let userFileNameInput = document.createElement("input");
userFileNameInput.setAttribute("type", "text");
userFileNameInput.setAttribute("name", "userFileName");
userFileNameInput.setAttribute("placeholder", "Enter a filename");
userFileNameInput.classList.add("w3-input");
userFileNameInput.id = "userFileName";
div.appendChild(userFileNameInput);
divContainer.appendChild(div);
return divContainer;
}
export {createTemplate, createTemplateCallBack};

193
js/9.2/evts.js Normal file
View File

@ -0,0 +1,193 @@
import {
clearData,
createStorageObj,
createBookShelf,
importBookShelf,
} from "./storage.js";
import {
loadTemplate,
storeFilesToServer,
setTemplatePreset,
checkForStoredDataOnServer,
delStoredDataOnServer
} from "./web.js";
import parseFormOnSubmit from "./parseForm.js";
import { getUsrId } from "./scripts.js";
function showMenu() {
var x = document.getElementById("navMob");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function showSidebar() {
let sidebar = document.getElementById("sidebar");
if (getComputedStyle(sidebar).display === "none") {
sidebar.style.display = "block";
sidebar.style.marginTop = "35px";
} else {
sidebar.style.display = "none";
}
if (screen.width < 993) {
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
}
}
function showTextBlocks() {
var x = document.getElementById("navTb");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
}
}
function insertTextBlocks(t) {
let insert = "!" + t.innerText.split(":")[0] + " ";
let id = activeState.lastElement;
let element = document.getElementById(id);
if (element === null) {
return;
}
element.value += insert;
let tB = document.getElementById("navTb");
tB.className.replace(" w3-show", "");
element.focus();
}
function handleOnBlur(t) {
activeState.lastElement = t.id;
createStorageObj();
}
function clickClearForm() {
//document.activeElement.blur();
//document.getElementById("sidebar").focus();
clearData("userInput");
let lT = activeState.loadedTemplate;
loadTemplate(lT);
}
function hideMenus() {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
let navBar = document.getElementById("navMob");
navBar.className = navBar.className.replace(" w3-show", "");
let tbBar = document.getElementById("navTb");
tbBar.className = tbBar.className.replace(" w3-show", "");
}
function modalNotifier(msg, timeout) {
let modalElement = document.getElementById("modalNotifier");
let msgElement = document.getElementById("modalMsg");
modalElement.style.display = "block";
msgElement.innerHTML = msg;
if (timeout === undefined) {
const run = setTimeout(() => (modalElement.style.display = "none"), 5000);
} else if (timeout >= 1) {
const run = setTimeout(
() => (modalElement.style.display = "none"),
timeout * 1000
);
}
}
function clickSetForm(e) {
e.preventDefault;
let dataArray = parseFormOnSubmit(true);
let lT = activeState.loadedTemplate;
setTemplatePreset(lT, JSON.stringify(dataArray));
modalNotifier("Form Saved", 2);
}
function clickImportFiles() {
checkForStoredDataOnServer();
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Import":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalMsg").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "BUTTON") {
let modal = document.getElementById("modalNotifier");
switch (e.target.innerHTML) {
case "Yes":
importBookShelf();
modal.replaceWith(modal.cloneNode(true));
modalNotifier("Imported!", 2);
break;
case "Cancel":
modal.replaceWith(modal.cloneNode(true));
document.getElementById("modalNotifier").style.display = "none";
break;
default:
e.preventDefault;
}
}
})
modalNotifier(
"<div class='w3-container'> \
Would you like to import the backup created on: "+activeState.serverFilesTs.replace("_", " - ")+ "<br><br> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Yes</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Cancel</button></div>",
0);
break;
case "Save":
storeFilesToServer(createBookShelf());
modal.replaceWith(modal.cloneNode(true));
modalNotifier(
"Files saved to server <br><br> would you like to <a href='/storage/" +
getUsrId() +
".txt' style='text-decoration: underline;' download>download</a> them?"
);
break;
case "Delete":
delStoredDataOnServer();
break;
default:
e.preventDefault;
}
}
});
modalNotifier(
"Here you can manage if your files should be saved on the server \
<br> If there are stored files already on the server you can inport them \
It will overwrite any saved documents <br><br> \
<div class='w3-container'> \
<button style='display: none;' id='importModalBtn' class='w3-button w3-border w3-flat-wet-asphalt' >Import</button> \
<button class='w3-button w3-border w3-flat-wet-asphalt' >Save</button> \
<button class='w3-button w3-border w3-flat-pomegranate' >Delete</button></div>",
0);
}
export {
hideMenus,
showMenu,
showSidebar,
showTextBlocks,
insertTextBlocks,
handleOnBlur,
clickClearForm,
modalNotifier,
clickSetForm,
clickImportFiles,
};

313
js/9.2/files.js Normal file
View File

@ -0,0 +1,313 @@
import {
storeData,
clearData,
retrieveData,
createStorageObj,
} from "./storage.js";
import { loadTemplate } from "./web.js";
import parseFormOnSubmit from "./parseForm.js";
function buildFile() {
createStorageObj();
//set current page value in activeState object
activeState.activePage = "files";
//check if user is authenticated and templateFilesArray is decryptable
let tF = retrieveData("templateFiles");
if (tF != "") {
try {
tF = JSON.parse(tF);
} catch (e) {
alert("Decryption failed; are you authenticated?");
window.location.reload();
return;
}
}
if (tF == null) {
//console.log("none yet");
alert("there are no saved texts yet");
return;
}
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = "Template Gen";
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
//hide set Form button
document.getElementById("setFormButton").style.display = "none";
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target && e.target.matches("li.w3-bar-item")) {
let fileName = e.target.dataset.file;
let template = e.target.dataset.template;
clickLoadFileDiv(fileName, template);
}
});
}
function loadFileDiv(fileName, template) {
activeState.fileName = fileName;
activeState.loadedTemplate = template;
storeData("userInputForce", retrieveData(fileName, template));
loadTemplate(template, false, true);
}
function loadFileDivCallBack() {
let tF = JSON.parse(retrieveData("templateFiles"));
document.getElementById("sidebar").appendChild(loadFileSidebar(tF));
let lT = activeState.loadedTemplate;
let fN = activeState.fileName;
let storageName = fN + "-" + lT;
let fileDisplay = document.createElement("DIV");
fileDisplay.classList.add(
"w3-row-padding",
"w3-padding-24",
"w3-container",
"w3-flat-clouds"
);
fileDisplay.id = "fileDisplayWrapper";
//start building submitContainer with edit copy and delete
let editButton = document.createElement("input");
editButton.setAttribute("type", "submit");
editButton.setAttribute("value", "Edit");
editButton.classList.add("w3-button");
editButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(editButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let copyButton = document.createElement("input");
copyButton.setAttribute("type", "submit");
copyButton.setAttribute("value", "Copy");
copyButton.classList.add("w3-button");
copyButton.classList.add("w3-grey");
document.getElementById("submitContainer").appendChild(copyButton);
document
.getElementById("submitContainer")
.appendChild(document.createTextNode(" "));
let deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "submit");
deleteButton.setAttribute("value", "Delete");
deleteButton.classList.add("w3-button");
deleteButton.classList.add("w3-red");
document.getElementById("submitContainer").appendChild(deleteButton);
if (screen.width > 992) {
document.getElementById("siteTitle").innerHTML = lT.replace(/_/g, " ");
} else {
document.getElementById("siteTitle").innerHTML = "TG";
}
let title = document.createElement("div");
title.classList.add("w3-panel");
let titleText = document.createElement("h2");
titleText.innerText = fN.replace(/_/g, " ");
titleText.style.margin = "0px";
title.appendChild(titleText);
fileDisplay.appendChild(title);
let div = document.createElement("div");
div.appendChild(parseFormOnSubmit(false, true));
fileDisplay.appendChild(div);
document.getElementById("mainForm").appendChild(fileDisplay);
//add events
formEvts(storageName);
}
function clickLoadFileDiv(fileName, template) {
document.getElementById("mainForm").innerHTML = "";
loadFileDiv(fileName, template);
}
function clearFileData(storData) {
let fileName = storData.split("-")[0];
let tF = JSON.parse(retrieveData("templateFiles"));
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", JSON.stringify(newArray));
clearData(fileName);
clearData("userInput");
document.getElementById("mainForm").innerHTML = "";
document.getElementById("output").innerHTML = "";
document.getElementById("submitContainer").innerHTML = "";
document.getElementById("sidebar").innerHTML = "";
document.getElementById("mainForm").innerHTML = mainFormPlaceholder();
document.getElementById("sidebar").appendChild(loadFileSidebar(newArray));
}
function loadFileSidebar(tF) {
let sidebarList = document.createElement("ul");
sidebarList.classList.add("w3-ul");
for (let obj of tF) {
let sidebarListItem = document.createElement("li");
sidebarListItem.classList.add(
"w3-bar-item",
"w3-padding-large",
"w3-button"
);
sidebarListItem.style.borderBottom = "1px solid #ddd";
sidebarListItem.id = "sb-" + obj.fileName.replace(/:/g, "_");
sidebarListItem.innerHTML =
obj.fileName.replace(/_/g, " ") + " - " + obj.template.replace(/_/g, " ");
sidebarListItem.setAttribute("data-file", obj.fileName);
sidebarListItem.setAttribute("data-template", obj.template);
sidebarList.appendChild(sidebarListItem);
}
return sidebarList;
}
function mainFormPlaceholder(msg = "Select a file") {
return "<div class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" + msg + "</p><br><br><br><br><br><br><br><br><br><br><br></div></div>";
}
function copyFileToClipboard() {
const fileDisplay = document.getElementById("fileDisplay");
if (fileDisplay != null) {
copyToClipBoard(fileDisplay.innerHTML);
} else {
console.log("error file not found");
}
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function formEvts(storageName) {
//add event listener to submitContainer
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Edit":
loadSpecificTemplate(storageName);
break;
case "Copy":
copyFileToClipboard();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
case "Delete":
let previousFile = getPreviousFile(storageName);
clearFileData(storageName);
document.getElementById("mainForm").innerHTML = "";
if (previousFile) {
loadFileDiv(previousFile.fileName, previousFile.template);
} else {
document.getElementById("mainForm").innerHTML = mainFormPlaceholder("No file yet");
}
break;
default:
e.preventDefault;
}
}
});
}
function loadSpecificTemplate(storageName) {
storeData(
"userInputForce",
retrieveData(storageName.split("-")[0], storageName.split("-")[1])
);
loadTemplate(storageName.split("-")[1]);
}
function getPreviousFile(storageName) {
let orgFileName = storageName.split("-")[0];
let tF = JSON.parse(retrieveData("templateFiles"));
let i = 0;
let previousFile;
for (let obj of tF) {
if (obj.fileName == orgFileName) {
previousFile = tF[i-1];
break;
}
i++;
}
return (previousFile != undefined) ? previousFile : false;
}
export { buildFile, loadFileDivCallBack };

296
js/9.2/form.js Normal file
View File

@ -0,0 +1,296 @@
//class Form {
// constructor () {
// this.buildForm = buildForm;
// this.retrieveForm = retrieveForm;
// }
//
//
//
//}
import { storeData, createStorageObj } from "./storage.js";
import parseInput from "./parseTemplate.js";
import transformTemplateObject from "./buildForm.js";
import { showSidebar, handleOnBlur } from "./evts.js";
import parseFormOnSubmit, { parseTextMarkups } from "./parseForm.js";
function buildForm(templateInput, loadOnly = false) {
var wordArray = [];
//display set Form button
document.getElementById("setFormButton").style.display = "block";
//check for presets in "-form.txt" file; indicated by !JSON_placeholder
if (templateInput.indexOf("!JSON_placeholder:") !== -1) {
let jsonPlaceholder = templateInput.split("!JSON_placeholder:")[1];
templateInput = templateInput.split("!JSON_placeholder:")[0];
storeData("templatePreset", jsonPlaceholder);
}
//start building wordArray by splitting input by line win/unix and define eol char for recreating templateInput
let eol;
if (templateInput.indexOf("\r\n") !== -1) {
eol = false;
var wordArrayByLine = templateInput.split("\r\n");
} else {
eol = true;
var wordArrayByLine = templateInput.split("\n");
}
//finish building wordArray by Looping through lines and spliting it into one array of words
//also create temporary templateInput to exclude comments
let templateInputArr = [];
for (let wordArrayByLineLine of wordArrayByLine) {
//ignore "#" comment lines
if (wordArrayByLineLine.substring(0, 1) == "#") {
continue;
}
//add words ob lines to wordArray
wordArray = wordArray.concat(wordArrayByLineLine.split(" "));
//add line to temp templatearray
templateInputArr.push(wordArrayByLineLine);
}
//create templateInput without comments
templateInput = templateInputArr.join(eol ? "\n" : "\r\n");
//parse text markups like !l !n in templateInput
templateInput = parseTextMarkups(templateInput);
//set objects array for parseInput Function
var objects = [];
//loop through words, parse it individually and add it to objects array
for (let i = 0; i < wordArray.length; i++) {
parseInput(wordArray, objects, i);
//console.log(wordArray[i]);
}
//set individual positionens of objects in string and add it to objects
setStringPos(objects, templateInput);
//save objects array and template file string for web.js in session storage
window.sessionStorage.setItem("templateObjects", JSON.stringify(objects));
window.sessionStorage.setItem("fullString", templateInput);
//sort objects array by words prio
objects = prioritizeArray(objects);
//remove non display objects and safe it to session storage
let objectsPurified = purifyObjects(objects);
window.sessionStorage.setItem(
"templateObjectsPurified",
JSON.stringify(objectsPurified)
);
//reset page and event listeners
let mainFormDiv = document.getElementById("mainForm");
let outputDiv = document.getElementById("output");
let submitContainerDiv = document.getElementById("submitContainer");
let sidebarDiv = document.getElementById("sidebar");
//sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
mainFormDiv.innerHTML = "";
mainFormDiv.replaceWith(mainFormDiv.cloneNode(true));
outputDiv.innerHTML = "";
outputDiv.replaceWith(outputDiv.cloneNode(true));
submitContainerDiv.innerHTML = "";
submitContainerDiv.replaceWith(submitContainerDiv.cloneNode(true));
sidebarDiv.innerHTML = "";
//finally build html code for Form and siddebar and add it to dom if needed
if (loadOnly) {return};
transformTemplateObject(objectsPurified);
//add events
formEvts();
}
function prioritizeArray(objects) {
let prioArray = [];
let objects_sorted = [];
for (let valPreSorted of objects) {
prioArray.push(valPreSorted.prio);
}
prioArray.sort(function (a, b) {
return a - b;
});
//console.log(prioArray);
for (let valSorted of prioArray) {
for (let obj of objects) {
if (valSorted === obj.prio) {
objects_sorted.push(obj);
if (obj.prio !== 0) {
break;
}
}
}
}
return objects_sorted;
}
function purifyObjects(objects) {
let objectsPurified = [];
let objectsPrePurified = [];
for (let objPrePurified of objects) {
if (!objectsPrePurified.includes(objPrePurified.word)) {
objectsPurified.push(objPrePurified);
}
objectsPrePurified.push(objPrePurified.word);
}
return objectsPurified;
}
function setStringPos(objects, fullStringMaster) {
let stringCursor = 0;
let startPos = 0;
let endPos = 0;
let fullString = "";
for (let obj of objects) {
fullString = fullStringMaster.substring(stringCursor);
if (fullString.indexOf("%" + obj.word) !== -1) {
startPos = 0;
endPos = 0;
startPos = fullString.indexOf("%" + obj.word) + stringCursor;
let objPrioLength = 1;
if (obj.prio > 9) {
objPrioLength = 2;
}
if (obj.prio == 0) {
objPrioLength = 0;
}
switch (obj.type) {
case "simpleInput":
endPos = startPos + 2 + obj.word.length + objPrioLength;
break;
case "genderSpecific":
let gSC = 0;
if (typeof obj.m !== "undefined") {
gSC = gSC + obj.m.length + 3;
}
if (typeof obj.w !== "undefined") {
gSC = gSC + obj.w.length + 3;
}
if (typeof obj.d !== "undefined") {
gSC = gSC + obj.d.length + 3;
}
endPos = startPos + 2 + gSC + objPrioLength + obj.word.length + 1;
break;
case "list":
let gSC1 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC1 = gSC1 + obj[objListItem].length + 3;
}
}
endPos = startPos + 2 + gSC1 + objPrioLength + obj.word.length + 1;
break;
case "conList":
let gSC2 = 0;
for (
let objListItem = 0;
objListItem < obj.listCount + 1;
objListItem++
) {
if (typeof obj[objListItem] !== "undefined") {
gSC2 = gSC2 + obj[objListItem].length + obj["clType-"+obj[objListItem]].length + 4;
if (obj["clType-"+obj[objListItem]] == "cl-simpleInput") {
gSC2 = gSC2 - obj["clType-"+obj[objListItem]].length;
}
}
}
endPos = startPos + 2 + gSC2 + objPrioLength + obj.word.length + 1;
break;
default:
endPos =
startPos +
2 +
obj.word.length +
1 +
obj.type.length +
objPrioLength;
break;
}
obj.spos = startPos;
obj.epos = endPos;
stringCursor = endPos;
}
}
}
function formEvts() {
//add event for main copy button
document.getElementById("submitContainer").addEventListener("click", (e) => {
if (e.target && e.target.tagName === "INPUT") {
switch (e.target.value) {
case "Copy":
createStorageObj();
parseFormOnSubmit();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-carrot");
e.target.style.pointerEvents = "none";
const timeoutCopy = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-carrot"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
case "Save":
createStorageObj();
e.target.className = e.target.className.replace(" w3-grey", " w3-flat-nephritis");
e.target.style.pointerEvents = "none";
const timeoutSave = setTimeout(() => {
e.target.className = e.target.className.replace(" w3-flat-nephritis"," w3-grey");
e.target.style.pointerEvents = "auto";
}, 250);
break;
default:
e.preventDefault;
}
}
});
//add sidebar events
document.getElementById("sidebar").addEventListener("click", (e) => {
if (e.target) {
if (e.target.id == "sb-submit") {
if (screen.width < 993) {
showSidebar();
}
parseFormOnSubmit();
focusOnField("output");
}
if (e.target.id == "sb-item") {
setTimeout(() => {
focusOnField(e.target.dataset.item);
}, 100);
}
}
});
//add handle on blur event listener
document.getElementById("mainForm").addEventListener("click", (e) => {
if (e.target && e.target.matches("div.w3-section")) {
e.preventDefault;
handleOnBlur(e.target);
}
});
}
function focusOnField(id) {
let targetElement = document.getElementById(id);
if (targetElement == null) return;
document.activeElement.blur();
targetElement.focus();
setTimeout(function () {
let offset = targetElement.offsetTop - 100;
window.scrollTo(0, offset);
}, 100);
}
export default buildForm;

247
js/9.2/identify.js Normal file
View File

@ -0,0 +1,247 @@
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, debug = false } = {}) => {
const devicePixelRatio = +parseInt(window.devicePixelRatio);
const {
appName,
appCodeName,
appVersion,
cookieEnabled,
deviceMemory,
doNotTrack,
hardwareConcurrency,
language,
languages,
maxTouchPoints,
platform,
product,
productSub,
userAgent,
vendor,
vendorSub,
} = window.navigator;
const { width, height, colorDepth, pixelDepth } = window.screen;
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const touchSupport = 'ontouchstart' in window;
const canvas = getCanvasID(debug);
const webgl = enableWebgl ? getWebglID(debug) : undefined; // undefined will remove this from the stringify down here
const webglInfo = enableWebgl ? getWebglInfo(debug) : undefined; // undefined will remove this from the stringify down here
const data = hardwareOnly
? JSON.stringify({
canvas,
colorDepth,
deviceMemory,
devicePixelRatio,
hardwareConcurrency,
height,
maxTouchPoints,
pixelDepth,
platform,
touchSupport,
webgl,
webglInfo,
width,
})
: JSON.stringify({
appCodeName,
appName,
appVersion,
canvas,
colorDepth,
cookieEnabled,
deviceMemory,
devicePixelRatio,
doNotTrack,
hardwareConcurrency,
height,
language,
languages,
maxTouchPoints,
pixelDepth,
platform,
product,
productSub,
timezone,
timezoneOffset,
touchSupport,
userAgent,
vendor,
vendorSub,
webgl,
webglInfo,
width,
});
const datastring = JSON.stringify(data, null, 4);
if (debug) console.log('fingerprint data', datastring);
const result = murmurhash3_32_gc(datastring);
return result;
};
export const getCanvasID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(text, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(text, 4, 17);
const result = canvas.toDataURL();
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglID = (debug) => {
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('webgl');
canvas.width = 256;
canvas.height = 128;
const f =
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
const g = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
const h = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW), (h.itemSize = 3), (h.numItems = 3);
const j = ctx.createProgram();
const k = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(k, f);
ctx.compileShader(k);
const l = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(l, g);
ctx.compileShader(l);
ctx.attachShader(j, k);
ctx.attachShader(j, l);
ctx.linkProgram(j);
ctx.useProgram(j);
j.vertexPosAttrib = ctx.getAttribLocation(j, 'attrVertex');
j.offsetUniform = ctx.getUniformLocation(j, 'uniformOffset');
ctx.enableVertexAttribArray(j.vertexPosArray);
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
ctx.uniform2f(j.offsetUniform, 1, 1);
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, h.numItems);
const n = new Uint8Array(canvas.width * canvas.height * 4);
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, '');
if (debug) {
document.body.appendChild(canvas);
} else {
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
}
return murmurhash3_32_gc(result);
} catch {
return null;
}
};
export const getWebglInfo = () => {
try {
const ctx = document.createElement('canvas').getContext('webgl');
const result = {
VERSION: ctx.getParameter(ctx.VERSION),
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
VENDOR: ctx.getParameter(ctx.VENDOR),
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
};
return result;
} catch {
return null;
}
};
export const murmurhash3_32_gc = (key) => {
const remainder = key.length & 3; // key.length % 4
const bytes = key.length - remainder;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
let h1, h1b, k1;
for (let i = 0; i < bytes; i++) {
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
}
const i = bytes - 1;
k1 = 0;
switch (remainder) {
case 3: {
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
break;
}
case 2: {
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
break;
}
case 1: {
k1 ^= key.charCodeAt(i) & 0xff;
break;
}
}
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
export default getBrowserFingerprint;

151
js/9.2/init.js Normal file
View File

@ -0,0 +1,151 @@
import { hideMenus, showMenu, showSidebar, showTextBlocks, clickSetForm, clickImportFiles } from "./evts.js";
import { buildFile } from "./files.js";
import setPassword, { passwordHash } from "./scripts.js";
import { getUsrId } from "./scripts.js";
import parseFormOnSubmit from "./parseForm.js";
import { createStorageObj } from "./storage.js";
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { loadNavBar, initTextBlocks } from "./web.js";
window.activeState = {
userId: getUsrId(),
activePage: "landing",
loadedTemplate: "",
fileName: "",
lastElement: "",
serverFilesTs: "",
templates: [],
templateFieldTypes: [
"simpleInput",
"longText",
"hiddenField",
"current_time",
"current_date",
"markup",
],
markups: [
"title",
"link",
"italic",
"green_highlighted",
"highlighted",
]
};
function init() {
//check if user is logged in
let verfiedStatus = window.sessionStorage.getItem(sha256("verified"));
if (verfiedStatus != null) {
//user logged in
//write verifiedStatus content into passwordHash for decode check later
passwordHash.set(XORCipher.decode(sha256("passwordHash"), verfiedStatus));
document.getElementById("login").style.display = "none";
} else {
document.getElementById("login").style.display = "block";
}
//load NavigationBar with templates according to server
loadNavBar();
//init Textblocks field with entries according to server
initTextBlocks();
//add event listeners to document and window
eventListeners();
//print current version to footer
printVersion();
//adjust title for mobile use
if (screen.width < 993) {
document.getElementById("siteTitle").innerHTML = "TG";
}
}
function eventListeners() {
//add hideMenu to Body
document
.getElementsByClassName("w3-main")[0]
.addEventListener("click", hideMenus);
//add set Password to loginForm
document
.getElementById("submitPassword")
.addEventListener("click", setPassword);
//add toggle Navigation Menu
document
.getElementById("toggleNavigationMenu")
.addEventListener("click", showMenu);
//add loadTemplateBtn event showMenu
document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu);
//add toggle sideBar Menu
document
.getElementById("toggleSidebarMenu")
.addEventListener("click", showSidebar);
//add toggle files Menu and sidebar button
document
.getElementById("toggleFilesMenuSB")
.addEventListener("click", buildFile);
document
.getElementById("toggleFilesMenu")
.addEventListener("click", buildFile);
//add load template sidebar entry
document
.getElementById("loadTemplateBtn")
.addEventListener("click", showMenu);
//add toggle textBLocks Menu
document
.getElementById("toggleTestBlocksMenu")
.addEventListener("click", showTextBlocks);
//add setFormBtn for use in form
document
.getElementById("setFormBtn")
.addEventListener("click", (e) => clickSetForm(e));
//add saveFiles to server listener on launch page
document
.getElementById("importFilesSB")
.addEventListener("click", () => clickImportFiles());
//add key listener for ctrl s in form mode
window.addEventListener("keydown", (e) => {
if (e.ctrlKey && e.key == "s") {
if (activeState.activePage == "form");
createStorageObj();
parseFormOnSubmit();
e.preventDefault();
}
})
}
function printVersion() {
const scripts = document.getElementsByTagName("script");
const versionSpan = document.getElementById("currentVersion").lastChild;
for (var i=0;i<scripts.length;i++) {
if (scripts[i].src) {
let source = scripts[i].src;
// js/version/main.js
let pathVersion = source.split("/");
pathVersion = pathVersion[pathVersion.length-2];
//add it to document footer currentVersion
versionSpan.textContent = "version: " + pathVersion;
}
}
}
export default init;

7
js/9.2/main.js Normal file
View File

@ -0,0 +1,7 @@
import init from "./init.js";
document.addEventListener("DOMContentLoaded", () => init());

362
js/9.2/parseForm.js Normal file
View File

@ -0,0 +1,362 @@
import { storeData, clearData, retrieveData } from "./storage.js";
function parseFormOnSubmit(returnJSON = false, parseOnly = false) {
//event.preventDefault;
let dataArray = [];
if (parseOnly) {
let lT = activeState.loadedTemplate;
dataArray = retrieveData("userInputForce", lT);
if (dataArray != "") {
try {
dataArray = JSON.parse(dataArray);
} catch (e) {
alert("Decryption failed; are you authenticated?");
window.location.reload();
return;
}
}
if (dataArray == null) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder();
let div = wrapper.firstChild;
return div;
}
if (dataArray.length <= 0) {
let wrapper = document.createElement("div");
wrapper.innerHTML = mainFormPlaceholder();
let div = wrapper.firstChild;
return div;
}
} else {
let x = document.getElementById("mainFormObj");
if (x != null) {
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
}
//set filename to active state according to userFileName field from loadTemplate
let userFileNameField = document.getElementById("userFileName");
let userFileName = userFileNameField.value;
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
} else if (userFileNamePH != null) {
activeState.fileName = userFileNamePH;
}
}
//get original objects from sessionstorage gen from loadTemplate
let objects = JSON.parse(window.sessionStorage.getItem("templateObjects"));
//get the complete unparsed template string from sessionstorage from loadTemplate
let fullString = window.sessionStorage.getItem("fullString");
let b = "";
if (objects == null) {
return;
}
//iterate through templateObjects and look for according formdata
for (let obj of objects) {
for (let data of dataArray) {
//convert conList Master name to default name as set flag for appending connected list fields cl-name
let conListFlag = false;
if (data.name.split("-")[0] == "clM") {
if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
conListFlag = true;
data.name = data.name.substring(4);
if (data.value == "!none") {
obj.result = "";
continue;
}
if (data.value == "!selected") {
data.value = obj[0];
obj.result = "";
}
}
}
if (obj.word.replace(/ /g, "_") === data.name) {
let value = parseDataForResult(obj, data.value);
obj.result = value;
}
if (conListFlag) {
if (obj.type == "conList") {
//check for button if only one item exists and search conlist item
if (obj.listCount == 0) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
//console.log(d, obj[0], data);
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
obj.result = obj.result + "\n" + value;
}
}
}
} else {
//loop through dataArray and look for coresponding conlist items
for (let i = 0; i <= obj.listCount; i++) {
for (let d of dataArray) {
if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
d.name = d.name.split(":!")[0];
if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
if (data.value.replace(/ /g, "_") == d.name.substring(3)) {
if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
let value = parseDataForResult(obj, d.value);
obj.result = obj.result + "\n" + value;
}
}
}
}
}
}
}
}
}
//console.log(this, dataArray);
b = fullString.substring(0, objects[0].spos);
for (let i = 0; i < objects.length; i++) {
let j = i + 1;
if (objects[j] === undefined) {
b +=
objects[i].result +
fullString.substring(objects[i].epos, fullString.length);
} else {
b +=
objects[i].result +
fullString.substring(objects[i].epos, objects[j].spos);
}
}
let bHtml = b.replace(/(?:\r\n|\r|\n)/g, "<br>");
bHtml = bHtml.replace(/!l /g, " • ");
bHtml = bHtml.replace(/!ls /g, " ○ ");
bHtml = bHtml.replace(/ /g, "&nbsp;");
bHtml =
"<div style='font-family: Arial, Helvetica, sans-serif;'>" +
bHtml +
"</div>";
let div = document.createElement("div");
div.classList.add("w3-code", "notranslate", "w3-border-white");
div.id = "fileDisplay";
div.innerHTML = bHtml;
if (parseOnly) {
return div;
}
let p = document.createElement("p");
p.innerHTML = "Copied to Clipboard:";
document.getElementById("output").innerHTML = "";
document.getElementById("output").appendChild(p);
document.getElementById("output").appendChild(div);
storeData("userInput", JSON.stringify(dataArray));
clearData("userInput");
if (returnJSON) {
return dataArray;
} else {
copyToClipBoard(bHtml);
}
}
function parseDataForResult(obj, value) {
//handle placeholders like title, link, italic
if (obj.hasOwnProperty("placeholder") && value !== "") {
//console.log(obj.placeholder);
//check for markups
if (activeState.markups.includes(obj.placeholder)) {
value = parseMarkupmarkups(value, obj.placeholder);
} else {
value = obj.placeholder + "\n" + value;
}
}
//Plugin TextBlock Insertion according to file _textblocks.txt
value = parseTextBlocks(value);
//handle placeholders like !l or !n and set it to final interpreted string for object
value = parseTextMarkups(value);
return value;
}
export function parseTextMarkups(data) {
let dataArray = data.split("\n");
let listFlag = false;
let listSubFlag = false;
let boldFlag = false;
let listNumberFlag = false;
let listNumberFlagNum = 1;
for (let i = 0; i < dataArray.length; i++) {
switch (dataArray[i]) {
case "!l":
listFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!ls":
listSubFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!n":
listNumberFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!b":
boldFlag = true;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!e":
listFlag = false;
listNumberFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
case "!es":
listSubFlag = false;
dataArray.splice(i, 1);
i = i - 1;
break;
default:
if (boldFlag) {
dataArray[i] = "<b>" + dataArray[i] + "</b>";
boldFlag = false;
}
if (listSubFlag) {
dataArray[i] = " ○ " + dataArray[i];
continue;
}
if (listFlag) {
dataArray[i] = " • " + dataArray[i];
}
if (listNumberFlag) {
dataArray[i] = " " + listNumberFlagNum + ". " + dataArray[i];
listNumberFlagNum++;
}
}
}
return dataArray.join("\n");
}
function parseMarkupmarkups(value, markup) {
switch (markup) {
case "title":
return "<b>" + value + "</b>";
break;
case "italic":
return "<i>" + value + "</i>";
break;
}
}
function parseTextBlocks(data) {
let textBlocks = loadTextBlocks();
let textBlockIds = Object.keys(textBlocks);
for (let i = 0; i < textBlockIds.length; i++) {
let id = textBlockIds[i];
if (data.indexOf("!" + id) !== -1) {
//console.log("found: "+id);
let sPos = data.indexOf("!" + id);
let ePos = sPos + id.length + 1;
data =
data.substring(0, sPos) +
textBlocks[id] +
data.substring(ePos, data.length);
}
}
return data;
}
function loadTextBlocks() {
let textBlocks = document.getElementById("textBlocks").innerText;
let textBlocksObject = {};
if (textBlocks.indexOf("\r\n") !== -1) {
var wordArrayByLine = textBlocks.split("\r\n");
} else {
var wordArrayByLine = textBlocks.split("\n");
}
for (let i = 0; i < wordArrayByLine.length; i++) {
let textBlockId = wordArrayByLine[i].split(":")[0];
let textBlockText = wordArrayByLine[i].substring(
textBlockId.length + 2,
wordArrayByLine[i].length
);
if (textBlockId.length < 1) {
continue;
}
textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
}
return textBlocksObject;
}
function copyToClipBoard(html) {
// Create an iframe (isolated container) for the HTML
var container = document.createElement("div");
container.innerHTML = html;
// Hide element
container.style.position = "fixed";
container.style.pointerEvents = "none";
container.style.opacity = 0;
// Detect all style sheets of the page
var activeSheets = Array.prototype.slice
.call(document.styleSheets)
.filter(function (sheet) {
return !sheet.disabled;
});
// Mount the iframe to the DOM to make `contentWindow` available
document.body.appendChild(container);
// Copy to clipboard
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
document.execCommand("copy");
for (var i = 0; i < activeSheets.length; i++)
activeSheets[i].disabled = false;
// Remove the iframe
document.body.removeChild(container);
}
function mainFormPlaceholder() {
return "<div class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>Select a file</p><br><br><br><br><br><br><br><br><br><br><br></div></div>";
}
export default parseFormOnSubmit;

374
js/9.2/parseTemplate.js Normal file
View File

@ -0,0 +1,374 @@
function parseInput(wordArray, objects, i) {
let word = wordArray[i];
if (word.substring(0, 1) == "%") {
//check if regular use of % in text 20% an ignoreCase
if (word.substring(0, 2) !== "% ") {
//found simple input %word / excluding %m:
if (word.substring(2, 3) !== ":") {
//init Word Object
var wordObj = {};
let w = word.substring(1);
//for loop to escape spaces in simple input
for (let j = i + 1; j < wordArray.length; j++) {
w = w + " " + wordArray[j];
//invoke look for gender specific template
i = findGenderSpecificInput(wordArray, wordObj, j);
//invoke look for list template
i = findListInput(wordArray, wordObj, j);
//invoke connected fields
i = findConnectedListInput(wordArray, wordObj, j);
//find end of template string and format it for future handling¨
if (w.indexOf("%") !== -1) {
//found % sign
if (w.indexOf("%") !== w.length - 1) {
//% is not last char of string
word = "%" + w;
} else {
//% is last
//no prio has been set
word = w.slice(0, -1);
}
break;
}
}
if (word.indexOf("\n") !== -1) {
if (word.substring(word.indexOf("\n"), 2).indexOf("%") !== -1) {
//alert("attention newlineChar in: "+ word.substring(word.indexOf("\n"),2));
}
}
//parse priority
if (word.substring(1).indexOf("%") === -1) {
//object if no prio was set
wordObj.word = word;
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
} else {
//handle edgecase if punctuation mark is directly after prio
let postMarker = word.substring(1).indexOf("%") + 2;
let postMarkerEnd = word.length;
let isPriority = true;
let i = 0;
//console.log(word + " * " + word.substring(postMarkerEnd-2, postMarkerEnd) + " - " + postMarker + ":" + postMarkerEnd + " - " + word.length);
while (
!isCharNumber(word.substring(postMarkerEnd - 1, postMarkerEnd))
) {
postMarkerEnd = postMarkerEnd - 1;
//if no priority has been set; set flag
//console.log(word.substring(postMarkerEnd-1, postMarkerEnd));
if (postMarkerEnd < 1) {
isPriority = false;
break;
}
i++;
}
if (isPriority) {
//console.log(word + " prio: "+isPriority);
//object if prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = parseInt(
word.substring(postMarker, postMarkerEnd),
10
);
if (isNaN(wordObj.prio)) {
alert(
"error in template: %" +
wordObj.word +
"% there must always a space after the priority number"
);
wordObj.prio = 0;
}
} else {
//object if no prio has been defined
wordObj.word = word.substring(1, postMarker - 1);
wordObj.arrayPos = objects.length;
wordObj.prio = 0;
}
}
//check if genderSpecific or list has been found and if so reformat word
//console.log(wordObj);
switch (wordObj.type) {
case "genderSpecific":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "list":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
break;
case "conList":
if (word.substring(0, 1) === "%") {
wordObj.word = word.split("=")[0].substring(1);
} else {
wordObj.word = word.split("=")[0];
}
//check if format has been given or markup
for (let i = 0; i <= wordObj.listCount; i++) {
let params = wordObj[i].split(":");
if (params[1] !== undefined) {
wordObj[i] = params[0];
wordObj["clType-"+wordObj[i]] = (params[2] !== undefined) ? params[1]+":"+params[2]: params[1];
} else {
wordObj["clType-"+wordObj[i]] = "cl-simpleInput";
}
}
break;
default:
wordObj.type = "simpleInput";
//check if customTemplate was used set type and format word
if (word.indexOf("=") !== -1) {
parseCustomTemplates(wordObj);
}
break;
}
objects.push(wordObj);
}
}
}
}
function findGenderSpecificInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=m:") !== -1) {
wordObj.type = "genderSpecific";
let mw = word.substring(word.indexOf("=m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=w:") !== -1) {
let ww = word.substring(word.indexOf("=w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf("=d:") !== -1) {
let dw = word.substring(word.indexOf("=d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseGenderTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";m:") !== -1) {
let mw = word.substring(word.indexOf(";m:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
mw = mw + " " + wordArray[j];
i = j;
if (mw.indexOf(";") !== -1) {
wordObj.m = mw.slice(0, mw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";w:") !== -1) {
let ww = word.substring(word.indexOf(";w:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
ww = ww + " " + wordArray[j];
i = j;
if (ww.indexOf(";") !== -1) {
wordObj.w = ww.slice(0, ww.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
if (word.indexOf(";d:") !== -1) {
let dw = word.substring(word.indexOf(";d:") + 3);
for (let j = i + 1; j < wordArray.length; j++) {
dw = dw + " " + wordArray[j];
i = j;
if (dw.indexOf(";") !== -1) {
wordObj.d = dw.slice(0, dw.indexOf(";"));
i = parseGenderTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=l:") !== -1) {
wordObj.type = "list";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";l:") !== -1) {
let lw = word.substring(word.indexOf(";l:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function findConnectedListInput(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf("=h:") !== -1) {
wordObj.type = "conList";
wordObj.listCount = 0;
let lw = word.substring(word.indexOf("=h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//adding length word + 3 = m: ;
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseConnectedListTemplate(wordArray, wordObj, i) {
let word = wordArray[i];
if (word.indexOf(";h:") !== -1) {
let lw = word.substring(word.indexOf(";h:") + 3);
//escape if there is no space in listitem
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
//shorten wordArray and hand it to parseListTemplate: firstItem;l:secondItem;l: to ;l:secondItem;l:third Item
wordArray[i] = wordArray[i]
.substring(1)
.substring(wordArray[i].indexOf(";") + 1);
//advance wordArray i if third Item has a space in it and no ; is found to avoid endless loop
if (wordArray[i].substring(1).indexOf(";") === -1) {
i++;
}
//console.log(wordArray[i].substring(1));
i = parseConnectedListTemplate(wordArray, wordObj, i);
return i;
}
for (let j = i + 1; j < wordArray.length; j++) {
lw = lw + " " + wordArray[j];
i = j;
if (lw.indexOf(";") !== -1) {
wordObj.listCount++;
wordObj[wordObj.listCount] = lw.slice(0, lw.indexOf(";"));
i = parseConnectedListTemplate(wordArray, wordObj, i);
break;
}
}
}
return i;
}
function parseCustomTemplates(wordObj) {
let word = wordObj.word;
for (let i = 0; i < activeState.templateFieldTypes.length; i++) {
if (word.indexOf("=" + activeState.templateFieldTypes[i]) !== -1) {
wordObj.word = word.split("=")[0];
wordObj.type = word.split("=")[1];
if (wordObj.type.indexOf(":") !== -1) {
let ltPlaceholder = wordObj.type.split(":")[1];
if (ltPlaceholder !== "undefined") {
wordObj.placeholder = ltPlaceholder;
//wordObj.type = wordObj.type.split(":")[0]; - dont do this
}
}
}
}
}
function isCharNumber(c) {
return c >= "0" && c <= "9";
}
export default parseInput;

76
js/9.2/scripts.js Normal file
View File

@ -0,0 +1,76 @@
import { retrieveData } from "./storage.js";
import sha256 from "./sha256.min.js";
import XORCipher from "./xorc.js";
import getBrowserFingerprint from "./identify.js"
export const passwordHash = {
toString: () => {
let fp = getBrowserFingerprint( { hardwareOnly: true } );
let data;
try {
data = window.sessionStorage.getItem(sha256(fp));
} catch (e) {
return "none";
}
if (data === null) return "none";
return XORCipher.decode(fp, data);
},
set: (pw) => {
let fp = getBrowserFingerprint( { hardwareOnly: true } );
window.sessionStorage.setItem(sha256(fp), XORCipher.encode(fp, pw));
}
}
function setPassword() {
let x = document.getElementById("loginForm");
let pw = x.elements[0].value;
if (pw != "" || pw !== "undefined") {
let pwOld = pw;
passwordHash.set(sha256(pw));
let templateFiles = retrieveData("templateFiles");
if (templateFiles != "") {
try {
JSON.parse(templateFiles);
} catch (e) {
document.getElementById("wrongPWAlert").style.display = "block";
const alertTimeout = setTimeout(() => {
document.getElementById("wrongPWAlert").style.display = "none";
}, 5000);
passwordHash.set(pwOld);
x.elements[0].value = "";
return;
}
}
//user logged in
document.getElementById("login").style.display = "none";
window.sessionStorage.setItem(sha256("verified"), XORCipher.encode(sha256("passwordHash"), passwordHash));
}
}
export function getUsrId() {
const fingerprint = getBrowserFingerprint( { hardwareOnly: true } );
return cyrb53(fingerprint + passwordHash);
}
const cyrb53 = (str, seed = 21) => {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
};
export default setPassword;

3
js/9.2/sha256.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
export default sha256;

223
js/9.2/storage.js Normal file
View File

@ -0,0 +1,223 @@
import XORCipher from "./xorc.js";
import sha256 from "./sha256.min.js";
import { getUsrId, passwordHash } from "./scripts.js";
function createStorageObj() {
let x = document.getElementById("mainFormObj");
let dataArray = [];
if (x == null) {
return;
}
for (let i = 0; i < x.length; i++) {
dataArray.push({
value: x.elements[i].value,
name: x.elements[i].name,
});
}
//console.log(this, dataArray);
let userFileNameField = document.getElementById("userFileName");
let userFileName = userFileNameField.value;
let userFileNamePH = userFileNameField.getAttribute("placeholder");
if (userFileName.length != 0) {
activeState.fileName = userFileName;
//clear old data as file switches to new filename
if (userFileNamePH.length != 0) {
clearData(userFileNamePH);
popFromTemplateFiles(userFileNamePH);
}
} else if (userFileNamePH.length != 0) {
activeState.fileName = userFileNamePH;
}
storeData("userInput", JSON.stringify(dataArray));
}
function storeData(name, data) {
//setCookie(name, btoa(data), 7);
if (name == "userInput") {
name = getFileName();
}
if (name == "userInputForce") {
name = "userInput";
}
let lT = activeState.loadedTemplate;
let key = sha256(name + "-" + lT);
if (name == "templateFiles") {
key = sha256(name + "-");
}
window.localStorage.setItem(key, obfuscate(data));
}
function retrieveData(type, template = "none") {
if (type == "userInput") {
let tF = JSON.parse(retrieveData("templateFiles"));
if (tF == null) {
return "";
} else {
type = tF[tF.length - 1].fileName;
}
}
if (type == "userInputForce") {
type = "userInput";
}
let cdata;
if (template == "none") {
let lT = activeState.loadedTemplate;
let key = sha256(type + "-" + lT);
if (type == "templateFiles") {
key = sha256(type + "-");
}
cdata = window.localStorage.getItem(key);
} else {
let key = sha256(type + "-" + template);
cdata = window.localStorage.getItem(key);
}
if (cdata != null) {
return obfuscate(cdata, false);
} else {
return "[]";
}
}
function clearData(type, template = "none") {
let lT;
let key;
if (template == "none") {
lT = activeState.loadedTemplate;
key = sha256(type + "-" + lT);
if (type == "templateFiles") {
key = sha256(type + "-");
}
} else {
lT = template;
key = sha256(type + "-" + template);
}
window.localStorage.removeItem(key);
}
function getFileName() {
let currentFileName = activeState.fileName;
if (currentFileName == "none" || currentFileName == "") {
let date = new Date();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute =
current_minute <= 9 ? "0" + current_minute : current_minute;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_year = date.getDate();
current_year = current_year <= 9 ? "0" + current_year : current_year;
let current_time = current_hour + ":" + current_minute;
let current_date = current_year + "." + current_month;
currentFileName = current_time + "_" + current_date;
//console.log(currentFileName);
}
let lT = activeState.loadedTemplate;
let tF = retrieveData("templateFiles");
if (tF != "") {
try {
tF = JSON.parse(tF);
} catch (e) {
alert("Decryption failed; are you authenticated?");
window.location.reload();
return;
}
}
if (tF != null) {
for (let tFi of tF) {
if (tFi.fileName == currentFileName) {return currentFileName};
}
tF.push({ fileName: currentFileName, template: lT });
} else {
tF = [{ fileName: currentFileName, template: lT }];
}
storeData("templateFiles", JSON.stringify(tF));
activeState.fileName = currentFileName;
return currentFileName;
}
function obfuscate(data, mode = true) {
if (mode) {
return XORCipher.encode(sha256(passwordHash), data);
} else {
return XORCipher.decode(sha256(passwordHash), data);
}
}
function popFromTemplateFiles(fileName) {
let tF = JSON.parse(retrieveData("templateFiles"));
let newArray = [];
for (let obj of tF) {
if (obj.fileName != fileName) {
newArray.push(obj);
}
}
storeData("templateFiles", JSON.stringify(newArray));
}
function createBookShelf() {
let tF = JSON.parse(retrieveData("templateFiles"));
let bookShelf = {};
let date = new Date();
let current_hour = date.getHours();
current_hour = current_hour <= 9 ? "0" + current_hour : current_hour;
let current_minute = date.getMinutes();
current_minute =
current_minute <= 9 ? "0" + current_minute : current_minute;
let current_month = date.getMonth() + 1;
current_month = current_month <= 9 ? "0" + current_month : current_month;
let current_year = date.getDate();
current_year = current_year <= 9 ? "0" + current_year : current_year;
let current_time = current_hour + ":" + current_minute;
let current_date = current_year + "." + current_month;
let saveFileName = current_time + "_" + current_date;
if (tF != null) {
bookShelf[0] = {name: "hash", data: getUsrId(), ts: saveFileName};
let i = 1;
for (let tFi of tF) {
let data = retrieveData(tFi.fileName, tFi.template);
bookShelf[i] = {};
bookShelf[i].name = tFi.fileName + "-" + tFi.template;
bookShelf[i].data = obfuscate(data);
i++;
}
}
return bookShelf;
}
function importBookShelf() {
localStorage.clear()
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
console.log("no files saved on server");
} else {
let respText = decodeURIComponent(this.responseText);
let mainArray = JSON.parse(respText);
let templateFilesArray = [];
for (let file of mainArray) {
if (file.name == "hash") continue;
window.localStorage.setItem(sha256(file.name), file.data);
templateFilesArray.push({ fileName: file.name.split("-")[0], template: file.name.split("-")[1] });
}
window.localStorage.setItem(sha256("templateFiles-"), obfuscate(JSON.stringify(templateFilesArray)));
}
}
};
xhttp.open("GET", "php/?getStoredFiles="+getUsrId(), true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
export { createStorageObj, storeData, retrieveData, clearData, getFileName, createBookShelf, importBookShelf};

279
js/9.2/web.js Normal file
View File

@ -0,0 +1,279 @@
import buildForm from "./form.js";
import { loadFileDivCallBack } from "./files.js";
import { retrieveData, clearData, getFileName, importBookShelf } from "./storage.js";
import { insertTextBlocks } from "./evts.js";
import { createTemplate, createTemplateCallBack} from "./createTemplate.js";
import { getUsrId } from "./scripts.js";
function loadTemplate(template, newFlag = false, loadOnly = false) {
document.getElementById("siteTitle").innerHTML = template.replace(/_/g, " ");
activeState.loadedTemplate = template;
if (newFlag) {
activeState.fileName = "none";
} else {
activeState.fileName = getFileName();
}
document.getElementById("navMob").className = document
.getElementById("navMob")
.className.replace(" w3-show", "");
if (screen.width < 993) {
let sidebar = document.getElementById("sidebar");
sidebar.style.display = "none";
document.getElementById("siteTitle").innerHTML = "TG";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let respText = decodeURIComponent(this.responseText);
if (loadOnly == "createTemplate") {
createTemplateCallBack(template, respText.split("!JSON_placeholder:")[0]);
return;
}
buildForm(respText, loadOnly);
if (loadOnly) {
loadFileDivCallBack();
return;
}
//retrieve previos userData / or preset data if newFile is called
let cdata;
if (newFlag) {
cdata = retrieveData("templatePreset", template);
} else {
cdata = retrieveData("userInputForce");
}
if (cdata != "") {
retrieveForm(JSON.parse(cdata));
}
//select first object and focus on it
let obj = JSON.parse(
window.sessionStorage.getItem("templateObjectsPurified")
);
let firstElement = document.getElementById(obj[0].word.replace(/ /g, "_"));
if (firstElement != null) firstElement.focus();
}
};
xhttp.open("GET", "php/?template=" + template, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function loadNewTemplate(template) {
//set current page value in activeState object
activeState.activePage = "template";
let sidebarDiv = document.getElementById("sidebar");
sidebarDiv.replaceWith(sidebarDiv.cloneNode(true));
clearData("userInput", template);
loadTemplate(template, true);
}
function loadNavBar() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = JSON.parse(this.responseText);
let divMob = document.getElementById("navMob");
for (let x in res) {
let aMob = document.createElement("a");
aMob.setAttribute("href", "#");
aMob.setAttribute("data-template", res[x][1]);
aMob.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
aMob.innerHTML = res[x][0];
divMob.appendChild(aMob);
activeState.templates.push(res[x][1]);
}
let createEntry = document.createElement("a");
createEntry.setAttribute("href", "#");
createEntry.setAttribute("data-template", "createNew");
createEntry.classList.add("w3-bar-item", "w3-button", "w3-padding-large");
createEntry.innerHTML = "Manage templates";
divMob.appendChild(createEntry);
divMob.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
let template = e.target.dataset.template;
if (template == "createNew") {
createTemplate();
return;
}
loadNewTemplate(template);
}
});
}
};
xhttp.open("GET", "php/?templates", true);
xhttp.send();
}
function initTextBlocks() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let res = JSON.parse(this.responseText);
const textBlocksHolder = document.getElementById("textBlocks");
const divReg = document.getElementById("navTb");
for (let x in res) {
let aReg = document.createElement("a");
aReg.setAttribute("href", "#");
aReg.classList.add("w3-bar-item", "w3-hide-small", "w3-padding-small");
let textBlockText = res[x][1];
if (res[x][1].length > 80) {
textBlockText = res[x][1].substr(0, 80) + "...";
}
aReg.innerHTML = "<b>" + res[x][0] + ":</b> " + textBlockText;
divReg.appendChild(aReg);
const text = document.createTextNode(
res[x][0] + ": " + res[x][1] + "\n"
);
textBlocksHolder.appendChild(text);
}
divReg.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.w3-bar-item")) {
insertTextBlocks(e.target);
}
});
}
};
xhttp.open("GET", "php/?textBlocks", true);
xhttp.send();
}
function setTemplatePreset(template, formData) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setForm");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
let data = {
template: template,
data: formData,
};
xhttp.send(JSON.stringify(data));
}
function setNewTemplate(fileName, data) {
let obj = {
fileName: fileName,
data: data,
};
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "php/?setTemplate");
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//console.log(this.responseText);
}
};
xhttp.send(JSON.stringify(obj));
}
function storeFilesToServer(data) {
//console.log(template +" : "+ formData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "success") {
console.log("files saved");
}
}
};
xhttp.open("POST", "php/?storeFiles", true);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify(data));
}
function checkForStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
} else {
activeState.serverFilesTs = this.responseText;
let btn = document.getElementById("importModalBtn");
btn.style.display = "";
}
}
};
xhttp.open("GET", "php/?storedFiles="+getUsrId(), true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function delStoredDataOnServer() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "none") {
let btn = document.getElementById("importModalBtn");
btn.style.display = "none";
}
}
};
xhttp.open("GET", "php/?storedFiles="+getUsrId()+"&del", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhttp.send();
}
function retrieveForm(arr) {
for (let i = 0; i < arr.length; i++) {
let e = document.getElementById(arr[i].name);
if (e === null) {
e = document.getElementById(arr[i].name.split("cl-")[1]);
if (e === null) continue;
}
if (e.name.substr(0, 4) == "clM-") continue;
switch (e.nodeName) {
case "TEXTAREA":
e.innerHTML = arr[i].value;
break;
case "INPUT":
e.value = arr[i].value;
break;
case "SELECT":
for (let j = 0; j < e.options.length; j++) {
if (e.options[j].value == arr[i].value) {
// Item is found. Set its property and exit
e.options[j].selected = true;
break;
}
}
break;
default:
e.innerHTML = arr[i].value;
break;
}
}
}
export {
loadTemplate,
loadNavBar,
initTextBlocks,
loadNewTemplate,
setTemplatePreset,
setNewTemplate,
storeFilesToServer,
checkForStoredDataOnServer,
delStoredDataOnServer
};

Some files were not shown because too many files have changed in this diff Show More