HTML, CSS, JS and JAVA corrections (#810)
* CSS corrections * HTML corrections * JS corrections * JAVA corrections * remove tab * CSS corrections 2 * JS corrections 2 * back to the roots * max-linie 127 * add slash hr|br * return bootstrap-icons.css * return bootstrap-icons.min.css * return bootstrap.min.css * Update bootstrap-icons.css * Update bootstrap-icons.min.css * Update bootstrap-icons.min.css * Update bootstrap.min.css * CSS corrections * HTML corrections * JS corrections * JAVA corrections * remove tab * CSS corrections 2 * JS corrections 2 * back to the roots * max-linie 127 * add slash hr|br * return bootstrap-icons.css * Update bootstrap-icons.css * Bootstrap CSS * Update prism.css
This commit is contained in:
4
src/main/resources/static/css/account.css
Normal file
4
src/main/resources/static/css/account.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.buttons-container {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
28
src/main/resources/static/css/add-image.css
Normal file
28
src/main/resources/static/css/add-image.css
Normal file
@@ -0,0 +1,28 @@
|
||||
#box-drag-container {
|
||||
position: relative;
|
||||
margin: 20px 0;
|
||||
}
|
||||
#pdf-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.draggable-buttons-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.draggable-buttons-box > button {
|
||||
z-index: 10;
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
.draggable-canvas {
|
||||
border: 1px solid red;
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
/* Dark Mode Styles */
|
||||
body, select, textarea {
|
||||
--body-background-color: 51, 51, 51;
|
||||
--base-font-color: 255, 255, 255;
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
body,
|
||||
select,
|
||||
textarea {
|
||||
--body-background-color: 51, 51, 51;
|
||||
--base-font-color: 255, 255, 255;
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.card {
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
@@ -11,11 +13,11 @@ body, select, textarea {
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #add8e6;
|
||||
}
|
||||
a:hover {
|
||||
color: #87ceeb; /* Slightly brighter blue on hover for accessibility */
|
||||
a {
|
||||
color: #add8e6;
|
||||
}
|
||||
a:hover {
|
||||
color: #87ceeb; /* Slightly brighter blue on hover for accessibility */
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
@@ -36,7 +38,7 @@ body, select, textarea {
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
#support-section {
|
||||
background-color: #444 !important;
|
||||
background-color: #444 !important;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
@@ -47,89 +49,93 @@ body, select, textarea {
|
||||
}
|
||||
|
||||
.favorite-icon img {
|
||||
filter: brightness(0) invert(1) !important;
|
||||
filter: brightness(0) invert(1) !important;
|
||||
}
|
||||
table thead {
|
||||
background-color: #333 !important;
|
||||
border: 1px solid #444;
|
||||
background-color: #333 !important;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
table th, table td {
|
||||
border: 1px solid #444 !important;
|
||||
color: white;
|
||||
table th,
|
||||
table td {
|
||||
border: 1px solid #444 !important;
|
||||
color: white;
|
||||
}
|
||||
.btn {
|
||||
background-color: #444 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
background-color: #444 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #007bff !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
background-color: #007bff !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-secondary {
|
||||
background-color: #6c757d !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
background-color: #6c757d !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-info {
|
||||
background-color: #17a2b8 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
background-color: #17a2b8 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-danger {
|
||||
background-color: #dc3545 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
background-color: #dc3545 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background-color: #ffc107 !important;
|
||||
border: none;
|
||||
color: #000 !important;
|
||||
background-color: #ffc107 !important;
|
||||
border: none;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
.btn-outline-secondary:hover {
|
||||
background-color: #444 !important;
|
||||
color: #007bff !important;
|
||||
border-color: #007bff;
|
||||
background-color: #444 !important;
|
||||
color: #007bff !important;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.blackwhite-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
hr {
|
||||
border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */
|
||||
background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */
|
||||
border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */
|
||||
background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
#global-buttons-container input {
|
||||
background-color: #323948;
|
||||
caret-color: #ffffff;
|
||||
color: #ffffff;
|
||||
background-color: #323948;
|
||||
caret-color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
#global-buttons-container input::placeholder {
|
||||
color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#global-buttons-container input:disabled::-webkit-input-placeholder { /* WebKit browsers */
|
||||
color: #6E6865;
|
||||
#global-buttons-container input:disabled::-webkit-input-placeholder {
|
||||
/* WebKit browsers */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
|
||||
color: #6E6865;
|
||||
#global-buttons-container input:disabled:-moz-placeholder {
|
||||
/* Mozilla Firefox 4 to 18 */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled::-moz-placeholder { /* Mozilla Firefox 19+ */
|
||||
color: #6E6865;
|
||||
#global-buttons-container input:disabled::-moz-placeholder {
|
||||
/* Mozilla Firefox 19+ */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-ms-input-placeholder { /* Internet Explorer 10+ */
|
||||
color: #6E6865;
|
||||
#global-buttons-container input:disabled:-ms-input-placeholder {
|
||||
/* Internet Explorer 10+ */
|
||||
color: #6e6865;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
#drag-container {
|
||||
position: fixed;
|
||||
display:flex;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#drag-container:not(:empty) {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#drag-container .dragged-img {
|
||||
position: fixed;
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.58);
|
||||
transform-origin: top left;
|
||||
position: fixed;
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.58);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.drag-manager_dragging {
|
||||
width: 0px;
|
||||
visibility: hidden;
|
||||
width: 0px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.drag-manager_draghover {
|
||||
width: 375px !important;
|
||||
width: 375px !important;
|
||||
}
|
||||
|
||||
.drag-manager_draghover .insert-file-button-container {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.drag-manager_draghover .button-container {
|
||||
visibility: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .drag-manager_draghover img {
|
||||
left: calc(50% + 62.5px) !important;
|
||||
html[lang-direction="ltr"] .drag-manager_draghover img {
|
||||
left: calc(50% + 62.5px) !important;
|
||||
}
|
||||
|
||||
html[lang-direction=rtl] .drag-manager_draghover img {
|
||||
left: 125px
|
||||
html[lang-direction="rtl"] .drag-manager_draghover img {
|
||||
left: 125px;
|
||||
}
|
||||
|
||||
.drag-manager_dragging-container .hide-on-drag {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint {
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background-color: #FFFFFF10;
|
||||
transition: width 0.1s;
|
||||
animation: end-drop-expand .3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background-color: #ffffff10;
|
||||
transition: width 0.1s;
|
||||
animation: end-drop-expand 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint svg {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint.drag-manager_draghover {
|
||||
width: 150px !important;
|
||||
width: 150px !important;
|
||||
}
|
||||
|
||||
@keyframes end-drop-expand {
|
||||
from {
|
||||
width: 0;
|
||||
}
|
||||
to {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
from {
|
||||
width: 0;
|
||||
}
|
||||
to {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
88
src/main/resources/static/css/error.css
Normal file
88
src/main/resources/static/css/error.css
Normal file
@@ -0,0 +1,88 @@
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#support-section {
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#support-section h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#support-section p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#button-group {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#github-button,
|
||||
#discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008cba;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#github-button:hover,
|
||||
#discord-button:hover,
|
||||
#home-button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#home-button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008cba;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
@@ -1,94 +1,97 @@
|
||||
#errorContainer {
|
||||
margin: 20px; /* adjust this value as needed */
|
||||
margin: 20px; /* adjust this value as needed */
|
||||
}
|
||||
|
||||
#helpModalDialog {
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
#helpModal h1 {
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
#helpModal p {
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#helpModal .button:hover {
|
||||
background-color: #005b7f;
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#helpModal .features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
#helpModal .feature-card {
|
||||
border: 1px solid rgba(0, 0, 0, .125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#helpModal .feature-card .card-text {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#support-section {
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#support-section h1 {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#support-section p {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#button-group {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#github-button, #discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008CBA;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
#github-button,
|
||||
#discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008cba;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#github-button:hover, #discord-button:hover, #home-button:hover {
|
||||
background-color: #005b7f;
|
||||
#github-button:hover,
|
||||
#discord-button:hover,
|
||||
#home-button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#home-button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008CBA;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008cba;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.custom-file-label {
|
||||
padding-right: 90px;
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.selected-files {
|
||||
margin-top: 10px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
margin-top: 10px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
20
src/main/resources/static/css/footer.css
Normal file
20
src/main/resources/static/css/footer.css
Normal file
@@ -0,0 +1,20 @@
|
||||
#footer {
|
||||
display: flex;
|
||||
flex-direction: column; /* Stack children vertically */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer-center {
|
||||
display: flex;
|
||||
align-items: center; /* Center children horizontally */
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.footer-powered-by {
|
||||
margin-top: auto; /* Pushes the text to the bottom */
|
||||
color: grey;
|
||||
text-align: center; /* Centers the text inside the div */
|
||||
width: 100%; /* Full width to center the text properly */
|
||||
}
|
||||
@@ -1,49 +1,54 @@
|
||||
#game-container {
|
||||
position: relative;
|
||||
width: 100vh;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
position: relative;
|
||||
width: 100vh;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
}
|
||||
|
||||
.pdf, .player, .projectile {
|
||||
position: absolute;
|
||||
.pdf,
|
||||
.player,
|
||||
.projectile {
|
||||
position: absolute;
|
||||
}
|
||||
.pdf {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.player {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.projectile {
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
}
|
||||
#score, #level, #lives, #high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
#score,
|
||||
#level,
|
||||
#lives,
|
||||
#high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
}
|
||||
#score {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
#lives {
|
||||
top: 10px;
|
||||
left: calc(7vw); /* Adjusted position */
|
||||
top: 10px;
|
||||
left: calc(7vw); /* Adjusted position */
|
||||
}
|
||||
#high-score {
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
}
|
||||
#level {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#page-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#footer {
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.navbar {
|
||||
height: auto; /* Adjusts height automatically based on content */
|
||||
white-space: nowrap; /* Prevents wrapping of navbar contents */
|
||||
height: auto; /* Adjusts height automatically based on content */
|
||||
white-space: nowrap; /* Prevents wrapping of navbar contents */
|
||||
}
|
||||
/* TODO enable later
|
||||
.navbar .container {
|
||||
@@ -25,70 +25,70 @@
|
||||
margin-right: auto;
|
||||
}*/
|
||||
|
||||
html[lang-direction=ltr] * {
|
||||
direction: ltr;
|
||||
html[lang-direction="ltr"] * {
|
||||
direction: ltr;
|
||||
}
|
||||
html[lang-direction=rtl] * {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
html[lang-direction="rtl"] * {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
.ignore-rtl {
|
||||
direction: ltr !important;
|
||||
text-align: left !important;
|
||||
direction: ltr !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.align-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.align-center-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-center-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.btn-group > label:first-of-type {
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
}
|
||||
|
||||
html[lang-direction="rtl"] input.form-check-input {
|
||||
position: relative;
|
||||
margin-left: 0px;
|
||||
position: relative;
|
||||
margin-left: 0px;
|
||||
}
|
||||
html[lang-direction="rtl"] label.form-check-label {
|
||||
display: inline;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.margin-auto-parent {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
.margin-center {
|
||||
margin: 0 auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#pdf-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.fixed-shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,64 +1,62 @@
|
||||
#searchBar {
|
||||
background-image: url('../images/search.svg');
|
||||
background-position: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 20px 12px 40px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
|
||||
background-image: url("../images/search.svg");
|
||||
background-position: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 20px 12px 40px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.dark-mode-search {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' hei… 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z'/%3E%3C/svg%3E") !important;
|
||||
color: #f8f9fa !important;
|
||||
background-color: #212529 !important;
|
||||
border-color: #343a40 !important;
|
||||
}
|
||||
|
||||
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' hei… 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z'/%3E%3C/svg%3E") !important;
|
||||
color: #f8f9fa !important;
|
||||
background-color: #212529 !important;
|
||||
border-color: #343a40 !important;
|
||||
}
|
||||
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
border: 2px solid rgba(0, 0, 0, .25);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: rgba(13, 110, 253, 0.05);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 2px solid transparent;
|
||||
border: 2px solid rgba(0, 0, 0, 0.25);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: rgba(13, 110, 253, 0.05);
|
||||
transition:
|
||||
transform 0.3s,
|
||||
border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 2px solid transparent;
|
||||
}
|
||||
|
||||
.feature-card a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
outline: 1px solid rgba(0, 0, 0, .5);
|
||||
cursor: pointer;
|
||||
transform: scale(1.1);
|
||||
outline: 1px solid rgba(0, 0, 0, 0.5);
|
||||
cursor: pointer;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.feature-card:hover .card-title {
|
||||
text-decoration: underline;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.card-title.text-primary {
|
||||
color: #000; /* Replace with your desired shade of blue */
|
||||
@@ -67,27 +65,27 @@
|
||||
.home-card-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
transform: translateY(-5px);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
.home-card-icon-colour {
|
||||
filter: invert(0.2) sepia(2) saturate(50) hue-rotate(190deg);
|
||||
filter: invert(0.2) sepia(2) saturate(50) hue-rotate(190deg);
|
||||
}
|
||||
|
||||
.favorite-icon {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
/* Only show the favorite icons when the parent card is being hovered over */
|
||||
.feature-card:hover .favorite-icon {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
.favorite-icon img {
|
||||
filter: brightness(0);
|
||||
filter: brightness(0);
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
padding: 3rem 3rem; /* Reduce vertical padding */
|
||||
padding: 3rem 3rem; /* Reduce vertical padding */
|
||||
}
|
||||
|
||||
@@ -1,40 +1,43 @@
|
||||
|
||||
#image-highlighter {
|
||||
position: fixed;
|
||||
display:flex;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
visibility: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: visbility 0.1s linear, background-color 0.1s linear;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
visibility: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition:
|
||||
visbility 0.1s linear,
|
||||
background-color 0.1s linear;
|
||||
}
|
||||
|
||||
#image-highlighter > * {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
animation: image-highlight .1s linear;
|
||||
transition: transform .1s linear, opacity .1s linear;
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
animation: image-highlight 0.1s linear;
|
||||
transition:
|
||||
transform 0.1s linear,
|
||||
opacity 0.1s linear;
|
||||
}
|
||||
|
||||
#image-highlighter > *.remove {
|
||||
transform: scale(0.8) !important;
|
||||
opacity: 0 !important;
|
||||
transform: scale(0.8) !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
#image-highlighter:not(:empty) {
|
||||
background-color: rgba(0, 0, 0, 0.37);
|
||||
visibility: visible;
|
||||
background-color: rgba(0, 0, 0, 0.37);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@keyframes image-highlight {
|
||||
from {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
from {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
9
src/main/resources/static/css/licenses.css
Normal file
9
src/main/resources/static/css/licenses.css
Normal file
@@ -0,0 +1,9 @@
|
||||
td a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td a:hover,
|
||||
td a:focus {
|
||||
text-decoration: underline;
|
||||
/* Adds underline on hover/focus for clarity */
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
/* Dark Mode Styles */
|
||||
body {
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
}
|
||||
|
||||
|
||||
#global-buttons-container input {
|
||||
background-color: #ffffff;
|
||||
/*caret-color: #ffffff;*/
|
||||
/*color: #ffffff;*/
|
||||
background-color: #ffffff;
|
||||
/*caret-color: #ffffff;*/
|
||||
/*color: #ffffff;*/
|
||||
}
|
||||
/*#global-buttons-container input:disabled::-webkit-input-placeholder { !* WebKit browsers *!*/
|
||||
/* color: #98A0AB;*/
|
||||
|
||||
111
src/main/resources/static/css/login.css
Normal file
111
src/main/resources/static/css/login.css
Normal file
@@ -0,0 +1,111 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="text"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.container-flex {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
width: 100%; /* Set width to 100% */
|
||||
align-items: center; /* Center its children horizontally */
|
||||
}
|
||||
.footer-bottom {
|
||||
margin-top: auto;
|
||||
}
|
||||
body.light-mode input:-webkit-autofill,
|
||||
body.light-mode input:-webkit-autofill:hover,
|
||||
body.light-mode input:-webkit-autofill:focus,
|
||||
body.light-mode input:-webkit-autofill:active {
|
||||
-webkit-text-fill-color: #212529; /* Dark font color */
|
||||
-webkit-box-shadow: 0 0 0 1000px #f8f9fa inset; /* Light background color */
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
body.dark-mode input:-webkit-autofill,
|
||||
body.dark-mode input:-webkit-autofill:hover,
|
||||
body.dark-mode input:-webkit-autofill:focus,
|
||||
body.dark-mode input:-webkit-autofill:active {
|
||||
-webkit-text-fill-color: #f8f9fa; /* Light font color */
|
||||
-webkit-box-shadow: 0 0 0 1000px #212529 inset; /* Dark background color */
|
||||
}
|
||||
/* Light Mode */
|
||||
body.light-mode .form-floating > input:focus + label {
|
||||
color: #212529 !important; /* Dark text for light background */
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
body.dark-mode .form-floating > input:focus + label {
|
||||
color: #fff !important; /* Light text for dark background */
|
||||
}
|
||||
|
||||
body.light-mode .form-floating > label {
|
||||
color: #212529 !important; /* Dark text for light background */
|
||||
}
|
||||
|
||||
body.dark-mode .form-floating > label {
|
||||
color: #fff !important; /* Light text for dark background */
|
||||
}
|
||||
|
||||
/* Removing default styles for ul and li */
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Positioning the container of these elements to the top right */
|
||||
.your-container-class {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Styling for the dropdown */
|
||||
.dropdown-menu {
|
||||
min-width: 200px; /* or whatever width you prefer */
|
||||
}
|
||||
|
||||
.navbar-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
.list-group-item {
|
||||
.list-group-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -25,5 +25,4 @@
|
||||
.move-down span {
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
|
||||
}
|
||||
|
||||
119
src/main/resources/static/css/multi-tool.css
Normal file
119
src/main/resources/static/css/multi-tool.css
Normal file
@@ -0,0 +1,119 @@
|
||||
.multi-tool-container {
|
||||
max-width: 95vw;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#global-buttons-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
backdrop-filter: blur(2px);
|
||||
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
#global-buttons-container > * {
|
||||
padding: 0.6rem 0.75rem;
|
||||
}
|
||||
|
||||
#global-buttons-container svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
#export-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(0, 0, 0, 0.025);
|
||||
--scroll-bar-color: #f1f1f1;
|
||||
--scroll-bar-thumb: #888;
|
||||
--scroll-bar-thumb-hover: #555;
|
||||
background-color: var(--background-color);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 25px;
|
||||
border-radius: 10px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
min-height: 275px;
|
||||
margin: 0 0 30px 0;
|
||||
}
|
||||
|
||||
#pages-container {
|
||||
margin: auto;
|
||||
gap: 0px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* width */
|
||||
#pages-container-wrapper::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
#pages-container-wrapper::-webkit-scrollbar-track {
|
||||
background: var(--scroll-bar-color);
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
#pages-container-wrapper::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: var(--scroll-bar-thumb);
|
||||
}
|
||||
|
||||
/* Handle on hover */
|
||||
#pages-container-wrapper::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--scroll-bar-thumb-hover);
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: 250px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column-reverse;
|
||||
aspect-ratio: 1;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
transition: width 1s linear;
|
||||
}
|
||||
|
||||
.page-container img {
|
||||
/* max-width: calc(100% - 15px); */
|
||||
max-height: calc(100% - 15px);
|
||||
max-width: 237px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
translate: -50% -50%;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
border-radius: 4px;
|
||||
transition: rotate 0.3s;
|
||||
}
|
||||
|
||||
#add-pdf-button {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
color: white;
|
||||
background-color: #007bff; /* Primary blue color */
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
z-index: 2;
|
||||
}
|
||||
@@ -1,80 +1,116 @@
|
||||
|
||||
|
||||
#navbarSearch {
|
||||
top: 100%;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
transition: all 0.3s;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#navbarSearch.show {
|
||||
max-height: 300px; /* Adjust this to your desired max height */
|
||||
}
|
||||
|
||||
#searchForm {
|
||||
width: 200px; /* Adjust this value as needed */
|
||||
width: 200px; /* Adjust this value as needed */
|
||||
}
|
||||
|
||||
/* Style the search results to match the navbar */
|
||||
#searchResults {
|
||||
max-height: 200px; /* Adjust this value as needed */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
max-height: 200px; /* Adjust this value as needed */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
max-width: 300px; /* Adjust to your preferred width */
|
||||
transition: height 0.3s ease; /* Smooth height transition */
|
||||
}
|
||||
|
||||
#searchResults .dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
height: 50px; /* Fixed height */
|
||||
overflow: hidden; /* Hide overflow */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
height: 50px; /* Fixed height */
|
||||
overflow: hidden; /* Hide overflow */
|
||||
}
|
||||
|
||||
#searchResults .icon {
|
||||
margin-right: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#searchResults .icon-text {
|
||||
display: inline;
|
||||
overflow: hidden; /* Hide overflow */
|
||||
text-overflow: ellipsis; /* Add ellipsis for long text */
|
||||
display: inline;
|
||||
overflow: hidden; /* Hide overflow */
|
||||
text-overflow: ellipsis; /* Add ellipsis for long text */
|
||||
}
|
||||
|
||||
#search-icon i {
|
||||
font-size: 24px; /* Adjust this to your desired size */
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
#search-icon:hover i {
|
||||
color: #666; /* Adjust this to your hover color */
|
||||
}
|
||||
|
||||
.search-input {
|
||||
transition:
|
||||
border 0.3s,
|
||||
box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: #666; /* Adjust this to your focus color */
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Adjust this to your desired shadow */
|
||||
}
|
||||
|
||||
/* Set a fixed height and styling for each search result item */
|
||||
.search-results a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px; /* space between icon and text */
|
||||
height: 40px; /* Adjust based on your design */
|
||||
overflow: hidden; /* Prevent content from overflowing */
|
||||
white-space: nowrap; /* Prevent text from wrapping to next line */
|
||||
text-overflow: ellipsis; /* Truncate text if it's too long */
|
||||
}
|
||||
|
||||
.main-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.icon+.icon {
|
||||
margin-left: -4px;
|
||||
.icon + .icon {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
margin-left: 4px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.nav-item-separator {
|
||||
position: relative;
|
||||
margin: 0 4px; /* Adjust the margin as needed */
|
||||
position: relative;
|
||||
margin: 0 4px; /* Adjust the margin as needed */
|
||||
}
|
||||
|
||||
.nav-item-separator::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10%; /* Adjust the top and bottom margins as needed */
|
||||
bottom: 10%;
|
||||
width: 1px;
|
||||
background-color: #ccc; /* Adjust the color as needed */
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10%; /* Adjust the top and bottom margins as needed */
|
||||
bottom: 10%;
|
||||
width: 1px;
|
||||
background-color: #ccc; /* Adjust the color as needed */
|
||||
}
|
||||
|
||||
.navbar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@@ -1,87 +1,85 @@
|
||||
|
||||
.pdf-actions_button-container {
|
||||
z-index: 2;
|
||||
display:flex;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear;
|
||||
}
|
||||
|
||||
.pdf-actions_container:hover .pdf-actions_button-container {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pdf-actions_button-container > * {
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin: 3px;
|
||||
display: block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin: 3px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pdf-actions_container svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.pdf-actions_container:nth-child(1) .pdf-actions_move-left-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
.pdf-actions_container:last-child .pdf-actions_move-right-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* "insert pdf" buttons that appear on the right when hover */
|
||||
.pdf-actions_insert-file-button-container {
|
||||
translate: 0 -50%;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
translate: 0 -50%;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.left {
|
||||
left: -20px;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.right {
|
||||
right: -20px;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .pdf-actions_insert-file-button-container.right {
|
||||
display:none;
|
||||
html[lang-direction="ltr"] .pdf-actions_insert-file-button-container.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[lang-direction=rtl] .pdf-actions_insert-file-button-container.left {
|
||||
display:none;
|
||||
html[lang-direction="rtl"] .pdf-actions_insert-file-button-container.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.left .pdf-actions_insert-file-button {
|
||||
left: 0;
|
||||
translate: 0 -50%;
|
||||
left: 0;
|
||||
translate: 0 -50%;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.right .pdf-actions_insert-file-button {
|
||||
right: 0;
|
||||
translate: 0 -50%;
|
||||
right: 0;
|
||||
translate: 0 -50%;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.right {
|
||||
display: block;
|
||||
html[lang-direction="ltr"] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.right {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
html[lang-direction=rtl] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.left {
|
||||
display: block;
|
||||
html[lang-direction="rtl"] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.left {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container:hover {
|
||||
opacity: 1;
|
||||
transition: opacity 0.05s;
|
||||
opacity: 1;
|
||||
transition: opacity 0.05s;
|
||||
}
|
||||
.pdf-actions_insert-file-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
translate: 50% -50%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 100px;
|
||||
}
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
translate: 50% -50%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
21
src/main/resources/static/css/pipeline.css
Normal file
21
src/main/resources/static/css/pipeline.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.btn-margin {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.bordered-box {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.center-element {
|
||||
width: 80%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.element-margin {
|
||||
margin: 10px 0;
|
||||
/* Adjust this value to increase/decrease the margin as needed */
|
||||
}
|
||||
@@ -1,37 +1,113 @@
|
||||
/* Rainbow Mode Styles */
|
||||
body {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
);
|
||||
color: #fff !important;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: white !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: white !important;
|
||||
}
|
||||
.jumbotron {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
);
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
.list-group-item {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
#support-section {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
}
|
||||
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(255, 255, 255, 0.046) !important;
|
||||
--scroll-bar-color: #4c4c4c !important;
|
||||
--scroll-bar-thumb: #d3d3d3 !important;
|
||||
--scroll-bar-thumb-hover: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
29
src/main/resources/static/css/rotate-pdf.css
Normal file
29
src/main/resources/static/css/rotate-pdf.css
Normal file
@@ -0,0 +1,29 @@
|
||||
#pdf-preview {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
max-width: calc(100% - 30px);
|
||||
max-height: calc(100% - 30px);
|
||||
box-shadow: 0 0 4px rgba(100, 100, 100, 0.25);
|
||||
transition: rotate 0.3s;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
.previewContainer {
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0;
|
||||
padding: 15px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
39
src/main/resources/static/css/sign.css
Normal file
39
src/main/resources/static/css/sign.css
Normal file
@@ -0,0 +1,39 @@
|
||||
select#font-select,
|
||||
select#font-select option {
|
||||
height: 60px; /* Adjust as needed */
|
||||
font-size: 30px; /* Adjust as needed */
|
||||
}
|
||||
|
||||
.drawing-pad-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#drawing-pad-canvas {
|
||||
background: rgba(125, 125, 125, 0.2);
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
#box-drag-container {
|
||||
position: relative;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.draggable-buttons-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.draggable-buttons-box > button {
|
||||
z-index: 10;
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
.draggable-canvas {
|
||||
border: 1px solid red;
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
}
|
||||
10
src/main/resources/static/css/split-pdf-by-sections.css
Normal file
10
src/main/resources/static/css/split-pdf-by-sections.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.pdf-visual-aid {
|
||||
width: 150px; /* Adjust as needed */
|
||||
height: 200px; /* Adjust as needed */
|
||||
border: 1px solid black; /* Represents the PDF page */
|
||||
position: relative;
|
||||
}
|
||||
.line {
|
||||
position: absolute;
|
||||
background-color: red; /* Line color */
|
||||
}
|
||||
41
src/main/resources/static/css/stamp.css
Normal file
41
src/main/resources/static/css/stamp.css
Normal file
@@ -0,0 +1,41 @@
|
||||
.a4container {
|
||||
position: relative;
|
||||
width: 50%;
|
||||
aspect-ratio: 0.707;
|
||||
border: 1px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.pageNumber {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1em;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
background-color: #ccc;
|
||||
width: 15%;
|
||||
height: 15%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.pageNumber:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#myForm {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.selectedPosition {
|
||||
background-color: #0a0;
|
||||
}
|
||||
|
||||
.selectedPosition.selectedHovered {
|
||||
background-color: #006600;
|
||||
}
|
||||
@@ -1,26 +1,24 @@
|
||||
|
||||
.tab-group {
|
||||
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
.tab-container.active {
|
||||
display: block;
|
||||
border: 1px solid rgba(var(--base-font-color), 0.25);
|
||||
padding: 15px;
|
||||
display: block;
|
||||
border: 1px solid rgba(var(--base-font-color), 0.25);
|
||||
padding: 15px;
|
||||
}
|
||||
.tab-buttons > button {
|
||||
margin-bottom: -1px;
|
||||
background: 0 0;
|
||||
border: 1px solid transparent;
|
||||
color: rgb(var(--base-font-color));
|
||||
margin-bottom: -1px;
|
||||
background: 0 0;
|
||||
border: 1px solid transparent;
|
||||
color: rgb(var(--base-font-color));
|
||||
|
||||
border-top-left-radius: 0.25rem;
|
||||
border-top-right-radius: 0.25rem;
|
||||
border-top-left-radius: 0.25rem;
|
||||
border-top-right-radius: 0.25rem;
|
||||
}
|
||||
.tab-buttons > button.active {
|
||||
background-color: rgb(var(--body-background-color));
|
||||
border-color: rgba(var(--base-font-color), 0.25) rgba(var(--base-font-color), 0.25) rgb(var(--body-background-color));
|
||||
}
|
||||
background-color: rgb(var(--body-background-color));
|
||||
border-color: rgba(var(--base-font-color), 0.25) rgba(var(--base-font-color), 0.25) rgb(var(--body-background-color));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var toggleCount = 0
|
||||
var lastToggleTime = Date.now()
|
||||
var toggleCount = 0;
|
||||
var lastToggleTime = Date.now();
|
||||
|
||||
var elements = {
|
||||
lightModeStyles: null,
|
||||
@@ -11,18 +11,18 @@ var elements = {
|
||||
navbar: null,
|
||||
navIcons: null,
|
||||
navDropdownMenus: null,
|
||||
}
|
||||
};
|
||||
|
||||
function getElements() {
|
||||
elements.lightModeStyles = document.getElementById("light-mode-styles")
|
||||
elements.darkModeStyles = document.getElementById("dark-mode-styles")
|
||||
elements.rainbowModeStyles = document.getElementById("rainbow-mode-styles")
|
||||
elements.darkModeIcon = document.getElementById("dark-mode-icon")
|
||||
elements.searchBar = document.getElementById("searchBar")
|
||||
elements.formControls = document.querySelectorAll(".form-control")
|
||||
elements.navbar = document.querySelectorAll("nav.navbar")
|
||||
elements.navIcons = document.querySelectorAll("nav .icon, .navbar-icon")
|
||||
elements.navDropdownMenus = document.querySelectorAll("nav .dropdown-menu")
|
||||
elements.lightModeStyles = document.getElementById("light-mode-styles");
|
||||
elements.darkModeStyles = document.getElementById("dark-mode-styles");
|
||||
elements.rainbowModeStyles = document.getElementById("rainbow-mode-styles");
|
||||
elements.darkModeIcon = document.getElementById("dark-mode-icon");
|
||||
elements.searchBar = document.getElementById("searchBar");
|
||||
elements.formControls = document.querySelectorAll(".form-control");
|
||||
elements.navbar = document.querySelectorAll("nav.navbar");
|
||||
elements.navIcons = document.querySelectorAll("nav .icon, .navbar-icon");
|
||||
elements.navDropdownMenus = document.querySelectorAll(".dropdown-menu");
|
||||
}
|
||||
function setMode(mode) {
|
||||
var event = new CustomEvent("modeChanged", { detail: mode });
|
||||
@@ -48,22 +48,22 @@ function setMode(mode) {
|
||||
elements.searchBar.classList.add("dark-mode-search");
|
||||
}
|
||||
if (elements && elements.formControls) {
|
||||
elements.formControls.forEach(input => input.classList.add("bg-dark", "text-white"));
|
||||
elements.formControls.forEach((input) => input.classList.add("bg-dark", "text-white"));
|
||||
}
|
||||
if (elements && elements.navbar) {
|
||||
elements.navbar.forEach(navElement => {
|
||||
elements.navbar.forEach((navElement) => {
|
||||
navElement.classList.remove("navbar-light", "bg-light");
|
||||
navElement.classList.add("navbar-dark", "bg-dark");
|
||||
});
|
||||
}
|
||||
if (elements && elements.navDropdownMenus) {
|
||||
elements.navDropdownMenus.forEach(menu => menu.classList.add("dropdown-menu-dark"));
|
||||
elements.navDropdownMenus.forEach((menu) => menu.classList.add("dropdown-menu-dark"));
|
||||
}
|
||||
if (elements && elements.navIcons) {
|
||||
elements.navIcons.forEach(icon => (icon.style.filter = "invert(1)"));
|
||||
elements.navIcons.forEach((icon) => (icon.style.filter = "invert(1)"));
|
||||
}
|
||||
var tables = document.querySelectorAll(".table");
|
||||
tables.forEach(table => {
|
||||
tables.forEach((table) => {
|
||||
table.classList.add("table-dark");
|
||||
});
|
||||
if (jumbotron) {
|
||||
@@ -78,22 +78,22 @@ function setMode(mode) {
|
||||
elements.searchBar.classList.remove("dark-mode-search");
|
||||
}
|
||||
if (elements && elements.formControls) {
|
||||
elements.formControls.forEach(input => input.classList.remove("bg-dark", "text-white"));
|
||||
elements.formControls.forEach((input) => input.classList.remove("bg-dark", "text-white"));
|
||||
}
|
||||
if (elements && elements.navbar) {
|
||||
elements.navbar.forEach(navElement => {
|
||||
elements.navbar.forEach((navElement) => {
|
||||
navElement.classList.remove("navbar-dark", "bg-dark");
|
||||
navElement.classList.add("navbar-light", "bg-light");
|
||||
});
|
||||
}
|
||||
if (elements && elements.navDropdownMenus) {
|
||||
elements.navDropdownMenus.forEach(menu => menu.classList.remove("dropdown-menu-dark"));
|
||||
elements.navDropdownMenus.forEach((menu) => menu.classList.remove("dropdown-menu-dark"));
|
||||
}
|
||||
if (elements && elements.navIcons) {
|
||||
elements.navIcons.forEach(icon => (icon.style.filter = "none"));
|
||||
elements.navIcons.forEach((icon) => (icon.style.filter = "none"));
|
||||
}
|
||||
var tables = document.querySelectorAll(".table-dark");
|
||||
tables.forEach(table => {
|
||||
tables.forEach((table) => {
|
||||
table.classList.remove("table-dark");
|
||||
});
|
||||
if (jumbotron) {
|
||||
@@ -108,43 +108,43 @@ function setMode(mode) {
|
||||
}
|
||||
|
||||
function toggleDarkMode() {
|
||||
var currentTime = Date.now()
|
||||
var currentTime = Date.now();
|
||||
if (currentTime - lastToggleTime < 1000) {
|
||||
toggleCount++
|
||||
toggleCount++;
|
||||
} else {
|
||||
toggleCount = 1
|
||||
toggleCount = 1;
|
||||
}
|
||||
lastToggleTime = currentTime
|
||||
lastToggleTime = currentTime;
|
||||
|
||||
if (toggleCount >= 18) {
|
||||
localStorage.setItem("dark-mode", "rainbow")
|
||||
setMode("rainbow")
|
||||
localStorage.setItem("dark-mode", "rainbow");
|
||||
setMode("rainbow");
|
||||
} else if (localStorage.getItem("dark-mode") == "on") {
|
||||
localStorage.setItem("dark-mode", "off")
|
||||
setMode("off")
|
||||
localStorage.setItem("dark-mode", "off");
|
||||
setMode("off");
|
||||
} else {
|
||||
localStorage.setItem("dark-mode", "on")
|
||||
setMode("on")
|
||||
localStorage.setItem("dark-mode", "on");
|
||||
setMode("on");
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
getElements()
|
||||
getElements();
|
||||
|
||||
var currentMode = localStorage.getItem("dark-mode")
|
||||
var currentMode = localStorage.getItem("dark-mode");
|
||||
if (currentMode === "on" || currentMode === "off" || currentMode === "rainbow") {
|
||||
setMode(currentMode)
|
||||
setMode(currentMode);
|
||||
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
setMode("on")
|
||||
setMode("on");
|
||||
} else {
|
||||
setMode("off")
|
||||
setMode("off");
|
||||
}
|
||||
|
||||
var darkModeToggle = document.getElementById("dark-mode-toggle");
|
||||
if (darkModeToggle !== null) {
|
||||
darkModeToggle.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
toggleDarkMode();
|
||||
});
|
||||
}
|
||||
})
|
||||
darkModeToggle.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
toggleDarkMode();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,242 +1,235 @@
|
||||
function showErrorBanner(message, stackTrace) {
|
||||
const errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "block"; // Display the banner
|
||||
document.querySelector("#errorContainer .alert-heading").textContent = "Error";
|
||||
document.querySelector("#errorContainer p").textContent = message;
|
||||
document.querySelector("#traceContent").textContent = stackTrace;
|
||||
const errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "block"; // Display the banner
|
||||
document.querySelector("#errorContainer .alert-heading").textContent = "Error";
|
||||
document.querySelector("#errorContainer p").textContent = message;
|
||||
document.querySelector("#traceContent").textContent = stackTrace;
|
||||
}
|
||||
let firstErrorOccurred = false;
|
||||
|
||||
$(document).ready(function() {
|
||||
$('form').submit(async function(event) {
|
||||
event.preventDefault();
|
||||
firstErrorOccurred = false;
|
||||
const url = this.action;
|
||||
const files = $('#fileInput-input')[0].files;
|
||||
const formData = new FormData(this);
|
||||
$(document).ready(function () {
|
||||
$("form").submit(async function (event) {
|
||||
event.preventDefault();
|
||||
firstErrorOccurred = false;
|
||||
const url = this.action;
|
||||
const files = $("#fileInput-input")[0].files;
|
||||
const formData = new FormData(this);
|
||||
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
}
|
||||
const override = $("#override").val() || "";
|
||||
const originalButtonText = $("#submitBtn").text();
|
||||
$("#submitBtn").text("Processing...");
|
||||
console.log(override);
|
||||
try {
|
||||
if (remoteCall === true) {
|
||||
if (override === "multi" || (!multiple && files.length > 1 && override !== "single")) {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
}
|
||||
const override = $('#override').val() || '';
|
||||
const originalButtonText = $('#submitBtn').text();
|
||||
$('#submitBtn').text('Processing...');
|
||||
console.log(override);
|
||||
try {
|
||||
if(remoteCall === true) {
|
||||
if (override === 'multi' || (!multiple && files.length > 1) && override !== 'single' ) {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
}
|
||||
}
|
||||
$('#submitBtn').text(originalButtonText);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
$('#submitBtn').text(originalButtonText);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
$("#submitBtn").text(originalButtonText);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
$("#submitBtn").text(originalButtonText);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
||||
try {
|
||||
const response = await fetch(url, { method: "POST", body: formData });
|
||||
const contentType = response.headers.get("content-type");
|
||||
|
||||
if (!response.ok) {
|
||||
if (contentType && contentType.includes("application/json")) {
|
||||
return handleJsonResponse(response);
|
||||
console.error("Throwing error banner, response was not okay");
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
async function handleSingleDownload(url, formData, isMulti = false , isZip = false) {
|
||||
try {
|
||||
const response = await fetch(url, { method: 'POST', body: formData });
|
||||
const contentType = response.headers.get('content-type');
|
||||
const contentDisposition = response.headers.get("Content-Disposition");
|
||||
let filename = getFilenameFromContentDisposition(contentDisposition);
|
||||
|
||||
if (!response.ok) {
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
return handleJsonResponse(response);
|
||||
console.error('Throwing error banner, response was not okay');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const contentDisposition = response.headers.get('Content-Disposition');
|
||||
let filename = getFilenameFromContentDisposition(contentDisposition);
|
||||
|
||||
const blob = await response.blob();
|
||||
if (contentType.includes('application/pdf') || contentType.includes('image/')) {
|
||||
return handleResponse(blob, filename, !isMulti, isZip);
|
||||
} else {
|
||||
return handleResponse(blob, filename, false, isZip);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in handleSingleDownload:', error);
|
||||
throw error; // Re-throw the error if you want it to be handled higher up.
|
||||
}
|
||||
const blob = await response.blob();
|
||||
if (contentType.includes("application/pdf") || contentType.includes("image/")) {
|
||||
return handleResponse(blob, filename, !isMulti, isZip);
|
||||
} else {
|
||||
return handleResponse(blob, filename, false, isZip);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in handleSingleDownload:", error);
|
||||
throw error; // Re-throw the error if you want it to be handled higher up.
|
||||
}
|
||||
}
|
||||
|
||||
function getFilenameFromContentDisposition(contentDisposition) {
|
||||
let filename;
|
||||
let filename;
|
||||
|
||||
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
||||
} else {
|
||||
// If the Content-Disposition header is not present or does not contain the filename, use a default filename
|
||||
filename = 'download';
|
||||
}
|
||||
if (contentDisposition && contentDisposition.indexOf("attachment") !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split("filename=")[1].replace(/"/g, "")).trim();
|
||||
} else {
|
||||
// If the Content-Disposition header is not present or does not contain the filename, use a default filename
|
||||
filename = "download";
|
||||
}
|
||||
|
||||
return filename;
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handleJsonResponse(response) {
|
||||
const json = await response.json();
|
||||
const errorMessage = JSON.stringify(json, null, 2);
|
||||
if (errorMessage.toLowerCase().includes('the password is incorrect') || errorMessage.toLowerCase().includes('Password is not provided') || errorMessage.toLowerCase().includes('PDF contains an encryption dictionary')) {
|
||||
if (!firstErrorOccurred) {
|
||||
firstErrorOccurred = true;
|
||||
alert(pdfPasswordPrompt);
|
||||
}
|
||||
} else {
|
||||
showErrorBanner(json.error + ':' + json.message, json.trace);
|
||||
}
|
||||
const json = await response.json();
|
||||
const errorMessage = JSON.stringify(json, null, 2);
|
||||
if (
|
||||
errorMessage.toLowerCase().includes("the password is incorrect") ||
|
||||
errorMessage.toLowerCase().includes("Password is not provided") ||
|
||||
errorMessage.toLowerCase().includes("PDF contains an encryption dictionary")
|
||||
) {
|
||||
if (!firstErrorOccurred) {
|
||||
firstErrorOccurred = true;
|
||||
alert(pdfPasswordPrompt);
|
||||
}
|
||||
} else {
|
||||
showErrorBanner(json.error + ":" + json.message, json.trace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function handleResponse(blob, filename, considerViewOptions = false, isZip = false) {
|
||||
if (!blob) return;
|
||||
const downloadOption = localStorage.getItem('downloadOption');
|
||||
if (considerViewOptions) {
|
||||
if (downloadOption === 'sameWindow') {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.location.href = url;
|
||||
return;
|
||||
} else if (downloadOption === 'newWindow') {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, '_blank');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!isZip){
|
||||
downloadFile(blob, filename);
|
||||
}
|
||||
return { filename, blob };
|
||||
if (!blob) return;
|
||||
const downloadOption = localStorage.getItem("downloadOption");
|
||||
if (considerViewOptions) {
|
||||
if (downloadOption === "sameWindow") {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.location.href = url;
|
||||
return;
|
||||
} else if (downloadOption === "newWindow") {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, "_blank");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!isZip) {
|
||||
downloadFile(blob, filename);
|
||||
}
|
||||
return { filename, blob };
|
||||
}
|
||||
|
||||
function handleDownloadError(error) {
|
||||
const errorMessage = error.message;
|
||||
showErrorBanner(errorMessage);
|
||||
const errorMessage = error.message;
|
||||
showErrorBanner(errorMessage);
|
||||
}
|
||||
|
||||
let urls = []; // An array to hold all the URLs
|
||||
|
||||
function downloadFile(blob, filename) {
|
||||
if (!(blob instanceof Blob)) {
|
||||
console.error('Invalid blob passed to downloadFile function');
|
||||
return;
|
||||
}
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
urls.push(url); // Store the URL so it doesn't get garbage collected too soon
|
||||
if (!(blob instanceof Blob)) {
|
||||
console.error("Invalid blob passed to downloadFile function");
|
||||
return;
|
||||
}
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
urls.push(url); // Store the URL so it doesn't get garbage collected too soon
|
||||
|
||||
return { filename, blob };
|
||||
return { filename, blob };
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function submitMultiPdfForm(url, files) {
|
||||
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
let jszip = null;
|
||||
// Show the progress bar
|
||||
$('#progressBarContainer').show();
|
||||
// Initialize the progress bar
|
||||
const zipThreshold = parseInt(localStorage.getItem("zipThreshold"), 10) || 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
let jszip = null;
|
||||
// Show the progress bar
|
||||
$("#progressBarContainer").show();
|
||||
// Initialize the progress bar
|
||||
|
||||
let progressBar = $('#progressBar');
|
||||
progressBar.css('width', '0%');
|
||||
progressBar.attr('aria-valuenow', 0);
|
||||
progressBar.attr('aria-valuemax', files.length);
|
||||
let progressBar = $("#progressBar");
|
||||
progressBar.css("width", "0%");
|
||||
progressBar.attr("aria-valuenow", 0);
|
||||
progressBar.attr("aria-valuemax", files.length);
|
||||
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
|
||||
// Get the form with the method attribute set to POST
|
||||
let postForm = document.querySelector('form[method="POST"]');
|
||||
|
||||
// Get the form with the method attribute set to POST
|
||||
let postForm = document.querySelector('form[method="POST"]');
|
||||
|
||||
// Get existing form data
|
||||
let formData;
|
||||
if (postForm) {
|
||||
formData = new FormData($(postForm)[0]); // Convert the form to a jQuery object and get the raw DOM element
|
||||
} else {
|
||||
console.log("No form with POST method found.");
|
||||
}
|
||||
//Remove file to reuse parameters for other runs
|
||||
formData.delete('fileInput');
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
// Get existing form data
|
||||
let formData;
|
||||
if (postForm) {
|
||||
formData = new FormData($(postForm)[0]); // Convert the form to a jQuery object and get the raw DOM element
|
||||
} else {
|
||||
console.log("No form with POST method found.");
|
||||
}
|
||||
//Remove file to reuse parameters for other runs
|
||||
formData.delete("fileInput");
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
const CONCURRENCY_LIMIT = 8;
|
||||
const chunks = [];
|
||||
for (let i = 0; i < Array.from(files).length; i += CONCURRENCY_LIMIT) {
|
||||
chunks.push(Array.from(files).slice(i, i + CONCURRENCY_LIMIT));
|
||||
}
|
||||
}
|
||||
const CONCURRENCY_LIMIT = 8;
|
||||
const chunks = [];
|
||||
for (let i = 0; i < Array.from(files).length; i += CONCURRENCY_LIMIT) {
|
||||
chunks.push(Array.from(files).slice(i, i + CONCURRENCY_LIMIT));
|
||||
}
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const promises = chunk.map(async file => {
|
||||
let fileFormData = new FormData();
|
||||
fileFormData.append('fileInput', file);
|
||||
console.log(fileFormData);
|
||||
// Add other form data
|
||||
for (let pair of formData.entries()) {
|
||||
fileFormData.append(pair[0], pair[1]);
|
||||
console.log(pair[0]+ ', ' + pair[1]);
|
||||
}
|
||||
for (const chunk of chunks) {
|
||||
const promises = chunk.map(async (file) => {
|
||||
let fileFormData = new FormData();
|
||||
fileFormData.append("fileInput", file);
|
||||
console.log(fileFormData);
|
||||
// Add other form data
|
||||
for (let pair of formData.entries()) {
|
||||
fileFormData.append(pair[0], pair[1]);
|
||||
console.log(pair[0] + ", " + pair[1]);
|
||||
}
|
||||
|
||||
try {
|
||||
const downloadDetails = await handleSingleDownload(url, fileFormData, true, zipFiles);
|
||||
console.log(downloadDetails);
|
||||
if (zipFiles) {
|
||||
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
||||
} else {
|
||||
//downloadFile(downloadDetails.blob, downloadDetails.filename);
|
||||
}
|
||||
updateProgressBar(progressBar, Array.from(files).length);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
await Promise.all(promises);
|
||||
try {
|
||||
const downloadDetails = await handleSingleDownload(url, fileFormData, true, zipFiles);
|
||||
console.log(downloadDetails);
|
||||
if (zipFiles) {
|
||||
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
||||
} else {
|
||||
//downloadFile(downloadDetails.blob, downloadDetails.filename);
|
||||
}
|
||||
updateProgressBar(progressBar, Array.from(files).length);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (zipFiles) {
|
||||
try {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
downloadFile(content, "files.zip");
|
||||
} catch (error) {
|
||||
console.error('Error generating ZIP file: ' + error);
|
||||
}
|
||||
}
|
||||
progressBar.css('width', '100%');
|
||||
progressBar.attr('aria-valuenow', Array.from(files).length);
|
||||
if (zipFiles) {
|
||||
try {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
downloadFile(content, "files.zip");
|
||||
} catch (error) {
|
||||
console.error("Error generating ZIP file: " + error);
|
||||
}
|
||||
}
|
||||
progressBar.css("width", "100%");
|
||||
progressBar.attr("aria-valuenow", Array.from(files).length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateProgressBar(progressBar, files) {
|
||||
let progress = ((progressBar.attr('aria-valuenow') / files.length) * 100) + (100 / files.length);
|
||||
progressBar.css('width', progress + '%');
|
||||
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
|
||||
let progress = (progressBar.attr("aria-valuenow") / files.length) * 100 + 100 / files.length;
|
||||
progressBar.css("width", progress + "%");
|
||||
progressBar.attr("aria-valuenow", parseInt(progressBar.attr("aria-valuenow")) + 1);
|
||||
}
|
||||
window.addEventListener('unload', () => {
|
||||
for (const url of urls) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
window.addEventListener("unload", () => {
|
||||
for (const url of urls) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,282 +1,287 @@
|
||||
const DraggableUtils = {
|
||||
boxDragContainer: document.getElementById("box-drag-container"),
|
||||
pdfCanvas: document.getElementById("pdf-canvas"),
|
||||
nextId: 0,
|
||||
pdfDoc: null,
|
||||
pageIndex: 0,
|
||||
documentsMap: new Map(),
|
||||
|
||||
boxDragContainer: document.getElementById('box-drag-container'),
|
||||
pdfCanvas: document.getElementById('pdf-canvas'),
|
||||
nextId: 0,
|
||||
pdfDoc: null,
|
||||
pageIndex: 0,
|
||||
documentsMap: new Map(),
|
||||
init() {
|
||||
interact(".draggable-canvas")
|
||||
.draggable({
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
const target = event.target;
|
||||
const x = (parseFloat(target.getAttribute("data-bs-x")) || 0) + event.dx;
|
||||
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0) + event.dy;
|
||||
|
||||
init() {
|
||||
interact('.draggable-canvas')
|
||||
.draggable({
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
const target = event.target;
|
||||
const x = (parseFloat(target.getAttribute('data-bs-x')) || 0) + event.dx;
|
||||
const y = (parseFloat(target.getAttribute('data-bs-y')) || 0) + event.dy;
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.setAttribute('data-bs-x', x);
|
||||
target.setAttribute('data-bs-y', y);
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
})
|
||||
.resizable({
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target
|
||||
var x = (parseFloat(target.getAttribute('data-bs-x')) || 0)
|
||||
var y = (parseFloat(target.getAttribute('data-bs-y')) || 0)
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
})
|
||||
.resizable({
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target;
|
||||
var x = parseFloat(target.getAttribute("data-bs-x")) || 0;
|
||||
var y = parseFloat(target.getAttribute("data-bs-y")) || 0;
|
||||
|
||||
// check if control key is pressed
|
||||
if (event.ctrlKey) {
|
||||
const aspectRatio = target.offsetWidth / target.offsetHeight;
|
||||
// preserve aspect ratio
|
||||
let width = event.rect.width;
|
||||
let height = event.rect.height;
|
||||
const aspectRatio = target.offsetWidth / target.offsetHeight;
|
||||
// preserve aspect ratio
|
||||
let width = event.rect.width;
|
||||
let height = event.rect.height;
|
||||
|
||||
if (Math.abs(event.deltaRect.width) >= Math.abs(event.deltaRect.height)) {
|
||||
height = width / aspectRatio;
|
||||
} else {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
if (Math.abs(event.deltaRect.width) >= Math.abs(event.deltaRect.height)) {
|
||||
height = width / aspectRatio;
|
||||
} else {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
|
||||
event.rect.width = width;
|
||||
event.rect.height = height;
|
||||
event.rect.width = width;
|
||||
event.rect.height = height;
|
||||
}
|
||||
|
||||
target.style.width = event.rect.width + 'px'
|
||||
target.style.height = event.rect.height + 'px'
|
||||
target.style.width = event.rect.width + "px";
|
||||
target.style.height = event.rect.height + "px";
|
||||
|
||||
// translate when resizing from top or left edges
|
||||
x += event.deltaRect.left
|
||||
y += event.deltaRect.top
|
||||
x += event.deltaRect.left;
|
||||
y += event.deltaRect.top;
|
||||
|
||||
target.style.transform = 'translate(' + x + 'px,' + y + 'px)'
|
||||
target.style.transform = "translate(" + x + "px," + y + "px)";
|
||||
|
||||
target.setAttribute('data-bs-x', x)
|
||||
target.setAttribute('data-bs-y', y)
|
||||
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
target.textContent = Math.round(event.rect.width) + "\u00D7" + Math.round(event.rect.height);
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
modifiers: [
|
||||
interact.modifiers.restrictSize({
|
||||
min: { width: 5, height: 5 },
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
});
|
||||
},
|
||||
onInteraction(target) {
|
||||
this.boxDragContainer.appendChild(target);
|
||||
},
|
||||
modifiers: [
|
||||
interact.modifiers.restrictSize({
|
||||
min: { width: 5, height: 5 },
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
});
|
||||
},
|
||||
onInteraction(target) {
|
||||
this.boxDragContainer.appendChild(target);
|
||||
},
|
||||
|
||||
createDraggableCanvas() {
|
||||
const createdCanvas = document.createElement('canvas');
|
||||
createdCanvas.id = `draggable-canvas-${this.nextId++}`;
|
||||
createdCanvas.classList.add("draggable-canvas");
|
||||
createDraggableCanvas() {
|
||||
const createdCanvas = document.createElement("canvas");
|
||||
createdCanvas.id = `draggable-canvas-${this.nextId++}`;
|
||||
createdCanvas.classList.add("draggable-canvas");
|
||||
|
||||
const x = 0;
|
||||
const y = 20;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
createdCanvas.setAttribute('data-bs-x', x);
|
||||
createdCanvas.setAttribute('data-bs-y', y);
|
||||
const x = 0;
|
||||
const y = 20;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
createdCanvas.setAttribute("data-bs-x", x);
|
||||
createdCanvas.setAttribute("data-bs-y", y);
|
||||
|
||||
createdCanvas.onclick = e => this.onInteraction(e.target);
|
||||
createdCanvas.onclick = (e) => this.onInteraction(e.target);
|
||||
|
||||
this.boxDragContainer.appendChild(createdCanvas);
|
||||
return createdCanvas;
|
||||
},
|
||||
createDraggableCanvasFromUrl(dataUrl) {
|
||||
return new Promise((resolve) => {
|
||||
var myImage = new Image();
|
||||
myImage.src = dataUrl;
|
||||
myImage.onload = () => {
|
||||
var createdCanvas = this.createDraggableCanvas();
|
||||
this.boxDragContainer.appendChild(createdCanvas);
|
||||
return createdCanvas;
|
||||
},
|
||||
createDraggableCanvasFromUrl(dataUrl) {
|
||||
return new Promise((resolve) => {
|
||||
var myImage = new Image();
|
||||
myImage.src = dataUrl;
|
||||
myImage.onload = () => {
|
||||
var createdCanvas = this.createDraggableCanvas();
|
||||
|
||||
createdCanvas.width = myImage.width;
|
||||
createdCanvas.height = myImage.height;
|
||||
createdCanvas.width = myImage.width;
|
||||
createdCanvas.height = myImage.height;
|
||||
|
||||
const imgAspect = myImage.width / myImage.height;
|
||||
const pdfAspect = this.boxDragContainer.offsetWidth / this.boxDragContainer.offsetHeight;
|
||||
const imgAspect = myImage.width / myImage.height;
|
||||
const pdfAspect = this.boxDragContainer.offsetWidth / this.boxDragContainer.offsetHeight;
|
||||
|
||||
var scaleMultiplier;
|
||||
if (imgAspect > pdfAspect) {
|
||||
scaleMultiplier = this.boxDragContainer.offsetWidth / myImage.width;
|
||||
} else {
|
||||
scaleMultiplier = this.boxDragContainer.offsetHeight / myImage.height;
|
||||
}
|
||||
|
||||
var newWidth = createdCanvas.width;
|
||||
var newHeight = createdCanvas.height;
|
||||
if (scaleMultiplier < 1) {
|
||||
newWidth = newWidth * scaleMultiplier;
|
||||
newHeight = newHeight * scaleMultiplier;
|
||||
}
|
||||
|
||||
createdCanvas.style.width = newWidth+"px";
|
||||
createdCanvas.style.height = newHeight+"px";
|
||||
|
||||
var myContext = createdCanvas.getContext("2d");
|
||||
myContext.drawImage(myImage,0,0);
|
||||
resolve(createdCanvas);
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteAllDraggableCanvases() {
|
||||
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach(el => el.remove());
|
||||
},
|
||||
deleteDraggableCanvas(element) {
|
||||
if (element) {
|
||||
element.remove();
|
||||
}
|
||||
},
|
||||
getLastInteracted() {
|
||||
return this.boxDragContainer.querySelector(".draggable-canvas:last-of-type");
|
||||
},
|
||||
|
||||
storePageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
if (!pagesMap) {
|
||||
pagesMap = {};
|
||||
}
|
||||
|
||||
const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")];
|
||||
const draggablesData = elements.map(el => {return{element:el, offsetWidth:el.offsetWidth, offsetHeight:el.offsetHeight}});
|
||||
elements.forEach(el => this.boxDragContainer.removeChild(el));
|
||||
|
||||
pagesMap[this.pageIndex] = draggablesData;
|
||||
pagesMap[this.pageIndex+"-offsetWidth"] = this.pdfCanvas.offsetWidth;
|
||||
pagesMap[this.pageIndex+"-offsetHeight"] = this.pdfCanvas.offsetHeight;
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
loadPageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
this.deleteAllDraggableCanvases();
|
||||
if (!pagesMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
const draggablesData = pagesMap[this.pageIndex];
|
||||
if (draggablesData) {
|
||||
draggablesData.forEach(draggableData => this.boxDragContainer.appendChild(draggableData.element));
|
||||
}
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
|
||||
async renderPage(pdfDocument, pageIdx) {
|
||||
this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc;
|
||||
this.pageIndex = pageIdx;
|
||||
|
||||
// persist
|
||||
const page = await this.pdfDoc.getPage(this.pageIndex+1);
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
this.pdfCanvas.width = page.view[3];
|
||||
this.pdfCanvas.height = page.view[2];
|
||||
var scaleMultiplier;
|
||||
if (imgAspect > pdfAspect) {
|
||||
scaleMultiplier = this.boxDragContainer.offsetWidth / myImage.width;
|
||||
} else {
|
||||
this.pdfCanvas.width = page.view[2];
|
||||
this.pdfCanvas.height = page.view[3];
|
||||
scaleMultiplier = this.boxDragContainer.offsetHeight / myImage.height;
|
||||
}
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: this.pdfCanvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 })
|
||||
var newWidth = createdCanvas.width;
|
||||
var newHeight = createdCanvas.height;
|
||||
if (scaleMultiplier < 1) {
|
||||
newWidth = newWidth * scaleMultiplier;
|
||||
newHeight = newHeight * scaleMultiplier;
|
||||
}
|
||||
|
||||
createdCanvas.style.width = newWidth + "px";
|
||||
createdCanvas.style.height = newHeight + "px";
|
||||
|
||||
var myContext = createdCanvas.getContext("2d");
|
||||
myContext.drawImage(myImage, 0, 0);
|
||||
resolve(createdCanvas);
|
||||
};
|
||||
});
|
||||
},
|
||||
deleteAllDraggableCanvases() {
|
||||
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach((el) => el.remove());
|
||||
},
|
||||
deleteDraggableCanvas(element) {
|
||||
if (element) {
|
||||
element.remove();
|
||||
}
|
||||
},
|
||||
getLastInteracted() {
|
||||
return this.boxDragContainer.querySelector(".draggable-canvas:last-of-type");
|
||||
},
|
||||
|
||||
storePageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
if (!pagesMap) {
|
||||
pagesMap = {};
|
||||
}
|
||||
|
||||
const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")];
|
||||
const draggablesData = elements.map((el) => {
|
||||
return {
|
||||
element: el,
|
||||
offsetWidth: el.offsetWidth,
|
||||
offsetHeight: el.offsetHeight,
|
||||
};
|
||||
});
|
||||
elements.forEach((el) => this.boxDragContainer.removeChild(el));
|
||||
|
||||
pagesMap[this.pageIndex] = draggablesData;
|
||||
pagesMap[this.pageIndex + "-offsetWidth"] = this.pdfCanvas.offsetWidth;
|
||||
pagesMap[this.pageIndex + "-offsetHeight"] = this.pdfCanvas.offsetHeight;
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
loadPageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
this.deleteAllDraggableCanvases();
|
||||
if (!pagesMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
const draggablesData = pagesMap[this.pageIndex];
|
||||
if (draggablesData) {
|
||||
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
||||
}
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
|
||||
async renderPage(pdfDocument, pageIdx) {
|
||||
this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc;
|
||||
this.pageIndex = pageIdx;
|
||||
|
||||
// persist
|
||||
const page = await this.pdfDoc.getPage(this.pageIndex + 1);
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
this.pdfCanvas.width = page.view[3];
|
||||
this.pdfCanvas.height = page.view[2];
|
||||
} else {
|
||||
this.pdfCanvas.width = page.view[2];
|
||||
this.pdfCanvas.height = page.view[3];
|
||||
}
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: this.pdfCanvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 }),
|
||||
};
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
//return pdfCanvas.toDataURL();
|
||||
},
|
||||
async incrementPage() {
|
||||
if (this.pageIndex < this.pdfDoc.numPages - 1) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex + 1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
async decrementPage() {
|
||||
if (this.pageIndex > 0) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex - 1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
|
||||
parseTransform(element) {},
|
||||
async getOverlayedPdfDocument() {
|
||||
const pdfBytes = await this.pdfDoc.getData();
|
||||
const pdfDocModified = await PDFLib.PDFDocument.load(pdfBytes, {
|
||||
ignoreEncryption: true,
|
||||
});
|
||||
this.storePageContents();
|
||||
|
||||
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
for (let pageIdx in pagesMap) {
|
||||
if (pageIdx.includes("offset")) {
|
||||
continue;
|
||||
}
|
||||
console.log(typeof pageIdx);
|
||||
|
||||
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
||||
const draggablesData = pagesMap[pageIdx];
|
||||
const offsetWidth = pagesMap[pageIdx + "-offsetWidth"];
|
||||
const offsetHeight = pagesMap[pageIdx + "-offsetHeight"];
|
||||
|
||||
for (const draggableData of draggablesData) {
|
||||
// embed the draggable canvas
|
||||
const draggableElement = draggableData.element;
|
||||
const response = await fetch(draggableElement.toDataURL());
|
||||
const draggableImgBytes = await response.arrayBuffer();
|
||||
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
|
||||
|
||||
// calculate the position in the pdf document
|
||||
const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, "");
|
||||
const transformComponents = tansform.split(",");
|
||||
const draggablePositionPixels = {
|
||||
x: parseFloat(transformComponents[0]),
|
||||
y: parseFloat(transformComponents[1]),
|
||||
width: draggableData.offsetWidth,
|
||||
height: draggableData.offsetHeight,
|
||||
};
|
||||
const draggablePositionRelative = {
|
||||
x: draggablePositionPixels.x / offsetWidth,
|
||||
y: draggablePositionPixels.y / offsetHeight,
|
||||
width: draggablePositionPixels.width / offsetWidth,
|
||||
height: draggablePositionPixels.height / offsetHeight,
|
||||
};
|
||||
const draggablePositionPdf = {
|
||||
x: draggablePositionRelative.x * page.getWidth(),
|
||||
y: draggablePositionRelative.y * page.getHeight(),
|
||||
width: draggablePositionRelative.width * page.getWidth(),
|
||||
height: draggablePositionRelative.height * page.getHeight(),
|
||||
};
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
//return pdfCanvas.toDataURL();
|
||||
},
|
||||
async incrementPage() {
|
||||
if (this.pageIndex < this.pdfDoc.numPages-1) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex+1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
async decrementPage() {
|
||||
if (this.pageIndex > 0) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex-1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
// draw the image
|
||||
page.drawImage(pdfImageObject, {
|
||||
x: draggablePositionPdf.x,
|
||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||
width: draggablePositionPdf.width,
|
||||
height: draggablePositionPdf.height,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
parseTransform(element) {
|
||||
|
||||
},
|
||||
async getOverlayedPdfDocument() {
|
||||
const pdfBytes = await this.pdfDoc.getData();
|
||||
const pdfDocModified = await PDFLib.PDFDocument.load(pdfBytes, { ignoreEncryption: true });
|
||||
this.storePageContents();
|
||||
|
||||
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
for (let pageIdx in pagesMap) {
|
||||
if (pageIdx.includes("offset")) {
|
||||
continue;
|
||||
}
|
||||
console.log(typeof pageIdx);
|
||||
|
||||
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
||||
const draggablesData = pagesMap[pageIdx];
|
||||
const offsetWidth = pagesMap[pageIdx+"-offsetWidth"];
|
||||
const offsetHeight = pagesMap[pageIdx+"-offsetHeight"];
|
||||
|
||||
for (const draggableData of draggablesData) {
|
||||
// embed the draggable canvas
|
||||
const draggableElement = draggableData.element;
|
||||
const response = await fetch(draggableElement.toDataURL());
|
||||
const draggableImgBytes = await response.arrayBuffer();
|
||||
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
|
||||
|
||||
// calculate the position in the pdf document
|
||||
const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, '');
|
||||
const transformComponents = tansform.split(",");
|
||||
const draggablePositionPixels = {
|
||||
x: parseFloat(transformComponents[0]),
|
||||
y: parseFloat(transformComponents[1]),
|
||||
width: draggableData.offsetWidth,
|
||||
height: draggableData.offsetHeight,
|
||||
};
|
||||
const draggablePositionRelative = {
|
||||
x: draggablePositionPixels.x / offsetWidth,
|
||||
y: draggablePositionPixels.y / offsetHeight,
|
||||
width: draggablePositionPixels.width / offsetWidth,
|
||||
height: draggablePositionPixels.height / offsetHeight,
|
||||
}
|
||||
const draggablePositionPdf = {
|
||||
x: draggablePositionRelative.x * page.getWidth(),
|
||||
y: draggablePositionRelative.y * page.getHeight(),
|
||||
width: draggablePositionRelative.width * page.getWidth(),
|
||||
height: draggablePositionRelative.height * page.getHeight(),
|
||||
}
|
||||
|
||||
// draw the image
|
||||
page.drawImage(pdfImageObject, {
|
||||
x: draggablePositionPdf.x,
|
||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||
width: draggablePositionPdf.width,
|
||||
height: draggablePositionPdf.height,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.loadPageContents();
|
||||
return pdfDocModified;
|
||||
},
|
||||
}
|
||||
this.loadPageContents();
|
||||
return pdfDocModified;
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
DraggableUtils.init();
|
||||
DraggableUtils.init();
|
||||
});
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
var traceVisible = false;
|
||||
|
||||
function toggletrace() {
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (!traceVisible) {
|
||||
traceDiv.style.maxHeight = "500px";
|
||||
traceVisible = true;
|
||||
} else {
|
||||
traceDiv.style.maxHeight = "0px";
|
||||
traceVisible = false;
|
||||
}
|
||||
adjustContainerHeight();
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (!traceVisible) {
|
||||
traceDiv.style.maxHeight = "500px";
|
||||
traceVisible = true;
|
||||
} else {
|
||||
traceDiv.style.maxHeight = "0px";
|
||||
traceVisible = false;
|
||||
}
|
||||
adjustContainerHeight();
|
||||
}
|
||||
|
||||
function copytrace() {
|
||||
var flip = false
|
||||
if (!traceVisible) {
|
||||
toggletrace()
|
||||
flip = true
|
||||
}
|
||||
var traceContent = document.getElementById("traceContent");
|
||||
var range = document.createRange();
|
||||
range.selectNode(traceContent);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand("copy");
|
||||
window.getSelection().removeAllRanges();
|
||||
if (flip) {
|
||||
toggletrace()
|
||||
}
|
||||
var flip = false;
|
||||
if (!traceVisible) {
|
||||
toggletrace();
|
||||
flip = true;
|
||||
}
|
||||
var traceContent = document.getElementById("traceContent");
|
||||
var range = document.createRange();
|
||||
range.selectNode(traceContent);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand("copy");
|
||||
window.getSelection().removeAllRanges();
|
||||
if (flip) {
|
||||
toggletrace();
|
||||
}
|
||||
}
|
||||
|
||||
function dismissError() {
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "none";
|
||||
errorContainer.style.height = "0";
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "none";
|
||||
errorContainer.style.height = "0";
|
||||
}
|
||||
|
||||
function adjustContainerHeight() {
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (traceVisible) {
|
||||
errorContainer.style.height = errorContainer.scrollHeight - traceDiv.scrollHeight + traceDiv.offsetHeight + "px";
|
||||
} else {
|
||||
errorContainer.style.height = "auto";
|
||||
}
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (traceVisible) {
|
||||
errorContainer.style.height = errorContainer.scrollHeight - traceDiv.scrollHeight + traceDiv.offsetHeight + "px";
|
||||
} else {
|
||||
errorContainer.style.height = "auto";
|
||||
}
|
||||
}
|
||||
function showHelp() {
|
||||
$('#helpModal').modal('show');
|
||||
}
|
||||
$("#helpModal").modal("show");
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
function updateFavoritesDropdown() {
|
||||
var dropdown = document.querySelector('#favoritesDropdown');
|
||||
var dropdown = document.querySelector("#favoritesDropdown");
|
||||
|
||||
// Check if dropdown exists
|
||||
if (!dropdown) {
|
||||
console.error('Dropdown element with ID "favoritesDropdown" not found!');
|
||||
return; // Exit the function
|
||||
// Check if dropdown exists
|
||||
if (!dropdown) {
|
||||
console.error('Dropdown element with ID "favoritesDropdown" not found!');
|
||||
return; // Exit the function
|
||||
}
|
||||
dropdown.innerHTML = ""; // Clear the current favorites
|
||||
|
||||
var hasFavorites = false;
|
||||
|
||||
for (var i = 0; i < localStorage.length; i++) {
|
||||
var key = localStorage.key(i);
|
||||
if (localStorage.getItem(key) === "favorite") {
|
||||
// Find the corresponding navbar entry
|
||||
var navbarEntry = document.querySelector(`a[href='${key}']`);
|
||||
if (navbarEntry) {
|
||||
// Create a new dropdown entry
|
||||
var dropdownItem = document.createElement("a");
|
||||
dropdownItem.className = "dropdown-item";
|
||||
dropdownItem.href = navbarEntry.href;
|
||||
dropdownItem.innerHTML = navbarEntry.innerHTML;
|
||||
dropdown.appendChild(dropdownItem);
|
||||
hasFavorites = true;
|
||||
} else {
|
||||
console.warn(`Navbar entry not found for key: ${key}`);
|
||||
}
|
||||
}
|
||||
dropdown.innerHTML = ''; // Clear the current favorites
|
||||
}
|
||||
|
||||
var hasFavorites = false;
|
||||
|
||||
for (var i = 0; i < localStorage.length; i++) {
|
||||
var key = localStorage.key(i);
|
||||
if (localStorage.getItem(key) === 'favorite') {
|
||||
// Find the corresponding navbar entry
|
||||
var navbarEntry = document.querySelector(`a[href='${key}']`);
|
||||
if (navbarEntry) {
|
||||
// Create a new dropdown entry
|
||||
var dropdownItem = document.createElement('a');
|
||||
dropdownItem.className = 'dropdown-item';
|
||||
dropdownItem.href = navbarEntry.href;
|
||||
dropdownItem.innerHTML = navbarEntry.innerHTML;
|
||||
dropdown.appendChild(dropdownItem);
|
||||
hasFavorites = true;
|
||||
} else {
|
||||
console.warn(`Navbar entry not found for key: ${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show or hide the default item based on whether there are any favorites
|
||||
if (!hasFavorites) {
|
||||
var defaultItem = document.createElement('a');
|
||||
defaultItem.className = 'dropdown-item';
|
||||
defaultItem.textContent = noFavourites;
|
||||
dropdown.appendChild(defaultItem);
|
||||
}
|
||||
// Show or hide the default item based on whether there are any favorites
|
||||
if (!hasFavorites) {
|
||||
var defaultItem = document.createElement("a");
|
||||
defaultItem.className = "dropdown-item";
|
||||
defaultItem.textContent = noFavourites;
|
||||
dropdown.appendChild(defaultItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the DOM content has been fully loaded before calling the function
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('DOMContentLoaded event fired');
|
||||
updateFavoritesDropdown();
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
console.log("DOMContentLoaded event fired");
|
||||
updateFavoritesDropdown();
|
||||
});
|
||||
|
||||
@@ -1,104 +1,107 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.custom-file-chooser').forEach(setupFileInput);
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.querySelectorAll(".custom-file-chooser").forEach(setupFileInput);
|
||||
});
|
||||
|
||||
function setupFileInput(chooser) {
|
||||
const elementId = chooser.getAttribute('data-bs-element-id');
|
||||
const filesSelected = chooser.getAttribute('data-bs-files-selected');
|
||||
const pdfPrompt = chooser.getAttribute('data-bs-pdf-prompt');
|
||||
const elementId = chooser.getAttribute("data-bs-element-id");
|
||||
const filesSelected = chooser.getAttribute("data-bs-files-selected");
|
||||
const pdfPrompt = chooser.getAttribute("data-bs-pdf-prompt");
|
||||
|
||||
let allFiles = [];
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
let allFiles = [];
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
|
||||
const dragenterListener = function() {
|
||||
dragCounter++;
|
||||
if (!overlay) {
|
||||
overlay = document.createElement('div');
|
||||
overlay.style.position = 'fixed';
|
||||
overlay.style.top = 0;
|
||||
overlay.style.left = 0;
|
||||
overlay.style.width = '100%';
|
||||
overlay.style.height = '100%';
|
||||
overlay.style.background = 'rgba(0, 0, 0, 0.5)';
|
||||
overlay.style.color = '#fff';
|
||||
overlay.style.zIndex = '1000';
|
||||
overlay.style.display = 'flex';
|
||||
overlay.style.alignItems = 'center';
|
||||
overlay.style.justifyContent = 'center';
|
||||
overlay.style.pointerEvents = 'none';
|
||||
overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
|
||||
document.getElementById('content-wrap').appendChild(overlay);
|
||||
}
|
||||
};
|
||||
const dragenterListener = function () {
|
||||
dragCounter++;
|
||||
if (!overlay) {
|
||||
overlay = document.createElement("div");
|
||||
overlay.style.position = "fixed";
|
||||
overlay.style.top = 0;
|
||||
overlay.style.left = 0;
|
||||
overlay.style.width = "100%";
|
||||
overlay.style.height = "100%";
|
||||
overlay.style.background = "rgba(0, 0, 0, 0.5)";
|
||||
overlay.style.color = "#fff";
|
||||
overlay.style.zIndex = "1000";
|
||||
overlay.style.display = "flex";
|
||||
overlay.style.alignItems = "center";
|
||||
overlay.style.justifyContent = "center";
|
||||
overlay.style.pointerEvents = "none";
|
||||
overlay.innerHTML = "<p>Drop files anywhere to upload</p>";
|
||||
document.getElementById("content-wrap").appendChild(overlay);
|
||||
}
|
||||
};
|
||||
|
||||
const dragleaveListener = function() {
|
||||
dragCounter--;
|
||||
if (dragCounter === 0) {
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
const dragleaveListener = function () {
|
||||
dragCounter--;
|
||||
if (dragCounter === 0) {
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const dropListener = function(e) {
|
||||
e.preventDefault();
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
const dropListener = function (e) {
|
||||
e.preventDefault();
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
allFiles.push(files[i]);
|
||||
}
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
allFiles.push(files[i]);
|
||||
}
|
||||
|
||||
const dataTransfer = new DataTransfer();
|
||||
allFiles.forEach(file => dataTransfer.items.add(file));
|
||||
const dataTransfer = new DataTransfer();
|
||||
allFiles.forEach((file) => dataTransfer.items.add(file));
|
||||
|
||||
const fileInput = document.getElementById(elementId);
|
||||
fileInput.files = dataTransfer.files;
|
||||
const fileInput = document.getElementById(elementId);
|
||||
fileInput.files = dataTransfer.files;
|
||||
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
|
||||
dragCounter = 0;
|
||||
dragCounter = 0;
|
||||
|
||||
fileInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
};
|
||||
fileInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
};
|
||||
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.body.addEventListener("dragenter", dragenterListener);
|
||||
document.body.addEventListener("dragleave", dragleaveListener);
|
||||
document.body.addEventListener("drop", dropListener);
|
||||
|
||||
$("#" + elementId).on("change", function (e) {
|
||||
allFiles = Array.from(e.target.files);
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
||||
function handleFileInputChange(inputElement) {
|
||||
const files = allFiles;
|
||||
const fileNames = files.map((f) => f.name);
|
||||
const selectedFilesContainer = $(inputElement).siblings(".selected-files");
|
||||
selectedFilesContainer.empty();
|
||||
fileNames.forEach((fileName) => {
|
||||
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.body.addEventListener('dragenter', dragenterListener);
|
||||
document.body.addEventListener('dragleave', dragleaveListener);
|
||||
document.body.addEventListener('drop', dropListener);
|
||||
|
||||
$("#" + elementId).on("change", function(e) {
|
||||
allFiles = Array.from(e.target.files);
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
||||
function handleFileInputChange(inputElement) {
|
||||
const files = allFiles;
|
||||
const fileNames = files.map(f => f.name);
|
||||
const selectedFilesContainer = $(inputElement).siblings(".selected-files");
|
||||
selectedFilesContainer.empty();
|
||||
fileNames.forEach(fileName => {
|
||||
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
||||
});
|
||||
if (fileNames.length === 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
||||
} else if (fileNames.length > 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames.length + " " + filesSelected);
|
||||
} else {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
||||
}
|
||||
if (fileNames.length === 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
||||
} else if (fileNames.length > 1) {
|
||||
$(inputElement)
|
||||
.siblings(".custom-file-label")
|
||||
.addClass("selected")
|
||||
.html(fileNames.length + " " + filesSelected);
|
||||
} else {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,292 +1,265 @@
|
||||
function initializeGame() {
|
||||
const gameContainer = document.getElementById('game-container');
|
||||
const player = document.getElementById('player');
|
||||
const gameContainer = document.getElementById("game-container");
|
||||
const player = document.getElementById("player");
|
||||
|
||||
let playerSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
player.style.width = playerSize + 'px';
|
||||
player.style.height = playerSize + 'px';
|
||||
let playerSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
player.style.width = playerSize + "px";
|
||||
player.style.height = playerSize + "px";
|
||||
|
||||
let playerX = gameContainer.clientWidth / 2 - playerSize / 2;
|
||||
let playerY = gameContainer.clientHeight * 0.1;
|
||||
const scoreElement = document.getElementById('score');
|
||||
const levelElement = document.getElementById('level');
|
||||
const livesElement = document.getElementById('lives');
|
||||
const highScoreElement = document.getElementById('high-score');
|
||||
let playerX = gameContainer.clientWidth / 2 - playerSize / 2;
|
||||
let playerY = gameContainer.clientHeight * 0.1;
|
||||
const scoreElement = document.getElementById("score");
|
||||
const levelElement = document.getElementById("level");
|
||||
const livesElement = document.getElementById("lives");
|
||||
const highScoreElement = document.getElementById("high-score");
|
||||
|
||||
let pdfSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
let projectileWidth = gameContainer.clientWidth * 0.00625;// 0.00625; // 0.5% of container width
|
||||
let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height
|
||||
let pdfSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
let projectileWidth = gameContainer.clientWidth * 0.00625; // 0.00625; // 0.5% of container width
|
||||
let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height
|
||||
|
||||
let paused = false;
|
||||
let paused = false;
|
||||
|
||||
const fireRate = 200; // Time between shots in milliseconds
|
||||
let lastProjectileTime = 0;
|
||||
let lives = 3;
|
||||
const fireRate = 200; // Time between shots in milliseconds
|
||||
let lastProjectileTime = 0;
|
||||
let lives = 3;
|
||||
|
||||
let highScore = localStorage.getItem("highScore") ? parseInt(localStorage.getItem("highScore")) : 0;
|
||||
updateHighScore();
|
||||
|
||||
let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0;
|
||||
updateHighScore();
|
||||
const keysPressed = {};
|
||||
const pdfs = [];
|
||||
const projectiles = [];
|
||||
let score = 0;
|
||||
let level = 1;
|
||||
let pdfSpeed = 0.5;
|
||||
let gameOver = false;
|
||||
|
||||
|
||||
|
||||
const keysPressed = {};
|
||||
const pdfs = [];
|
||||
const projectiles = [];
|
||||
let score = 0;
|
||||
let level = 1;
|
||||
let pdfSpeed = 0.5;
|
||||
let gameOver = false;
|
||||
|
||||
function handleKeys() {
|
||||
if (keysPressed['ArrowLeft']) {
|
||||
playerX -= 10;
|
||||
}
|
||||
if (keysPressed['ArrowRight']) {
|
||||
playerX += 10;
|
||||
}
|
||||
if (keysPressed[' '] && !gameOver) {
|
||||
const currentTime = new Date().getTime();
|
||||
if (currentTime - lastProjectileTime >= fireRate) {
|
||||
shootProjectile();
|
||||
lastProjectileTime = currentTime;
|
||||
}
|
||||
}
|
||||
updatePlayerPosition();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key === ' ') {
|
||||
event.preventDefault();
|
||||
}
|
||||
keysPressed[event.key] = true;
|
||||
handleKeys();
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (event) => {
|
||||
keysPressed[event.key] = false;
|
||||
});
|
||||
|
||||
|
||||
function updatePlayerPosition() {
|
||||
player.style.left = playerX + 'px';
|
||||
player.style.bottom = playerY + 'px';
|
||||
function handleKeys() {
|
||||
if (keysPressed["ArrowLeft"]) {
|
||||
playerX -= 10;
|
||||
}
|
||||
|
||||
function updateLives() {
|
||||
livesElement.textContent = 'Lives: ' + lives;
|
||||
if (keysPressed["ArrowRight"]) {
|
||||
playerX += 10;
|
||||
}
|
||||
|
||||
function updateHighScore() {
|
||||
highScoreElement.textContent = 'High Score: ' + highScore;
|
||||
if (keysPressed[" "] && !gameOver) {
|
||||
const currentTime = new Date().getTime();
|
||||
if (currentTime - lastProjectileTime >= fireRate) {
|
||||
shootProjectile();
|
||||
lastProjectileTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function shootProjectile() {
|
||||
const projectile = document.createElement('div');
|
||||
projectile.classList.add('projectile');
|
||||
projectile.style.backgroundColor = 'black';
|
||||
projectile.style.width = projectileWidth + 'px';
|
||||
projectile.style.height = projectileHeight + 'px';
|
||||
projectile.style.left = (playerX + playerSize / 2 - projectileWidth / 2) + 'px';
|
||||
projectile.style.top = (gameContainer.clientHeight - playerY - playerSize) + 'px';
|
||||
gameContainer.appendChild(projectile);
|
||||
projectiles.push(projectile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function spawnPdf() {
|
||||
const pdf = document.createElement('img');
|
||||
pdf.src = 'images/file-earmark-pdf.svg';
|
||||
pdf.classList.add('pdf');
|
||||
pdf.style.width = pdfSize + 'px';
|
||||
pdf.style.height = pdfSize + 'px';
|
||||
pdf.style.left = Math.floor(Math.random() * (gameContainer.clientWidth - pdfSize)) + 'px';
|
||||
pdf.style.top = '0px';
|
||||
gameContainer.appendChild(pdf);
|
||||
pdfs.push(pdf);
|
||||
}
|
||||
|
||||
|
||||
function resetEnemies() {
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
pdfs.length = 0;
|
||||
}
|
||||
|
||||
|
||||
function updateGame() {
|
||||
if (gameOver || paused) return;
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
const pdfY = parseFloat(pdf.style.top) + pdfSpeed;
|
||||
if (pdfY + 50 > gameContainer.clientHeight) {
|
||||
gameContainer.removeChild(pdf);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
|
||||
// Deduct 2 points when a PDF gets past the player
|
||||
score -= 0;
|
||||
updateScore();
|
||||
|
||||
// Decrease lives and check if game over
|
||||
lives--;
|
||||
updateLives();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
pdf.style.top = pdfY + 'px';
|
||||
|
||||
// Check for collision with player
|
||||
if (collisionDetected(player, pdf)) {
|
||||
lives--;
|
||||
updateLives();
|
||||
resetEnemies();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
projectiles.forEach((projectile, projectileIndex) => {
|
||||
const projectileY = parseInt(projectile.style.top) - 10;
|
||||
if (projectileY < 0) {
|
||||
gameContainer.removeChild(projectile);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
} else {
|
||||
projectile.style.top = projectileY + 'px';
|
||||
}
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
if (collisionDetected(projectile, pdf)) {
|
||||
gameContainer.removeChild(pdf);
|
||||
gameContainer.removeChild(projectile);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
score = score + 10;
|
||||
updateScore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
playerX = gameContainer.clientWidth / 2;
|
||||
playerY = 50;
|
||||
updatePlayerPosition();
|
||||
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
projectiles.forEach((projectile) => gameContainer.removeChild(projectile));
|
||||
|
||||
pdfs.length = 0;
|
||||
projectiles.length = 0;
|
||||
|
||||
score = 0;
|
||||
level = 1;
|
||||
lives = 3;
|
||||
|
||||
gameOver = false;
|
||||
|
||||
updateScore();
|
||||
updateLives();
|
||||
levelElement.textContent = 'Level: ' + level;
|
||||
pdfSpeed = 1;
|
||||
clearTimeout(spawnPdfTimeout); // Clear the existing spawnPdfTimeout
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
spawnPdfInterval();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateScore() {
|
||||
scoreElement.textContent = 'Score: ' + score;
|
||||
checkLevelUp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function checkLevelUp() {
|
||||
const newLevel = Math.floor(score / 100) + 1;
|
||||
if (newLevel > level) {
|
||||
level = newLevel;
|
||||
levelElement.textContent = 'Level: ' + level;
|
||||
pdfSpeed += 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
function collisionDetected(a, b) {
|
||||
const rectA = a.getBoundingClientRect();
|
||||
const rectB = b.getBoundingClientRect();
|
||||
return (
|
||||
rectA.left < rectB.right &&
|
||||
rectA.right > rectB.left &&
|
||||
rectA.top < rectB.bottom &&
|
||||
rectA.bottom > rectB.top
|
||||
);
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
gameOver = true;
|
||||
if (score > highScore) {
|
||||
highScore = score;
|
||||
localStorage.setItem('highScore', highScore);
|
||||
updateHighScore();
|
||||
}
|
||||
alert('Game Over! Your final score is: ' + score);
|
||||
document.getElementById('game-container-wrapper').close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let spawnPdfTimeout;
|
||||
|
||||
const BASE_SPAWN_INTERVAL_MS = 1250; // milliseconds before a new enemy spawns
|
||||
const LEVEL_INCREASE_FACTOR_MS = 0; // milliseconds to decrease the spawn interval per level
|
||||
const MAX_SPAWN_RATE_REDUCTION_MS = 800; // Max milliseconds from the base spawn interval
|
||||
|
||||
function spawnPdfInterval() {
|
||||
console.log("spawnPdfInterval");
|
||||
if (gameOver || paused) {
|
||||
console.log("spawnPdfInterval 2");
|
||||
clearTimeout(spawnPdfTimeout);
|
||||
return;
|
||||
}
|
||||
console.log("spawnPdfInterval 3");
|
||||
spawnPdf();
|
||||
let spawnRateReduction = Math.min(level * LEVEL_INCREASE_FACTOR_MS, MAX_SPAWN_RATE_REDUCTION_MS);
|
||||
let spawnRate = BASE_SPAWN_INTERVAL_MS - spawnRateReduction;
|
||||
spawnPdfTimeout = setTimeout(spawnPdfInterval, spawnRate);
|
||||
}
|
||||
|
||||
updatePlayerPosition();
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (event.key === " ") {
|
||||
event.preventDefault();
|
||||
}
|
||||
keysPressed[event.key] = true;
|
||||
handleKeys();
|
||||
});
|
||||
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden) {
|
||||
paused = true;
|
||||
} else {
|
||||
paused = false;
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
document.addEventListener("keyup", (event) => {
|
||||
keysPressed[event.key] = false;
|
||||
});
|
||||
|
||||
function updatePlayerPosition() {
|
||||
player.style.left = playerX + "px";
|
||||
player.style.bottom = playerY + "px";
|
||||
}
|
||||
|
||||
function updateLives() {
|
||||
livesElement.textContent = "Lives: " + lives;
|
||||
}
|
||||
|
||||
function updateHighScore() {
|
||||
highScoreElement.textContent = "High Score: " + highScore;
|
||||
}
|
||||
|
||||
function shootProjectile() {
|
||||
const projectile = document.createElement("div");
|
||||
projectile.classList.add("projectile");
|
||||
projectile.style.backgroundColor = "black";
|
||||
projectile.style.width = projectileWidth + "px";
|
||||
projectile.style.height = projectileHeight + "px";
|
||||
projectile.style.left = playerX + playerSize / 2 - projectileWidth / 2 + "px";
|
||||
projectile.style.top = gameContainer.clientHeight - playerY - playerSize + "px";
|
||||
gameContainer.appendChild(projectile);
|
||||
projectiles.push(projectile);
|
||||
}
|
||||
|
||||
function spawnPdf() {
|
||||
const pdf = document.createElement("img");
|
||||
pdf.src = "images/file-earmark-pdf.svg";
|
||||
pdf.classList.add("pdf");
|
||||
pdf.style.width = pdfSize + "px";
|
||||
pdf.style.height = pdfSize + "px";
|
||||
pdf.style.left = Math.floor(Math.random() * (gameContainer.clientWidth - pdfSize)) + "px";
|
||||
pdf.style.top = "0px";
|
||||
gameContainer.appendChild(pdf);
|
||||
pdfs.push(pdf);
|
||||
}
|
||||
|
||||
function resetEnemies() {
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
pdfs.length = 0;
|
||||
}
|
||||
|
||||
function updateGame() {
|
||||
if (gameOver || paused) return;
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
const pdfY = parseFloat(pdf.style.top) + pdfSpeed;
|
||||
if (pdfY + 50 > gameContainer.clientHeight) {
|
||||
gameContainer.removeChild(pdf);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
|
||||
// Deduct 2 points when a PDF gets past the player
|
||||
score -= 0;
|
||||
updateScore();
|
||||
|
||||
// Decrease lives and check if game over
|
||||
lives--;
|
||||
updateLives();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pdf.style.top = pdfY + "px";
|
||||
|
||||
// Check for collision with player
|
||||
if (collisionDetected(player, pdf)) {
|
||||
lives--;
|
||||
updateLives();
|
||||
resetEnemies();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projectiles.forEach((projectile, projectileIndex) => {
|
||||
const projectileY = parseInt(projectile.style.top) - 10;
|
||||
if (projectileY < 0) {
|
||||
gameContainer.removeChild(projectile);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
} else {
|
||||
projectile.style.top = projectileY + "px";
|
||||
}
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
if (collisionDetected(projectile, pdf)) {
|
||||
gameContainer.removeChild(pdf);
|
||||
gameContainer.removeChild(projectile);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
score = score + 10;
|
||||
updateScore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.resetGame = resetGame;
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
playerX = gameContainer.clientWidth / 2;
|
||||
playerY = 50;
|
||||
updatePlayerPosition();
|
||||
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
projectiles.forEach((projectile) => gameContainer.removeChild(projectile));
|
||||
|
||||
pdfs.length = 0;
|
||||
projectiles.length = 0;
|
||||
|
||||
score = 0;
|
||||
level = 1;
|
||||
lives = 3;
|
||||
|
||||
gameOver = false;
|
||||
|
||||
updateScore();
|
||||
updateLives();
|
||||
levelElement.textContent = "Level: " + level;
|
||||
pdfSpeed = 1;
|
||||
clearTimeout(spawnPdfTimeout); // Clear the existing spawnPdfTimeout
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
spawnPdfInterval();
|
||||
}
|
||||
|
||||
function updateScore() {
|
||||
scoreElement.textContent = "Score: " + score;
|
||||
checkLevelUp();
|
||||
}
|
||||
|
||||
function checkLevelUp() {
|
||||
const newLevel = Math.floor(score / 100) + 1;
|
||||
if (newLevel > level) {
|
||||
level = newLevel;
|
||||
levelElement.textContent = "Level: " + level;
|
||||
pdfSpeed += 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
function collisionDetected(a, b) {
|
||||
const rectA = a.getBoundingClientRect();
|
||||
const rectB = b.getBoundingClientRect();
|
||||
return rectA.left < rectB.right && rectA.right > rectB.left && rectA.top < rectB.bottom && rectA.bottom > rectB.top;
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
gameOver = true;
|
||||
if (score > highScore) {
|
||||
highScore = score;
|
||||
localStorage.setItem("highScore", highScore);
|
||||
updateHighScore();
|
||||
}
|
||||
alert("Game Over! Your final score is: " + score);
|
||||
document.getElementById("game-container-wrapper").close();
|
||||
}
|
||||
|
||||
let spawnPdfTimeout;
|
||||
|
||||
const BASE_SPAWN_INTERVAL_MS = 1250; // milliseconds before a new enemy spawns
|
||||
const LEVEL_INCREASE_FACTOR_MS = 0; // milliseconds to decrease the spawn interval per level
|
||||
const MAX_SPAWN_RATE_REDUCTION_MS = 800; // Max milliseconds from the base spawn interval
|
||||
|
||||
function spawnPdfInterval() {
|
||||
console.log("spawnPdfInterval");
|
||||
if (gameOver || paused) {
|
||||
console.log("spawnPdfInterval 2");
|
||||
clearTimeout(spawnPdfTimeout);
|
||||
return;
|
||||
}
|
||||
console.log("spawnPdfInterval 3");
|
||||
spawnPdf();
|
||||
let spawnRateReduction = Math.min(level * LEVEL_INCREASE_FACTOR_MS, MAX_SPAWN_RATE_REDUCTION_MS);
|
||||
let spawnRate = BASE_SPAWN_INTERVAL_MS - spawnRateReduction;
|
||||
spawnPdfTimeout = setTimeout(spawnPdfInterval, spawnRate);
|
||||
}
|
||||
|
||||
updatePlayerPosition();
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
|
||||
document.addEventListener("visibilitychange", function () {
|
||||
if (document.hidden) {
|
||||
paused = true;
|
||||
} else {
|
||||
paused = false;
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
}
|
||||
});
|
||||
|
||||
window.resetGame = resetGame;
|
||||
}
|
||||
|
||||
window.initializeGame = initializeGame;
|
||||
|
||||
@@ -1,55 +1,52 @@
|
||||
function compareVersions(version1, version2) {
|
||||
const v1 = version1.split('.');
|
||||
const v2 = version2.split('.');
|
||||
const v1 = version1.split(".");
|
||||
const v2 = version2.split(".");
|
||||
|
||||
for (let i = 0; i < v1.length || i < v2.length; i++) {
|
||||
const n1 = parseInt(v1[i]) || 0;
|
||||
const n2 = parseInt(v2[i]) || 0;
|
||||
for (let i = 0; i < v1.length || i < v2.length; i++) {
|
||||
const n1 = parseInt(v1[i]) || 0;
|
||||
const n2 = parseInt(v2[i]) || 0;
|
||||
|
||||
if (n1 > n2) {
|
||||
return 1;
|
||||
} else if (n1 < n2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (n1 > n2) {
|
||||
return 1;
|
||||
} else if (n1 < n2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
async function getLatestReleaseVersion() {
|
||||
const url = "https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest";
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
return data.tag_name ? data.tag_name.substring(1) : "";
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch latest version:", error);
|
||||
return ""; // Return an empty string if the fetch fails
|
||||
}
|
||||
const url = "https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest";
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
return data.tag_name ? data.tag_name.substring(1) : "";
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch latest version:", error);
|
||||
return ""; // Return an empty string if the fetch fails
|
||||
}
|
||||
}
|
||||
|
||||
async function checkForUpdate() {
|
||||
// Initialize the update button as hidden
|
||||
var updateBtn = document.getElementById("update-btn");
|
||||
if (updateBtn !== null) {
|
||||
updateBtn.style.display = "none";
|
||||
}
|
||||
// Initialize the update button as hidden
|
||||
var updateBtn = document.getElementById("update-btn");
|
||||
if (updateBtn !== null) {
|
||||
updateBtn.style.display = "none";
|
||||
}
|
||||
|
||||
|
||||
const latestVersion = await getLatestReleaseVersion();
|
||||
console.log("latestVersion=" + latestVersion)
|
||||
console.log("currentVersion=" + currentVersion)
|
||||
console.log("compareVersions(latestVersion, currentVersion) > 0)=" + compareVersions(latestVersion, currentVersion))
|
||||
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
||||
document.getElementById("update-btn").style.display = "block";
|
||||
console.log("visible")
|
||||
} else {
|
||||
console.log("hidden")
|
||||
}
|
||||
const latestVersion = await getLatestReleaseVersion();
|
||||
console.log("latestVersion=" + latestVersion);
|
||||
console.log("currentVersion=" + currentVersion);
|
||||
console.log("compareVersions(latestVersion, currentVersion) > 0)=" + compareVersions(latestVersion, currentVersion));
|
||||
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
||||
document.getElementById("update-btn").style.display = "block";
|
||||
console.log("visible");
|
||||
} else {
|
||||
console.log("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
checkForUpdate();
|
||||
document.addEventListener("DOMContentLoaded", (event) => {
|
||||
checkForUpdate();
|
||||
});
|
||||
|
||||
@@ -1,78 +1,76 @@
|
||||
function filterCards() {
|
||||
var input = document.getElementById('searchBar');
|
||||
var filter = input.value.toUpperCase();
|
||||
var cards = document.querySelectorAll('.feature-card');
|
||||
var input = document.getElementById("searchBar");
|
||||
var filter = input.value.toUpperCase();
|
||||
var cards = document.querySelectorAll(".feature-card");
|
||||
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
var card = cards[i];
|
||||
var title = card.querySelector('h5.card-title').innerText;
|
||||
var text = card.querySelector('p.card-text').innerText;
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
var card = cards[i];
|
||||
var title = card.querySelector("h5.card-title").innerText;
|
||||
var text = card.querySelector("p.card-text").innerText;
|
||||
|
||||
// Get the navbar tags associated with the card
|
||||
var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`);
|
||||
var navbarTags = navbarItem ? navbarItem.getAttribute('data-bs-tags') : '';
|
||||
// Get the navbar tags associated with the card
|
||||
var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`);
|
||||
var navbarTags = navbarItem ? navbarItem.getAttribute("data-bs-tags") : "";
|
||||
|
||||
var content = title + ' ' + text + ' ' + navbarTags;
|
||||
var content = title + " " + text + " " + navbarTags;
|
||||
|
||||
if (content.toUpperCase().indexOf(filter) > -1) {
|
||||
card.style.display = "";
|
||||
} else {
|
||||
card.style.display = "none";
|
||||
}
|
||||
if (content.toUpperCase().indexOf(filter) > -1) {
|
||||
card.style.display = "";
|
||||
} else {
|
||||
card.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function toggleFavorite(element) {
|
||||
var img = element.querySelector('img');
|
||||
var card = element.closest('.feature-card');
|
||||
var cardId = card.id;
|
||||
if (img.src.endsWith('star.svg')) {
|
||||
img.src = 'images/star-fill.svg';
|
||||
card.classList.add('favorite');
|
||||
localStorage.setItem(cardId, 'favorite');
|
||||
} else {
|
||||
img.src = 'images/star.svg';
|
||||
card.classList.remove('favorite');
|
||||
localStorage.removeItem(cardId);
|
||||
}
|
||||
reorderCards();
|
||||
updateFavoritesDropdown();
|
||||
filterCards();
|
||||
var img = element.querySelector("img");
|
||||
var card = element.closest(".feature-card");
|
||||
var cardId = card.id;
|
||||
if (img.src.endsWith("star.svg")) {
|
||||
img.src = "images/star-fill.svg";
|
||||
card.classList.add("favorite");
|
||||
localStorage.setItem(cardId, "favorite");
|
||||
} else {
|
||||
img.src = "images/star.svg";
|
||||
card.classList.remove("favorite");
|
||||
localStorage.removeItem(cardId);
|
||||
}
|
||||
reorderCards();
|
||||
updateFavoritesDropdown();
|
||||
filterCards();
|
||||
}
|
||||
|
||||
function reorderCards() {
|
||||
var container = document.querySelector('.features-container');
|
||||
var cards = Array.from(container.getElementsByClassName('feature-card'));
|
||||
cards.sort(function(a, b) {
|
||||
var aIsFavorite = localStorage.getItem(a.id) === 'favorite';
|
||||
var bIsFavorite = localStorage.getItem(b.id) === 'favorite';
|
||||
if (aIsFavorite && !bIsFavorite) {
|
||||
return -1;
|
||||
}
|
||||
if (!aIsFavorite && bIsFavorite) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
cards.forEach(function(card) {
|
||||
container.appendChild(card);
|
||||
});
|
||||
var container = document.querySelector(".features-container");
|
||||
var cards = Array.from(container.getElementsByClassName("feature-card"));
|
||||
cards.sort(function (a, b) {
|
||||
var aIsFavorite = localStorage.getItem(a.id) === "favorite";
|
||||
var bIsFavorite = localStorage.getItem(b.id) === "favorite";
|
||||
if (aIsFavorite && !bIsFavorite) {
|
||||
return -1;
|
||||
}
|
||||
if (!aIsFavorite && bIsFavorite) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
cards.forEach(function (card) {
|
||||
container.appendChild(card);
|
||||
});
|
||||
}
|
||||
function initializeCards() {
|
||||
var cards = document.querySelectorAll('.feature-card');
|
||||
cards.forEach(function(card) {
|
||||
var cardId = card.id;
|
||||
var img = card.querySelector('.favorite-icon img');
|
||||
if (localStorage.getItem(cardId) === 'favorite') {
|
||||
img.src = 'images/star-fill.svg';
|
||||
card.classList.add('favorite');
|
||||
}
|
||||
});
|
||||
reorderCards();
|
||||
updateFavoritesDropdown();
|
||||
filterCards();
|
||||
var cards = document.querySelectorAll(".feature-card");
|
||||
cards.forEach(function (card) {
|
||||
var cardId = card.id;
|
||||
var img = card.querySelector(".favorite-icon img");
|
||||
if (localStorage.getItem(cardId) === "favorite") {
|
||||
img.src = "images/star-fill.svg";
|
||||
card.classList.add("favorite");
|
||||
}
|
||||
});
|
||||
reorderCards();
|
||||
updateFavoritesDropdown();
|
||||
filterCards();
|
||||
}
|
||||
|
||||
window.onload = initializeCards;
|
||||
window.onload = initializeCards;
|
||||
|
||||
@@ -1,80 +1,88 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setLanguageForDropdown('.lang_dropdown-item');
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
setLanguageForDropdown(".lang_dropdown-item");
|
||||
|
||||
// Detect the browser's preferred language
|
||||
let browserLang = navigator.language || navigator.userLanguage;
|
||||
// Convert to a format consistent with your language codes (e.g., en-GB, fr-FR)
|
||||
browserLang = browserLang.replace('-', '_');
|
||||
// Detect the browser's preferred language
|
||||
let browserLang = navigator.language || navigator.userLanguage;
|
||||
// Convert to a format consistent with your language codes (e.g., en-GB, fr-FR)
|
||||
browserLang = browserLang.replace("-", "_");
|
||||
|
||||
// Check if the dropdown contains the browser's language
|
||||
const dropdownLangExists = document.querySelector(`.lang_dropdown-item[data-language-code="${browserLang}"]`);
|
||||
// Check if the dropdown contains the browser's language
|
||||
const dropdownLangExists = document.querySelector(`.lang_dropdown-item[data-language-code="${browserLang}"]`);
|
||||
|
||||
// Set the default language to browser's language or 'en_GB' if not found in the dropdown
|
||||
const defaultLocale = dropdownLangExists ? browserLang : 'en_GB';
|
||||
const storedLocale = localStorage.getItem('languageCode') || defaultLocale;
|
||||
// Set the default language to browser's language or 'en_GB' if not found in the dropdown
|
||||
const defaultLocale = dropdownLangExists ? browserLang : "en_GB";
|
||||
const storedLocale = localStorage.getItem("languageCode") || defaultLocale;
|
||||
|
||||
const dropdownItems = document.querySelectorAll(".lang_dropdown-item");
|
||||
|
||||
|
||||
const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
|
||||
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.languageCode === storedLocale) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
item.addEventListener('click', handleDropdownItemClick);
|
||||
}
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove("active");
|
||||
if (item.dataset.languageCode === storedLocale) {
|
||||
item.classList.add("active");
|
||||
}
|
||||
item.addEventListener("click", handleDropdownItemClick);
|
||||
}
|
||||
});
|
||||
|
||||
function setLanguageForDropdown(dropdownClass) {
|
||||
const defaultLocale = document.documentElement.lang || 'en_GB';
|
||||
const storedLocale = localStorage.getItem('languageCode') || defaultLocale;
|
||||
const dropdownItems = document.querySelectorAll(dropdownClass);
|
||||
const defaultLocale = document.documentElement.lang || "en_GB";
|
||||
const storedLocale = localStorage.getItem("languageCode") || defaultLocale;
|
||||
const dropdownItems = document.querySelectorAll(dropdownClass);
|
||||
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.languageCode === storedLocale) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
item.addEventListener('click', handleDropdownItemClick);
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove("active");
|
||||
if (item.dataset.languageCode === storedLocale) {
|
||||
item.classList.add("active");
|
||||
}
|
||||
item.addEventListener("click", handleDropdownItemClick);
|
||||
}
|
||||
}
|
||||
|
||||
function handleDropdownItemClick(event) {
|
||||
event.preventDefault();
|
||||
const languageCode = event.currentTarget.dataset.bsLanguageCode; // change this to event.currentTarget
|
||||
if (languageCode) {
|
||||
localStorage.setItem('languageCode', languageCode);
|
||||
event.preventDefault();
|
||||
const languageCode = event.currentTarget.dataset.bsLanguageCode; // change this to event.currentTarget
|
||||
if (languageCode) {
|
||||
localStorage.setItem("languageCode", languageCode);
|
||||
|
||||
const currentUrl = window.location.href;
|
||||
if (currentUrl.indexOf('?lang=') === -1) {
|
||||
window.location.href = currentUrl + '?lang=' + languageCode;
|
||||
} else {
|
||||
window.location.href = currentUrl.replace(/\?lang=\w{2,}/, '?lang=' + languageCode);
|
||||
}
|
||||
const currentUrl = window.location.href;
|
||||
if (currentUrl.indexOf("?lang=") === -1) {
|
||||
window.location.href = currentUrl + "?lang=" + languageCode;
|
||||
} else {
|
||||
console.error("Language code is not set for this item."); // for debugging
|
||||
window.location.href = currentUrl.replace(/\?lang=\w{2,}/, "?lang=" + languageCode);
|
||||
}
|
||||
} else {
|
||||
console.error("Language code is not set for this item."); // for debugging
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.querySelectorAll(".nav-item.dropdown").forEach((element) => {
|
||||
const dropdownMenu = element.querySelector(".dropdown-menu");
|
||||
if (
|
||||
dropdownMenu.id !== "favoritesDropdown" &&
|
||||
dropdownMenu.children.length <= 2 &&
|
||||
dropdownMenu.querySelectorAll("hr.dropdown-divider").length === dropdownMenu.children.length
|
||||
) {
|
||||
if (
|
||||
element.previousElementSibling &&
|
||||
element.previousElementSibling.classList.contains("nav-item") &&
|
||||
element.previousElementSibling.classList.contains("nav-item-separator")
|
||||
) {
|
||||
element.previousElementSibling.remove();
|
||||
}
|
||||
element.remove();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.nav-item.dropdown').forEach((element) => {
|
||||
const dropdownMenu = element.querySelector(".dropdown-menu");
|
||||
if (dropdownMenu.id !== 'favoritesDropdown' && dropdownMenu.children.length <= 2 && dropdownMenu.querySelectorAll("hr.dropdown-divider").length === dropdownMenu.children.length) {
|
||||
if (element.previousElementSibling && element.previousElementSibling.classList.contains('nav-item') && element.previousElementSibling.classList.contains('nav-item-separator')) {
|
||||
element.previousElementSibling.remove();
|
||||
}
|
||||
element.remove();
|
||||
}
|
||||
});
|
||||
|
||||
//Sort languages by alphabet
|
||||
const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter(child => child.matches('a'));
|
||||
list.sort(function(a, b) {
|
||||
return a.textContent.toUpperCase().localeCompare(b.textContent.toUpperCase());
|
||||
}).forEach(node => document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').appendChild(node));
|
||||
|
||||
});
|
||||
//Sort languages by alphabet
|
||||
const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter(
|
||||
(child) => child.matches("a"),
|
||||
);
|
||||
list
|
||||
.sort(function (a, b) {
|
||||
return a.textContent.toUpperCase().localeCompare(b.textContent.toUpperCase());
|
||||
})
|
||||
.forEach((node) => document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').appendChild(node));
|
||||
});
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
async function downloadFilesWithCallback(processFileCallback) {
|
||||
const fileInput = document.querySelector('input[type="file"]');
|
||||
const files = fileInput.files;
|
||||
const fileInput = document.querySelector('input[type="file"]');
|
||||
const files = fileInput.files;
|
||||
|
||||
const zipThreshold = 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
const zipThreshold = 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
|
||||
let jszip = null;
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
let jszip = null;
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
|
||||
const promises = Array.from(files).map(async file => {
|
||||
const { processedData, fileName } = await processFileCallback(file);
|
||||
|
||||
if (zipFiles) {
|
||||
jszip.file(fileName, processedData);
|
||||
} else {
|
||||
const url = URL.createObjectURL(processedData);
|
||||
const downloadOption = localStorage.getItem('downloadOption');
|
||||
|
||||
if (downloadOption === 'sameWindow') {
|
||||
window.location.href = url;
|
||||
} else if (downloadOption === 'newWindow') {
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = url;
|
||||
downloadLink.download = fileName;
|
||||
downloadLink.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
const promises = Array.from(files).map(async (file) => {
|
||||
const { processedData, fileName } = await processFileCallback(file);
|
||||
|
||||
if (zipFiles) {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
const url = URL.createObjectURL(content);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = "files.zip";
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
jszip.file(fileName, processedData);
|
||||
} else {
|
||||
const url = URL.createObjectURL(processedData);
|
||||
const downloadOption = localStorage.getItem("downloadOption");
|
||||
|
||||
if (downloadOption === "sameWindow") {
|
||||
window.location.href = url;
|
||||
} else if (downloadOption === "newWindow") {
|
||||
window.open(url, "_blank");
|
||||
} else {
|
||||
const downloadLink = document.createElement("a");
|
||||
downloadLink.href = url;
|
||||
downloadLink.download = fileName;
|
||||
downloadLink.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
if (zipFiles) {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
const url = URL.createObjectURL(content);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "files.zip";
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
let currentSort = {
|
||||
field: null,
|
||||
descending: false
|
||||
field: null,
|
||||
descending: false,
|
||||
};
|
||||
|
||||
document.getElementById("fileInput-input").addEventListener("change", function() {
|
||||
var files = this.files;
|
||||
displayFiles(files);
|
||||
document.getElementById("fileInput-input").addEventListener("change", function () {
|
||||
var files = this.files;
|
||||
displayFiles(files);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {FileList} files
|
||||
*/
|
||||
function displayFiles(files) {
|
||||
const list = document.getElementById("selectedFiles");
|
||||
const list = document.getElementById("selectedFiles");
|
||||
|
||||
while (list.firstChild) {
|
||||
list.removeChild(list.firstChild);
|
||||
}
|
||||
while (list.firstChild) {
|
||||
list.removeChild(list.firstChild);
|
||||
}
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const item = document.createElement("li");
|
||||
item.className = "list-group-item";
|
||||
item.innerHTML = `
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const item = document.createElement("li");
|
||||
item.className = "list-group-item";
|
||||
item.innerHTML = `
|
||||
<div class="d-flex justify-content-between align-items-center w-100">
|
||||
<div class="filename">${files[i].name}</div>
|
||||
<div class="arrows d-flex">
|
||||
@@ -31,100 +31,100 @@ function displayFiles(files) {
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
list.appendChild(item);
|
||||
}
|
||||
list.appendChild(item);
|
||||
}
|
||||
|
||||
attachMoveButtons();
|
||||
attachMoveButtons();
|
||||
}
|
||||
|
||||
function attachMoveButtons() {
|
||||
var moveUpButtons = document.querySelectorAll(".move-up");
|
||||
for (var i = 0; i < moveUpButtons.length; i++) {
|
||||
moveUpButtons[i].addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.previousElementSibling) {
|
||||
grandParent.insertBefore(parent, parent.previousElementSibling);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
var moveUpButtons = document.querySelectorAll(".move-up");
|
||||
for (var i = 0; i < moveUpButtons.length; i++) {
|
||||
moveUpButtons[i].addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.previousElementSibling) {
|
||||
grandParent.insertBefore(parent, parent.previousElementSibling);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var moveDownButtons = document.querySelectorAll(".move-down");
|
||||
for (var i = 0; i < moveDownButtons.length; i++) {
|
||||
moveDownButtons[i].addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.nextElementSibling) {
|
||||
grandParent.insertBefore(parent.nextElementSibling, parent);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
var moveDownButtons = document.querySelectorAll(".move-down");
|
||||
for (var i = 0; i < moveDownButtons.length; i++) {
|
||||
moveDownButtons[i].addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
var grandParent = parent.parentNode;
|
||||
if (parent.nextElementSibling) {
|
||||
grandParent.insertBefore(parent.nextElementSibling, parent);
|
||||
updateFiles();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var removeButtons = document.querySelectorAll(".remove-file");
|
||||
for (var i = 0; i < removeButtons.length; i++) {
|
||||
removeButtons[i].addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
parent.remove();
|
||||
updateFiles();
|
||||
});
|
||||
}
|
||||
var removeButtons = document.querySelectorAll(".remove-file");
|
||||
for (var i = 0; i < removeButtons.length; i++) {
|
||||
removeButtons[i].addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
var parent = this.closest(".list-group-item");
|
||||
parent.remove();
|
||||
updateFiles();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("sortByNameBtn").addEventListener("click", function() {
|
||||
if (currentSort.field === "name" && !currentSort.descending) {
|
||||
currentSort.descending = true;
|
||||
sortFiles((a, b) => b.name.localeCompare(a.name));
|
||||
} else {
|
||||
currentSort.field = "name";
|
||||
currentSort.descending = false;
|
||||
sortFiles((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
document.getElementById("sortByNameBtn").addEventListener("click", function () {
|
||||
if (currentSort.field === "name" && !currentSort.descending) {
|
||||
currentSort.descending = true;
|
||||
sortFiles((a, b) => b.name.localeCompare(a.name));
|
||||
} else {
|
||||
currentSort.field = "name";
|
||||
currentSort.descending = false;
|
||||
sortFiles((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("sortByDateBtn").addEventListener("click", function() {
|
||||
if (currentSort.field === "lastModified" && !currentSort.descending) {
|
||||
currentSort.descending = true;
|
||||
sortFiles((a, b) => b.lastModified - a.lastModified);
|
||||
} else {
|
||||
currentSort.field = "lastModified";
|
||||
currentSort.descending = false;
|
||||
sortFiles((a, b) => a.lastModified - b.lastModified);
|
||||
}
|
||||
document.getElementById("sortByDateBtn").addEventListener("click", function () {
|
||||
if (currentSort.field === "lastModified" && !currentSort.descending) {
|
||||
currentSort.descending = true;
|
||||
sortFiles((a, b) => b.lastModified - a.lastModified);
|
||||
} else {
|
||||
currentSort.field = "lastModified";
|
||||
currentSort.descending = false;
|
||||
sortFiles((a, b) => a.lastModified - b.lastModified);
|
||||
}
|
||||
});
|
||||
|
||||
function sortFiles(comparator) {
|
||||
// Convert FileList to array and sort
|
||||
const sortedFilesArray = Array.from(document.getElementById("fileInput-input").files).sort(comparator);
|
||||
// Convert FileList to array and sort
|
||||
const sortedFilesArray = Array.from(document.getElementById("fileInput-input").files).sort(comparator);
|
||||
|
||||
// Refresh displayed list
|
||||
displayFiles(sortedFilesArray);
|
||||
// Refresh displayed list
|
||||
displayFiles(sortedFilesArray);
|
||||
|
||||
// Update the files property
|
||||
const dataTransfer = new DataTransfer();
|
||||
sortedFilesArray.forEach(file => dataTransfer.items.add(file));
|
||||
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||
// Update the files property
|
||||
const dataTransfer = new DataTransfer();
|
||||
sortedFilesArray.forEach((file) => dataTransfer.items.add(file));
|
||||
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||
}
|
||||
|
||||
function updateFiles() {
|
||||
var dataTransfer = new DataTransfer();
|
||||
var liElements = document.querySelectorAll("#selectedFiles li");
|
||||
const files = document.getElementById("fileInput-input").files;
|
||||
var dataTransfer = new DataTransfer();
|
||||
var liElements = document.querySelectorAll("#selectedFiles li");
|
||||
const files = document.getElementById("fileInput-input").files;
|
||||
|
||||
for (var i = 0; i < liElements.length; i++) {
|
||||
var fileNameFromList = liElements[i].querySelector(".filename").innerText;
|
||||
var fileFromFiles;
|
||||
for (var j = 0; j < files.length; j++) {
|
||||
var file = files[j];
|
||||
if (file.name === fileNameFromList) {
|
||||
dataTransfer.items.add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < liElements.length; i++) {
|
||||
var fileNameFromList = liElements[i].querySelector(".filename").innerText;
|
||||
var fileFromFiles;
|
||||
for (var j = 0; j < files.length; j++) {
|
||||
var file = files[j];
|
||||
if (file.name === fileNameFromList) {
|
||||
dataTransfer.items.add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||
}
|
||||
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||
}
|
||||
|
||||
@@ -1,125 +1,123 @@
|
||||
class DragDropManager {
|
||||
dragContainer;
|
||||
wrapper;
|
||||
pageDirection;
|
||||
movePageTo;
|
||||
pageDragging;
|
||||
draggelEl;
|
||||
draggedImageEl;
|
||||
hoveredEl;
|
||||
endInsertionElement;
|
||||
dragContainer;
|
||||
wrapper;
|
||||
pageDirection;
|
||||
movePageTo;
|
||||
pageDragging;
|
||||
draggelEl;
|
||||
draggedImageEl;
|
||||
hoveredEl;
|
||||
endInsertionElement;
|
||||
|
||||
constructor(id, wrapperId) {
|
||||
this.dragContainer = document.getElementById(id);
|
||||
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
||||
this.wrapper = document.getElementById(wrapperId);
|
||||
this.pageDragging = false;
|
||||
this.hoveredEl = undefined;
|
||||
this.draggelEl = undefined
|
||||
this.draggedImageEl = undefined;
|
||||
constructor(id, wrapperId) {
|
||||
this.dragContainer = document.getElementById(id);
|
||||
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
||||
this.wrapper = document.getElementById(wrapperId);
|
||||
this.pageDragging = false;
|
||||
this.hoveredEl = undefined;
|
||||
this.draggelEl = undefined;
|
||||
this.draggedImageEl = undefined;
|
||||
|
||||
var styleElement = document.createElement('link');
|
||||
styleElement.rel = 'stylesheet';
|
||||
styleElement.href = 'css/dragdrop.css'
|
||||
var styleElement = document.createElement("link");
|
||||
styleElement.rel = "stylesheet";
|
||||
styleElement.href = "css/dragdrop.css";
|
||||
|
||||
document.head.appendChild(styleElement);
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('drag-manager_endpoint');
|
||||
div.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("drag-manager_endpoint");
|
||||
div.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
|
||||
<path d="M8.5 6.5a.5.5 0 0 0-1 0v3.793L6.354 9.146a.5.5 0 1 0-.708.708l2 2a.5.5 0 0 0 .708 0l2-2a.5.5 0 0 0-.708-.708L8.5 10.293V6.5z"/>
|
||||
<path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z"/>
|
||||
</svg>`
|
||||
this.endInsertionElement = div;
|
||||
</svg>`;
|
||||
this.endInsertionElement = div;
|
||||
|
||||
this.startDraggingPage = this.startDraggingPage.bind(this);
|
||||
this.onDragEl = this.onDragEl.bind(this);
|
||||
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
||||
this.startDraggingPage = this.startDraggingPage.bind(this);
|
||||
this.onDragEl = this.onDragEl.bind(this);
|
||||
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
||||
|
||||
this.adapt(div);
|
||||
this.adapt(div);
|
||||
}
|
||||
|
||||
startDraggingPage(div) {
|
||||
this.pageDragging = true;
|
||||
this.draggedEl = div;
|
||||
const img = div.querySelector("img");
|
||||
div.classList.add("drag-manager_dragging");
|
||||
const imageSrc = img.src;
|
||||
|
||||
const imgEl = document.createElement("img");
|
||||
imgEl.classList.add("dragged-img");
|
||||
imgEl.src = imageSrc;
|
||||
this.draggedImageEl = imgEl;
|
||||
imgEl.style.visibility = "hidden";
|
||||
imgEl.style.transform = `rotate(${img.style.rotate === "" ? "0deg" : img.style.rotate}) translate(-50%, -50%)`;
|
||||
this.dragContainer.appendChild(imgEl);
|
||||
|
||||
window.addEventListener("mouseup", this.stopDraggingPage);
|
||||
window.addEventListener("mousemove", this.onDragEl);
|
||||
this.wrapper.classList.add("drag-manager_dragging-container");
|
||||
this.wrapper.appendChild(this.endInsertionElement);
|
||||
}
|
||||
|
||||
onDragEl(mouseEvent) {
|
||||
const { clientX, clientY } = mouseEvent;
|
||||
if (this.draggedImageEl) {
|
||||
this.draggedImageEl.style.visibility = "visible";
|
||||
this.draggedImageEl.style.left = `${clientX}px`;
|
||||
this.draggedImageEl.style.top = `${clientY}px`;
|
||||
}
|
||||
}
|
||||
|
||||
startDraggingPage(div,) {
|
||||
this.pageDragging = true;
|
||||
this.draggedEl = div;
|
||||
const img = div.querySelector('img');
|
||||
div.classList.add('drag-manager_dragging');
|
||||
const imageSrc = img.src;
|
||||
|
||||
const imgEl = document.createElement('img');
|
||||
imgEl.classList.add('dragged-img');
|
||||
imgEl.src = imageSrc;
|
||||
this.draggedImageEl = imgEl;
|
||||
imgEl.style.visibility = 'hidden';
|
||||
imgEl.style.transform = `rotate(${img.style.rotate === '' ? '0deg' : img.style.rotate}) translate(-50%, -50%)`;
|
||||
this.dragContainer.appendChild(imgEl);
|
||||
|
||||
window.addEventListener('mouseup', this.stopDraggingPage)
|
||||
window.addEventListener('mousemove', this.onDragEl)
|
||||
this.wrapper.classList.add('drag-manager_dragging-container');
|
||||
this.wrapper.appendChild(this.endInsertionElement);
|
||||
stopDraggingPage() {
|
||||
window.removeEventListener("mousemove", this.onDragEl);
|
||||
this.wrapper.classList.remove("drag-manager_dragging-container");
|
||||
this.wrapper.removeChild(this.endInsertionElement);
|
||||
window.removeEventListener("mouseup", this.stopDraggingPage);
|
||||
this.draggedImageEl = undefined;
|
||||
this.pageDragging = false;
|
||||
this.draggedEl.classList.remove("drag-manager_dragging");
|
||||
this.hoveredEl?.classList.remove("drag-manager_draghover");
|
||||
this.dragContainer.childNodes.forEach((dragChild) => {
|
||||
this.dragContainer.removeChild(dragChild);
|
||||
});
|
||||
if (!this.hoveredEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
onDragEl(mouseEvent) {
|
||||
const { clientX, clientY } = mouseEvent;
|
||||
if(this.draggedImageEl) {
|
||||
this.draggedImageEl.style.visibility = 'visible';
|
||||
this.draggedImageEl.style.left = `${clientX}px`;
|
||||
this.draggedImageEl.style.top = `${clientY}px`;
|
||||
}
|
||||
if (this.hoveredEl === this.endInsertionElement) {
|
||||
this.movePageTo(this.draggedEl);
|
||||
return;
|
||||
}
|
||||
this.movePageTo(this.draggedEl, this.hoveredEl);
|
||||
}
|
||||
|
||||
setActions({ movePageTo }) {
|
||||
this.movePageTo = movePageTo;
|
||||
}
|
||||
|
||||
stopDraggingPage() {
|
||||
window.removeEventListener('mousemove', this.onDragEl);
|
||||
this.wrapper.classList.remove('drag-manager_dragging-container');
|
||||
this.wrapper.removeChild(this.endInsertionElement);
|
||||
window.removeEventListener('mouseup', this.stopDraggingPage)
|
||||
this.draggedImageEl = undefined;
|
||||
this.pageDragging = false;
|
||||
this.draggedEl.classList.remove('drag-manager_dragging');
|
||||
this.hoveredEl?.classList.remove('drag-manager_draghover');
|
||||
this.dragContainer.childNodes.forEach((dragChild) => {
|
||||
this.dragContainer.removeChild(dragChild);
|
||||
})
|
||||
if(!this.hoveredEl) {
|
||||
return;
|
||||
}
|
||||
if(this.hoveredEl === this.endInsertionElement) {
|
||||
this.movePageTo(this.draggedEl);
|
||||
return;
|
||||
}
|
||||
this.movePageTo(this.draggedEl, this.hoveredEl);
|
||||
}
|
||||
adapt(div) {
|
||||
const onDragStart = () => {
|
||||
this.startDraggingPage(div);
|
||||
};
|
||||
|
||||
setActions({ movePageTo }) {
|
||||
this.movePageTo = movePageTo;
|
||||
}
|
||||
const onMouseEnter = () => {
|
||||
if (this.pageDragging) {
|
||||
this.hoveredEl = div;
|
||||
div.classList.add("drag-manager_draghover");
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseLeave = () => {
|
||||
this.hoveredEl = undefined;
|
||||
div.classList.remove("drag-manager_draghover");
|
||||
};
|
||||
|
||||
adapt(div) {
|
||||
const onDragStart = () => {
|
||||
this.startDraggingPage(div);
|
||||
}
|
||||
div.addEventListener("dragstart", onDragStart);
|
||||
div.addEventListener("mouseenter", onMouseEnter);
|
||||
div.addEventListener("mouseleave", onMouseLeave);
|
||||
|
||||
const onMouseEnter = () => {
|
||||
if (this.pageDragging) {
|
||||
this.hoveredEl = div;
|
||||
div.classList.add('drag-manager_draghover');
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseLeave = () => {
|
||||
this.hoveredEl = undefined
|
||||
div.classList.remove('drag-manager_draghover');
|
||||
}
|
||||
|
||||
div.addEventListener('dragstart', onDragStart);
|
||||
div.addEventListener('mouseenter', onMouseEnter);
|
||||
div.addEventListener('mouseleave', onMouseLeave);
|
||||
|
||||
return div;
|
||||
}
|
||||
return div;
|
||||
}
|
||||
}
|
||||
|
||||
export default DragDropManager;
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
class ImageHiglighter {
|
||||
imageHighlighter;
|
||||
constructor(id) {
|
||||
this.imageHighlighter = document.getElementById(id);
|
||||
this.imageHighlightCallback = this.imageHighlightCallback.bind(this);
|
||||
imageHighlighter;
|
||||
constructor(id) {
|
||||
this.imageHighlighter = document.getElementById(id);
|
||||
this.imageHighlightCallback = this.imageHighlightCallback.bind(this);
|
||||
|
||||
var styleElement = document.createElement('link');
|
||||
styleElement.rel = 'stylesheet';
|
||||
styleElement.href = 'css/imageHighlighter.css'
|
||||
var styleElement = document.createElement("link");
|
||||
styleElement.rel = "stylesheet";
|
||||
styleElement.href = "css/imageHighlighter.css";
|
||||
|
||||
document.head.appendChild(styleElement);
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
this.imageHighlighter.onclick = () => {
|
||||
this.imageHighlighter.childNodes.forEach((child) => {
|
||||
child.classList.add('remove');
|
||||
setTimeout(() => {
|
||||
this.imageHighlighter.removeChild(child);
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
imageHighlightCallback(highlightEvent) {
|
||||
var bigImg = document.createElement('img');
|
||||
bigImg.onclick = (imageClickEvent) => {
|
||||
// This prevents the highlighter's onClick from closing the image when clicking
|
||||
// on the image instead of next to it.
|
||||
imageClickEvent.preventDefault();
|
||||
imageClickEvent.stopPropagation();
|
||||
};
|
||||
bigImg.src = highlightEvent.target.src;
|
||||
this.imageHighlighter.appendChild(bigImg);
|
||||
this.imageHighlighter.onclick = () => {
|
||||
this.imageHighlighter.childNodes.forEach((child) => {
|
||||
child.classList.add("remove");
|
||||
setTimeout(() => {
|
||||
this.imageHighlighter.removeChild(child);
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
setActions() {
|
||||
// not needed in this case
|
||||
}
|
||||
imageHighlightCallback(highlightEvent) {
|
||||
var bigImg = document.createElement("img");
|
||||
bigImg.onclick = (imageClickEvent) => {
|
||||
// This prevents the highlighter's onClick from closing the image when clicking
|
||||
// on the image instead of next to it.
|
||||
imageClickEvent.preventDefault();
|
||||
imageClickEvent.stopPropagation();
|
||||
};
|
||||
bigImg.src = highlightEvent.target.src;
|
||||
this.imageHighlighter.appendChild(bigImg);
|
||||
}
|
||||
|
||||
adapt(div) {
|
||||
const img = div.querySelector('.page-image');
|
||||
img.addEventListener('click', this.imageHighlightCallback)
|
||||
return div;
|
||||
}
|
||||
setActions() {
|
||||
// not needed in this case
|
||||
}
|
||||
|
||||
adapt(div) {
|
||||
const img = div.querySelector(".page-image");
|
||||
img.addEventListener("click", this.imageHighlightCallback);
|
||||
return div;
|
||||
}
|
||||
}
|
||||
|
||||
export default ImageHiglighter;
|
||||
export default ImageHiglighter;
|
||||
|
||||
@@ -1,198 +1,200 @@
|
||||
class PdfActionsManager {
|
||||
pageDirection;
|
||||
pagesContainer;
|
||||
pageDirection;
|
||||
pagesContainer;
|
||||
|
||||
constructor(id) {
|
||||
this.pagesContainer = document.getElementById(id);
|
||||
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
||||
constructor(id) {
|
||||
this.pagesContainer = document.getElementById(id);
|
||||
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
||||
|
||||
var styleElement = document.createElement('link');
|
||||
styleElement.rel = 'stylesheet';
|
||||
styleElement.href = 'css/pdfActions.css'
|
||||
var styleElement = document.createElement("link");
|
||||
styleElement.rel = "stylesheet";
|
||||
styleElement.href = "css/pdfActions.css";
|
||||
|
||||
document.head.appendChild(styleElement);
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
|
||||
getPageContainer(element) {
|
||||
var container = element;
|
||||
while (!container.classList.contains("page-container")) {
|
||||
container = container.parentNode;
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
getPageContainer(element) {
|
||||
var container = element
|
||||
while (!container.classList.contains('page-container')) {
|
||||
container = container.parentNode;
|
||||
}
|
||||
return container;
|
||||
moveUpButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
|
||||
const sibling = imgContainer.previousSibling;
|
||||
if (sibling) {
|
||||
this.movePageTo(imgContainer, sibling, true);
|
||||
}
|
||||
}
|
||||
|
||||
moveUpButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
|
||||
const sibling = imgContainer.previousSibling;
|
||||
if (sibling) {
|
||||
this.movePageTo(imgContainer, sibling, true);
|
||||
}
|
||||
moveDownButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const sibling = imgContainer.nextSibling;
|
||||
if (sibling) {
|
||||
this.movePageTo(imgContainer, sibling.nextSibling, true);
|
||||
}
|
||||
}
|
||||
|
||||
moveDownButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const sibling = imgContainer.nextSibling;
|
||||
if (sibling) {
|
||||
this.movePageTo(imgContainer, sibling.nextSibling, true);
|
||||
}
|
||||
};
|
||||
rotateCCWButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const img = imgContainer.querySelector("img");
|
||||
|
||||
rotateCCWButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const img = imgContainer.querySelector("img");
|
||||
this.rotateElement(img, -90);
|
||||
}
|
||||
|
||||
this.rotateElement(img, -90)
|
||||
};
|
||||
rotateCWButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const img = imgContainer.querySelector("img");
|
||||
|
||||
rotateCWButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
const img = imgContainer.querySelector("img");
|
||||
this.rotateElement(img, 90);
|
||||
}
|
||||
|
||||
this.rotateElement(img, 90)
|
||||
};
|
||||
deletePageButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
this.pagesContainer.removeChild(imgContainer);
|
||||
if (this.pagesContainer.childElementCount === 0) {
|
||||
const filenameInput = document.getElementById("filename-input");
|
||||
const filenameParagraph = document.getElementById("filename");
|
||||
const downloadBtn = document.getElementById("export-button");
|
||||
|
||||
deletePageButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
this.pagesContainer.removeChild(imgContainer);
|
||||
if (this.pagesContainer.childElementCount === 0) {
|
||||
const filenameInput = document.getElementById('filename-input');
|
||||
const filenameParagraph = document.getElementById('filename');
|
||||
const downloadBtn = document.getElementById('export-button');
|
||||
filenameInput.disabled = true;
|
||||
filenameInput.value = "";
|
||||
filenameParagraph.innerText = "";
|
||||
|
||||
filenameInput.disabled = true;
|
||||
filenameInput.value = "";
|
||||
filenameParagraph.innerText = "";
|
||||
|
||||
downloadBtn.disabled = true;
|
||||
}
|
||||
};
|
||||
|
||||
insertFileButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
this.addPdfs(imgContainer)
|
||||
};
|
||||
|
||||
setActions({ movePageTo, addPdfs, rotateElement }) {
|
||||
this.movePageTo = movePageTo;
|
||||
this.addPdfs = addPdfs;
|
||||
this.rotateElement = rotateElement;
|
||||
|
||||
this.moveUpButtonCallback = this.moveUpButtonCallback.bind(this);
|
||||
this.moveDownButtonCallback = this.moveDownButtonCallback.bind(this);
|
||||
this.rotateCCWButtonCallback = this.rotateCCWButtonCallback.bind(this);
|
||||
this.rotateCWButtonCallback = this.rotateCWButtonCallback.bind(this);
|
||||
this.deletePageButtonCallback = this.deletePageButtonCallback.bind(this);
|
||||
this.insertFileButtonCallback = this.insertFileButtonCallback.bind(this);
|
||||
downloadBtn.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
adapt(div) {
|
||||
div.classList.add('pdf-actions_container');
|
||||
const leftDirection = this.pageDirection === 'rtl' ? 'right' : 'left'
|
||||
const rightDirection = this.pageDirection === 'rtl' ? 'left' : 'right'
|
||||
const buttonContainer = document.createElement('div');
|
||||
insertFileButtonCallback(e) {
|
||||
var imgContainer = this.getPageContainer(e.target);
|
||||
this.addPdfs(imgContainer);
|
||||
}
|
||||
|
||||
buttonContainer.classList.add("pdf-actions_button-container", "hide-on-drag");
|
||||
setActions({ movePageTo, addPdfs, rotateElement }) {
|
||||
this.movePageTo = movePageTo;
|
||||
this.addPdfs = addPdfs;
|
||||
this.rotateElement = rotateElement;
|
||||
|
||||
const moveUp = document.createElement('button');
|
||||
moveUp.classList.add("pdf-actions_move-left-button","btn", "btn-secondary");
|
||||
moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`;
|
||||
moveUp.onclick = this.moveUpButtonCallback;
|
||||
buttonContainer.appendChild(moveUp);
|
||||
this.moveUpButtonCallback = this.moveUpButtonCallback.bind(this);
|
||||
this.moveDownButtonCallback = this.moveDownButtonCallback.bind(this);
|
||||
this.rotateCCWButtonCallback = this.rotateCCWButtonCallback.bind(this);
|
||||
this.rotateCWButtonCallback = this.rotateCWButtonCallback.bind(this);
|
||||
this.deletePageButtonCallback = this.deletePageButtonCallback.bind(this);
|
||||
this.insertFileButtonCallback = this.insertFileButtonCallback.bind(this);
|
||||
}
|
||||
|
||||
const moveDown = document.createElement('button');
|
||||
moveDown.classList.add("pdf-actions_move-right-button","btn", "btn-secondary");
|
||||
moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`;
|
||||
moveDown.onclick = this.moveDownButtonCallback;
|
||||
buttonContainer.appendChild(moveDown);
|
||||
adapt(div) {
|
||||
div.classList.add("pdf-actions_container");
|
||||
const leftDirection = this.pageDirection === "rtl" ? "right" : "left";
|
||||
const rightDirection = this.pageDirection === "rtl" ? "left" : "right";
|
||||
const buttonContainer = document.createElement("div");
|
||||
|
||||
const rotateCCW = document.createElement('button');
|
||||
rotateCCW.classList.add("btn", "btn-secondary");
|
||||
rotateCCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||
buttonContainer.classList.add("pdf-actions_button-container", "hide-on-drag");
|
||||
|
||||
const moveUp = document.createElement("button");
|
||||
moveUp.classList.add("pdf-actions_move-left-button", "btn", "btn-secondary");
|
||||
moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`;
|
||||
moveUp.onclick = this.moveUpButtonCallback;
|
||||
buttonContainer.appendChild(moveUp);
|
||||
|
||||
const moveDown = document.createElement("button");
|
||||
moveDown.classList.add("pdf-actions_move-right-button", "btn", "btn-secondary");
|
||||
moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`;
|
||||
moveDown.onclick = this.moveDownButtonCallback;
|
||||
buttonContainer.appendChild(moveDown);
|
||||
|
||||
const rotateCCW = document.createElement("button");
|
||||
rotateCCW.classList.add("btn", "btn-secondary");
|
||||
rotateCCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
||||
</svg>`;
|
||||
rotateCCW.onclick = this.rotateCCWButtonCallback;
|
||||
buttonContainer.appendChild(rotateCCW);
|
||||
rotateCCW.onclick = this.rotateCCWButtonCallback;
|
||||
buttonContainer.appendChild(rotateCCW);
|
||||
|
||||
const rotateCW = document.createElement('button');
|
||||
rotateCW.classList.add("btn", "btn-secondary");
|
||||
rotateCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
const rotateCW = document.createElement("button");
|
||||
rotateCW.classList.add("btn", "btn-secondary");
|
||||
rotateCW.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
||||
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
||||
</svg>`;
|
||||
rotateCW.onclick = this.rotateCWButtonCallback;
|
||||
buttonContainer.appendChild(rotateCW);
|
||||
rotateCW.onclick = this.rotateCWButtonCallback;
|
||||
buttonContainer.appendChild(rotateCW);
|
||||
|
||||
const deletePage = document.createElement('button');
|
||||
deletePage.classList.add("btn", "btn-danger");
|
||||
deletePage.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
|
||||
const deletePage = document.createElement("button");
|
||||
deletePage.classList.add("btn", "btn-danger");
|
||||
deletePage.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/>
|
||||
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/>
|
||||
</svg>`;
|
||||
deletePage.onclick = this.deletePageButtonCallback;
|
||||
buttonContainer.appendChild(deletePage);
|
||||
deletePage.onclick = this.deletePageButtonCallback;
|
||||
buttonContainer.appendChild(deletePage);
|
||||
|
||||
div.appendChild(buttonContainer);
|
||||
div.appendChild(buttonContainer);
|
||||
|
||||
const insertFileButtonContainer = document.createElement('div');
|
||||
const insertFileButtonContainer = document.createElement("div");
|
||||
|
||||
insertFileButtonContainer.classList.add(
|
||||
"pdf-actions_insert-file-button-container",
|
||||
leftDirection,
|
||||
`align-center-${leftDirection}`);
|
||||
insertFileButtonContainer.classList.add(
|
||||
"pdf-actions_insert-file-button-container",
|
||||
leftDirection,
|
||||
`align-center-${leftDirection}`,
|
||||
);
|
||||
|
||||
const insertFileButton = document.createElement('button');
|
||||
insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
||||
insertFileButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">
|
||||
const insertFileButton = document.createElement("button");
|
||||
insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
||||
insertFileButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">
|
||||
<path d="M8 6.5a.5.5 0 0 1 .5.5v1.5H10a.5.5 0 0 1 0 1H8.5V11a.5.5 0 0 1-1 0V9.5H6a.5.5 0 0 1 0-1h1.5V7a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
|
||||
</svg>`;
|
||||
insertFileButton.onclick = this.insertFileButtonCallback;
|
||||
insertFileButtonContainer.appendChild(insertFileButton);
|
||||
insertFileButton.onclick = this.insertFileButtonCallback;
|
||||
insertFileButtonContainer.appendChild(insertFileButton);
|
||||
|
||||
div.appendChild(insertFileButtonContainer);
|
||||
div.appendChild(insertFileButtonContainer);
|
||||
|
||||
// add this button to every element, but only show it on the last one :D
|
||||
const insertFileButtonRightContainer = document.createElement('div');
|
||||
insertFileButtonRightContainer.classList.add(
|
||||
"pdf-actions_insert-file-button-container",
|
||||
rightDirection,
|
||||
`align-center-${rightDirection}`);
|
||||
// add this button to every element, but only show it on the last one :D
|
||||
const insertFileButtonRightContainer = document.createElement("div");
|
||||
insertFileButtonRightContainer.classList.add(
|
||||
"pdf-actions_insert-file-button-container",
|
||||
rightDirection,
|
||||
`align-center-${rightDirection}`,
|
||||
);
|
||||
|
||||
const insertFileButtonRight = document.createElement('button');
|
||||
insertFileButtonRight.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
||||
insertFileButtonRight.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">
|
||||
const insertFileButtonRight = document.createElement("button");
|
||||
insertFileButtonRight.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
||||
insertFileButtonRight.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-plus" viewBox="0 0 16 16">
|
||||
<path d="M8 6.5a.5.5 0 0 1 .5.5v1.5H10a.5.5 0 0 1 0 1H8.5V11a.5.5 0 0 1-1 0V9.5H6a.5.5 0 0 1 0-1h1.5V7a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
|
||||
insertFileButtonRight</svg>`;
|
||||
insertFileButtonRight.onclick = () => addPdfs();
|
||||
insertFileButtonRightContainer.appendChild(insertFileButtonRight);
|
||||
insertFileButtonRight.onclick = () => addPdfs();
|
||||
insertFileButtonRightContainer.appendChild(insertFileButtonRight);
|
||||
|
||||
div.appendChild(insertFileButtonRightContainer);
|
||||
div.appendChild(insertFileButtonRightContainer);
|
||||
|
||||
const adaptPageNumber = (pageNumber, div) => {
|
||||
const pageNumberElement = document.createElement('span');
|
||||
pageNumberElement.classList.add('page-number');
|
||||
pageNumberElement.textContent = pageNumber;
|
||||
const adaptPageNumber = (pageNumber, div) => {
|
||||
const pageNumberElement = document.createElement("span");
|
||||
pageNumberElement.classList.add("page-number");
|
||||
pageNumberElement.textContent = pageNumber;
|
||||
|
||||
div.insertBefore(pageNumberElement, div.firstChild);
|
||||
};
|
||||
div.insertBefore(pageNumberElement, div.firstChild);
|
||||
};
|
||||
|
||||
div.addEventListener('mouseenter', () => {
|
||||
const pageNumber = Array.from(div.parentNode.children).indexOf(div) + 1;
|
||||
adaptPageNumber(pageNumber, div);
|
||||
});
|
||||
div.addEventListener("mouseenter", () => {
|
||||
const pageNumber = Array.from(div.parentNode.children).indexOf(div) + 1;
|
||||
adaptPageNumber(pageNumber, div);
|
||||
});
|
||||
|
||||
div.addEventListener('mouseleave', () => {
|
||||
const pageNumberElement = div.querySelector('.page-number');
|
||||
if (pageNumberElement) {
|
||||
div.removeChild(pageNumberElement);
|
||||
}
|
||||
});
|
||||
div.addEventListener("mouseleave", () => {
|
||||
const pageNumberElement = div.querySelector(".page-number");
|
||||
if (pageNumberElement) {
|
||||
div.removeChild(pageNumberElement);
|
||||
}
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
return div;
|
||||
}
|
||||
}
|
||||
|
||||
export default PdfActionsManager;
|
||||
export default PdfActionsManager;
|
||||
|
||||
@@ -1,285 +1,282 @@
|
||||
class PdfContainer {
|
||||
fileName;
|
||||
pagesContainer;
|
||||
pagesContainerWrapper;
|
||||
pdfAdapters;
|
||||
downloadLink;
|
||||
fileName;
|
||||
pagesContainer;
|
||||
pagesContainerWrapper;
|
||||
pdfAdapters;
|
||||
downloadLink;
|
||||
|
||||
constructor(id, wrapperId, pdfAdapters) {
|
||||
this.pagesContainer = document.getElementById(id)
|
||||
this.pagesContainerWrapper = document.getElementById(wrapperId);
|
||||
this.downloadLink = null;
|
||||
this.movePageTo = this.movePageTo.bind(this);
|
||||
this.addPdfs = this.addPdfs.bind(this);
|
||||
this.addPdfsFromFiles = this.addPdfsFromFiles.bind(this);
|
||||
this.rotateElement = this.rotateElement.bind(this);
|
||||
this.rotateAll = this.rotateAll.bind(this);
|
||||
this.exportPdf = this.exportPdf.bind(this);
|
||||
this.updateFilename = this.updateFilename.bind(this);
|
||||
this.setDownloadAttribute = this.setDownloadAttribute.bind(this);
|
||||
this.preventIllegalChars = this.preventIllegalChars.bind(this);
|
||||
constructor(id, wrapperId, pdfAdapters) {
|
||||
this.pagesContainer = document.getElementById(id);
|
||||
this.pagesContainerWrapper = document.getElementById(wrapperId);
|
||||
this.downloadLink = null;
|
||||
this.movePageTo = this.movePageTo.bind(this);
|
||||
this.addPdfs = this.addPdfs.bind(this);
|
||||
this.addPdfsFromFiles = this.addPdfsFromFiles.bind(this);
|
||||
this.rotateElement = this.rotateElement.bind(this);
|
||||
this.rotateAll = this.rotateAll.bind(this);
|
||||
this.exportPdf = this.exportPdf.bind(this);
|
||||
this.updateFilename = this.updateFilename.bind(this);
|
||||
this.setDownloadAttribute = this.setDownloadAttribute.bind(this);
|
||||
this.preventIllegalChars = this.preventIllegalChars.bind(this);
|
||||
|
||||
this.pdfAdapters = pdfAdapters;
|
||||
this.pdfAdapters = pdfAdapters;
|
||||
|
||||
this.pdfAdapters.forEach(adapter => {
|
||||
adapter.setActions({
|
||||
movePageTo: this.movePageTo,
|
||||
addPdfs: this.addPdfs,
|
||||
rotateElement: this.rotateElement,
|
||||
updateFilename: this.updateFilename
|
||||
})
|
||||
})
|
||||
this.pdfAdapters.forEach((adapter) => {
|
||||
adapter.setActions({
|
||||
movePageTo: this.movePageTo,
|
||||
addPdfs: this.addPdfs,
|
||||
rotateElement: this.rotateElement,
|
||||
updateFilename: this.updateFilename,
|
||||
});
|
||||
});
|
||||
|
||||
window.addPdfs = this.addPdfs;
|
||||
window.exportPdf = this.exportPdf;
|
||||
window.rotateAll = this.rotateAll;
|
||||
window.addPdfs = this.addPdfs;
|
||||
window.exportPdf = this.exportPdf;
|
||||
window.rotateAll = this.rotateAll;
|
||||
|
||||
const filenameInput = document.getElementById('filename-input');
|
||||
const downloadBtn = document.getElementById('export-button');
|
||||
const filenameInput = document.getElementById("filename-input");
|
||||
const downloadBtn = document.getElementById("export-button");
|
||||
|
||||
filenameInput.onkeyup = this.updateFilename;
|
||||
filenameInput.onkeydown = this.preventIllegalChars;
|
||||
filenameInput.disabled = false;
|
||||
filenameInput.innerText = "";
|
||||
downloadBtn.disabled = true;
|
||||
filenameInput.onkeyup = this.updateFilename;
|
||||
filenameInput.onkeydown = this.preventIllegalChars;
|
||||
filenameInput.disabled = false;
|
||||
filenameInput.innerText = "";
|
||||
downloadBtn.disabled = true;
|
||||
}
|
||||
|
||||
movePageTo(startElement, endElement, scrollTo = false) {
|
||||
const childArray = Array.from(this.pagesContainer.childNodes);
|
||||
const startIndex = childArray.indexOf(startElement);
|
||||
const endIndex = childArray.indexOf(endElement);
|
||||
this.pagesContainer.removeChild(startElement);
|
||||
if (!endElement) {
|
||||
this.pagesContainer.append(startElement);
|
||||
} else {
|
||||
this.pagesContainer.insertBefore(startElement, endElement);
|
||||
}
|
||||
|
||||
movePageTo(startElement, endElement, scrollTo = false) {
|
||||
const childArray = Array.from(this.pagesContainer.childNodes);
|
||||
const startIndex = childArray.indexOf(startElement);
|
||||
const endIndex = childArray.indexOf(endElement);
|
||||
this.pagesContainer.removeChild(startElement);
|
||||
if(!endElement) {
|
||||
this.pagesContainer.append(startElement);
|
||||
if (scrollTo) {
|
||||
const { width } = startElement.getBoundingClientRect();
|
||||
const vector = endIndex !== -1 && startIndex > endIndex ? 0 - width : width;
|
||||
|
||||
this.pagesContainerWrapper.scroll({
|
||||
left: this.pagesContainerWrapper.scrollLeft + vector,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addPdfs(nextSiblingElement) {
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.multiple = true;
|
||||
input.setAttribute("accept", "application/pdf");
|
||||
input.onchange = async (e) => {
|
||||
const files = e.target.files;
|
||||
|
||||
this.addPdfsFromFiles(files, nextSiblingElement);
|
||||
this.updateFilename(files ? files[0].name : "");
|
||||
};
|
||||
|
||||
input.click();
|
||||
}
|
||||
|
||||
async addPdfsFromFiles(files, nextSiblingElement) {
|
||||
this.fileName = files[0].name;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
await this.addPdfFile(files[i], nextSiblingElement);
|
||||
}
|
||||
|
||||
document.querySelectorAll(".enable-on-file").forEach((element) => {
|
||||
element.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
rotateElement(element, deg) {
|
||||
var lastTransform = element.style.rotate;
|
||||
if (!lastTransform) {
|
||||
lastTransform = "0";
|
||||
}
|
||||
const lastAngle = parseInt(lastTransform.replace(/[^\d-]/g, ""));
|
||||
const newAngle = lastAngle + deg;
|
||||
|
||||
element.style.rotate = newAngle + "deg";
|
||||
}
|
||||
|
||||
async addPdfFile(file, nextSiblingElement) {
|
||||
const { renderer, pdfDocument } = await this.loadFile(file);
|
||||
|
||||
for (var i = 0; i < renderer.pageCount; i++) {
|
||||
const div = document.createElement("div");
|
||||
|
||||
div.classList.add("page-container");
|
||||
|
||||
var img = document.createElement("img");
|
||||
img.classList.add("page-image");
|
||||
const imageSrc = await renderer.renderPage(i);
|
||||
img.src = imageSrc;
|
||||
img.pageIdx = i;
|
||||
img.rend = renderer;
|
||||
img.doc = pdfDocument;
|
||||
div.appendChild(img);
|
||||
|
||||
this.pdfAdapters.forEach((adapter) => {
|
||||
adapter.adapt?.(div);
|
||||
});
|
||||
if (nextSiblingElement) {
|
||||
this.pagesContainer.insertBefore(div, nextSiblingElement);
|
||||
} else {
|
||||
this.pagesContainer.appendChild(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async loadFile(file) {
|
||||
var objectUrl = URL.createObjectURL(file);
|
||||
var pdfDocument = await this.toPdfLib(objectUrl);
|
||||
var renderer = await this.toRenderer(objectUrl);
|
||||
return { renderer, pdfDocument };
|
||||
}
|
||||
|
||||
async toRenderer(objectUrl) {
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs/pdf.worker.js";
|
||||
const pdf = await pdfjsLib.getDocument(objectUrl).promise;
|
||||
return {
|
||||
document: pdf,
|
||||
pageCount: pdf.numPages,
|
||||
renderPage: async function (pageIdx) {
|
||||
const page = await this.document.getPage(pageIdx + 1);
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
canvas.width = page.view[3];
|
||||
canvas.height = page.view[2];
|
||||
} else {
|
||||
this.pagesContainer.insertBefore(startElement, endElement);
|
||||
canvas.width = page.view[2];
|
||||
canvas.height = page.view[3];
|
||||
}
|
||||
|
||||
if(scrollTo) {
|
||||
const { width } = startElement.getBoundingClientRect();
|
||||
const vector = (endIndex !== -1 && startIndex > endIndex)
|
||||
? 0-width
|
||||
: width;
|
||||
|
||||
this.pagesContainerWrapper.scroll({
|
||||
left: this.pagesContainerWrapper.scrollLeft + vector,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
addPdfs(nextSiblingElement) {
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.multiple = true;
|
||||
input.setAttribute("accept", "application/pdf");
|
||||
input.onchange = async(e) => {
|
||||
const files = e.target.files;
|
||||
|
||||
this.addPdfsFromFiles(files, nextSiblingElement);
|
||||
this.updateFilename(files ? files[0].name : "");
|
||||
}
|
||||
|
||||
input.click();
|
||||
}
|
||||
|
||||
async addPdfsFromFiles(files, nextSiblingElement) {
|
||||
this.fileName = files[0].name;
|
||||
for (var i=0; i < files.length; i++) {
|
||||
await this.addPdfFile(files[i], nextSiblingElement);
|
||||
}
|
||||
|
||||
document.querySelectorAll(".enable-on-file").forEach(element => {
|
||||
element.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
rotateElement(element, deg) {
|
||||
var lastTransform = element.style.rotate;
|
||||
if (!lastTransform) {
|
||||
lastTransform = "0";
|
||||
}
|
||||
const lastAngle = parseInt(lastTransform.replace(/[^\d-]/g, ''));
|
||||
const newAngle = lastAngle + deg;
|
||||
|
||||
element.style.rotate = newAngle + "deg";
|
||||
}
|
||||
|
||||
async addPdfFile(file, nextSiblingElement) {
|
||||
const { renderer, pdfDocument } = await this.loadFile(file);
|
||||
|
||||
for (var i=0; i < renderer.pageCount; i++) {
|
||||
const div = document.createElement('div');
|
||||
|
||||
div.classList.add("page-container");
|
||||
|
||||
var img = document.createElement('img');
|
||||
img.classList.add('page-image')
|
||||
const imageSrc = await renderer.renderPage(i)
|
||||
img.src = imageSrc;
|
||||
img.pageIdx = i;
|
||||
img.rend = renderer;
|
||||
img.doc = pdfDocument;
|
||||
div.appendChild(img);
|
||||
|
||||
this.pdfAdapters.forEach((adapter) => {
|
||||
adapter.adapt?.(div)
|
||||
})
|
||||
if (nextSiblingElement) {
|
||||
this.pagesContainer.insertBefore(div, nextSiblingElement);
|
||||
} else {
|
||||
this.pagesContainer.appendChild(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async loadFile(file) {
|
||||
var objectUrl = URL.createObjectURL(file);
|
||||
var pdfDocument = await this.toPdfLib(objectUrl);
|
||||
var renderer = await this.toRenderer(objectUrl);
|
||||
return { renderer, pdfDocument };
|
||||
}
|
||||
|
||||
async toRenderer(objectUrl) {
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs/pdf.worker.js'
|
||||
const pdf = await pdfjsLib.getDocument(objectUrl).promise;
|
||||
return {
|
||||
document: pdf,
|
||||
pageCount: pdf.numPages,
|
||||
renderPage: async function(pageIdx) {
|
||||
const page = await this.document.getPage(pageIdx+1);
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
canvas.width = page.view[3];
|
||||
canvas.height = page.view[2];
|
||||
} else {
|
||||
canvas.width = page.view[2];
|
||||
canvas.height = page.view[3];
|
||||
}
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: canvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 })
|
||||
};
|
||||
|
||||
await page.render(renderContext).promise;
|
||||
return canvas.toDataURL();
|
||||
}
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: canvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 }),
|
||||
};
|
||||
|
||||
await page.render(renderContext).promise;
|
||||
return canvas.toDataURL();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async toPdfLib(objectUrl) {
|
||||
const existingPdfBytes = await fetch(objectUrl).then((res) => res.arrayBuffer());
|
||||
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes, {
|
||||
ignoreEncryption: true,
|
||||
});
|
||||
return pdfDoc;
|
||||
}
|
||||
|
||||
rotateAll(deg) {
|
||||
for (var i = 0; i < this.pagesContainer.childNodes.length; i++) {
|
||||
const img = this.pagesContainer.childNodes[i].querySelector("img");
|
||||
if (!img) continue;
|
||||
this.rotateElement(img, deg);
|
||||
}
|
||||
}
|
||||
|
||||
async exportPdf() {
|
||||
const pdfDoc = await PDFLib.PDFDocument.create();
|
||||
const pageContainers = this.pagesContainer.querySelectorAll(".page-container"); // Select all .page-container elements
|
||||
for (var i = 0; i < pageContainers.length; i++) {
|
||||
const img = pageContainers[i].querySelector("img"); // Find the img element within each .page-container
|
||||
if (!img) continue;
|
||||
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx]);
|
||||
const page = pages[0];
|
||||
|
||||
const rotation = img.style.rotate;
|
||||
if (rotation) {
|
||||
const rotationAngle = parseInt(rotation.replace(/[^\d-]/g, ""));
|
||||
page.setRotation(PDFLib.degrees(page.getRotation().angle + rotationAngle));
|
||||
}
|
||||
|
||||
pdfDoc.addPage(page);
|
||||
}
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
const pdfBlob = new Blob([pdfBytes], { type: "application/pdf" });
|
||||
const url = URL.createObjectURL(pdfBlob);
|
||||
const downloadOption = localStorage.getItem("downloadOption");
|
||||
|
||||
const filenameInput = document.getElementById("filename-input");
|
||||
|
||||
let inputArr = filenameInput.value.split(".");
|
||||
|
||||
if (inputArr !== null && inputArr !== undefined && inputArr.length > 0) {
|
||||
inputArr = inputArr.filter((n) => n); // remove all empty strings, nulls or undefined
|
||||
|
||||
if (inputArr.length > 1) {
|
||||
inputArr.pop(); // remove right part after last dot
|
||||
}
|
||||
|
||||
filenameInput.value = inputArr.join("");
|
||||
this.fileName = filenameInput.value;
|
||||
}
|
||||
|
||||
async toPdfLib(objectUrl) {
|
||||
const existingPdfBytes = await fetch(objectUrl).then(res => res.arrayBuffer());
|
||||
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes, { ignoreEncryption: true });
|
||||
return pdfDoc;
|
||||
if (!filenameInput.value.includes(".pdf")) {
|
||||
filenameInput.value = filenameInput.value + ".pdf";
|
||||
this.fileName = filenameInput.value;
|
||||
}
|
||||
|
||||
if (downloadOption === "sameWindow") {
|
||||
// Open the file in the same window
|
||||
window.location.href = url;
|
||||
} else if (downloadOption === "newWindow") {
|
||||
// Open the file in a new window
|
||||
window.open(url, "_blank");
|
||||
} else {
|
||||
// Download the file
|
||||
this.downloadLink = document.createElement("a");
|
||||
this.downloadLink.id = "download-link";
|
||||
this.downloadLink.href = url;
|
||||
// downloadLink.download = this.fileName ? this.fileName : 'managed.pdf';
|
||||
// downloadLink.download = this.fileName;
|
||||
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : "managed.pdf");
|
||||
this.downloadLink.setAttribute("target", "_blank");
|
||||
this.downloadLink.onclick = this.setDownloadAttribute;
|
||||
this.downloadLink.click();
|
||||
}
|
||||
}
|
||||
|
||||
setDownloadAttribute() {
|
||||
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : "managed.pdf");
|
||||
}
|
||||
|
||||
rotateAll(deg) {
|
||||
for (var i=0; i<this.pagesContainer.childNodes.length; i++) {
|
||||
const img = this.pagesContainer.childNodes[i].querySelector("img");
|
||||
if (!img) continue;
|
||||
this.rotateElement(img, deg)
|
||||
}
|
||||
updateFilename(fileName = "") {
|
||||
const filenameInput = document.getElementById("filename-input");
|
||||
const pagesContainer = document.getElementById("pages-container");
|
||||
const downloadBtn = document.getElementById("export-button");
|
||||
|
||||
downloadBtn.disabled = pagesContainer.childElementCount === 0;
|
||||
|
||||
if (!this.fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
async exportPdf() {
|
||||
const pdfDoc = await PDFLib.PDFDocument.create();
|
||||
const pageContainers = this.pagesContainer.querySelectorAll('.page-container'); // Select all .page-container elements
|
||||
for (var i = 0; i < pageContainers.length; i++) {
|
||||
const img = pageContainers[i].querySelector("img"); // Find the img element within each .page-container
|
||||
if (!img) continue;
|
||||
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx])
|
||||
const page = pages[0];
|
||||
|
||||
const rotation = img.style.rotate;
|
||||
if (rotation) {
|
||||
const rotationAngle = parseInt(rotation.replace(/[^\d-]/g, ''));
|
||||
page.setRotation(PDFLib.degrees(page.getRotation().angle + rotationAngle))
|
||||
}
|
||||
|
||||
pdfDoc.addPage(page);
|
||||
}
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
|
||||
const url = URL.createObjectURL(pdfBlob);
|
||||
const downloadOption = localStorage.getItem('downloadOption');
|
||||
|
||||
const filenameInput = document.getElementById('filename-input');
|
||||
|
||||
let inputArr = filenameInput.value.split('.');
|
||||
|
||||
if (inputArr !== null && inputArr !== undefined && inputArr.length > 0) {
|
||||
|
||||
inputArr = inputArr.filter(n => n); // remove all empty strings, nulls or undefined
|
||||
|
||||
if (inputArr.length > 1) {
|
||||
inputArr.pop(); // remove right part after last dot
|
||||
}
|
||||
|
||||
filenameInput.value = inputArr.join('');
|
||||
this.fileName = filenameInput.value;
|
||||
}
|
||||
|
||||
if (!filenameInput.value.includes('.pdf')) {
|
||||
filenameInput.value = filenameInput.value + '.pdf';
|
||||
this.fileName = filenameInput.value;
|
||||
}
|
||||
|
||||
if (downloadOption === 'sameWindow') {
|
||||
// Open the file in the same window
|
||||
window.location.href = url;
|
||||
} else if (downloadOption === 'newWindow') {
|
||||
// Open the file in a new window
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
// Download the file
|
||||
this.downloadLink = document.createElement('a');
|
||||
this.downloadLink.id = 'download-link';
|
||||
this.downloadLink.href = url;
|
||||
// downloadLink.download = this.fileName ? this.fileName : 'managed.pdf';
|
||||
// downloadLink.download = this.fileName;
|
||||
this.downloadLink.setAttribute('download', this.fileName ? this.fileName : 'managed.pdf');
|
||||
this.downloadLink.setAttribute('target', '_blank');
|
||||
this.downloadLink.onclick = this.setDownloadAttribute;
|
||||
this.downloadLink.click();
|
||||
}
|
||||
if (!filenameInput.value) {
|
||||
filenameInput.value = this.fileName;
|
||||
}
|
||||
}
|
||||
|
||||
setDownloadAttribute() {
|
||||
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : 'managed.pdf');
|
||||
}
|
||||
|
||||
updateFilename(fileName = "") {
|
||||
const filenameInput = document.getElementById('filename-input');
|
||||
const pagesContainer = document.getElementById('pages-container');
|
||||
const downloadBtn = document.getElementById('export-button');
|
||||
|
||||
downloadBtn.disabled = pagesContainer.childElementCount === 0
|
||||
|
||||
if (!this.fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
if (!filenameInput.value) {
|
||||
filenameInput.value = this.fileName;
|
||||
}
|
||||
}
|
||||
|
||||
preventIllegalChars(e) {
|
||||
// const filenameInput = document.getElementById('filename-input');
|
||||
//
|
||||
// filenameInput.value = filenameInput.value.replace('.pdf', '');
|
||||
//
|
||||
// // prevent .
|
||||
// if (filenameInput.value.includes('.')) {
|
||||
// filenameInput.value.replace('.','');
|
||||
// }
|
||||
}
|
||||
preventIllegalChars(e) {
|
||||
// const filenameInput = document.getElementById('filename-input');
|
||||
//
|
||||
// filenameInput.value = filenameInput.value.replace('.pdf', '');
|
||||
//
|
||||
// // prevent .
|
||||
// if (filenameInput.value.includes('.')) {
|
||||
// filenameInput.value.replace('.','');
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
export default PdfContainer;
|
||||
|
||||
@@ -1,94 +1,95 @@
|
||||
class FileDragManager {
|
||||
overlay;
|
||||
dragCounter;
|
||||
updateFilename;
|
||||
overlay;
|
||||
dragCounter;
|
||||
updateFilename;
|
||||
|
||||
constructor(cb = null) {
|
||||
this.dragCounter = 0;
|
||||
this.setCallback(cb);
|
||||
constructor(cb = null) {
|
||||
this.dragCounter = 0;
|
||||
this.setCallback(cb);
|
||||
|
||||
// Prevent default behavior for drag events
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
// Prevent default behavior for drag events
|
||||
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
this.dragenterListener = this.dragenterListener.bind(this);
|
||||
this.dragleaveListener = this.dragleaveListener.bind(this);
|
||||
this.dropListener = this.dropListener.bind(this);
|
||||
|
||||
document.body.addEventListener('dragenter', this.dragenterListener);
|
||||
document.body.addEventListener('dragleave', this.dragleaveListener);
|
||||
// Add drop event listener
|
||||
document.body.addEventListener('drop', this.dropListener);
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
setActions({ updateFilename }) {
|
||||
this.updateFilename = updateFilename;
|
||||
this.dragenterListener = this.dragenterListener.bind(this);
|
||||
this.dragleaveListener = this.dragleaveListener.bind(this);
|
||||
this.dropListener = this.dropListener.bind(this);
|
||||
|
||||
document.body.addEventListener("dragenter", this.dragenterListener);
|
||||
document.body.addEventListener("dragleave", this.dragleaveListener);
|
||||
// Add drop event listener
|
||||
document.body.addEventListener("drop", this.dropListener);
|
||||
}
|
||||
|
||||
setActions({ updateFilename }) {
|
||||
this.updateFilename = updateFilename;
|
||||
}
|
||||
|
||||
setCallback(cb) {
|
||||
if (cb) {
|
||||
this.callback = cb;
|
||||
} else {
|
||||
this.callback = (files) => console.warn("FileDragManager not set");
|
||||
}
|
||||
}
|
||||
|
||||
setCallback(cb) {
|
||||
if (cb) {
|
||||
this.callback = cb;
|
||||
} else {
|
||||
this.callback = (files) => console.warn("FileDragManager not set");
|
||||
}
|
||||
dragenterListener() {
|
||||
this.dragCounter++;
|
||||
if (!this.overlay) {
|
||||
// Create and show the overlay
|
||||
this.overlay = document.createElement("div");
|
||||
this.overlay.style.position = "fixed";
|
||||
this.overlay.style.top = 0;
|
||||
this.overlay.style.left = 0;
|
||||
this.overlay.style.width = "100%";
|
||||
this.overlay.style.height = "100%";
|
||||
this.overlay.style.background = "rgba(0, 0, 0, 0.5)";
|
||||
this.overlay.style.color = "#fff";
|
||||
this.overlay.style.zIndex = "1000";
|
||||
this.overlay.style.display = "flex";
|
||||
this.overlay.style.alignItems = "center";
|
||||
this.overlay.style.justifyContent = "center";
|
||||
this.overlay.style.pointerEvents = "none";
|
||||
this.overlay.innerHTML = "<p>Drop files anywhere to upload</p>";
|
||||
document.getElementById("content-wrap").appendChild(this.overlay);
|
||||
}
|
||||
}
|
||||
|
||||
dragenterListener() {
|
||||
this.dragCounter++;
|
||||
if (!this.overlay) {
|
||||
// Create and show the overlay
|
||||
this.overlay = document.createElement('div');
|
||||
this.overlay.style.position = 'fixed';
|
||||
this.overlay.style.top = 0;
|
||||
this.overlay.style.left = 0;
|
||||
this.overlay.style.width = '100%';
|
||||
this.overlay.style.height = '100%';
|
||||
this.overlay.style.background = 'rgba(0, 0, 0, 0.5)';
|
||||
this.overlay.style.color = '#fff';
|
||||
this.overlay.style.zIndex = '1000';
|
||||
this.overlay.style.display = 'flex';
|
||||
this.overlay.style.alignItems = 'center';
|
||||
this.overlay.style.justifyContent = 'center';
|
||||
this.overlay.style.pointerEvents = 'none';
|
||||
this.overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
|
||||
document.getElementById('content-wrap').appendChild(this.overlay);
|
||||
dragleaveListener() {
|
||||
this.dragCounter--;
|
||||
if (this.dragCounter === 0) {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropListener(e) {
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
this.callback(files)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
//maybe
|
||||
})
|
||||
.finally(() => {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
};
|
||||
|
||||
dragleaveListener() {
|
||||
this.dragCounter--;
|
||||
if (this.dragCounter === 0) {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dropListener(e) {
|
||||
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
this.callback(files).catch((err) => {
|
||||
console.error(err);
|
||||
//maybe
|
||||
}).finally(() => {
|
||||
// Hide and remove the overlay
|
||||
if (this.overlay) {
|
||||
this.overlay.remove();
|
||||
this.overlay = null;
|
||||
}
|
||||
|
||||
this.updateFilename(files ? files[0].name : "");
|
||||
});
|
||||
};
|
||||
this.updateFilename(files ? files[0].name : "");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default FileDragManager;
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
const scrollDivHorizontally = (id) => {
|
||||
var scrollDelta = 0; // variable to store the accumulated scroll delta
|
||||
var isScrolling = false; // variable to track if scroll is already in progress
|
||||
const divToScrollHorizontally = document.getElementById(id)
|
||||
function scrollLoop() {
|
||||
// Scroll the div horizontally by a fraction of the accumulated scroll delta
|
||||
divToScrollHorizontally.scrollLeft += scrollDelta * 0.1;
|
||||
var scrollDelta = 0; // variable to store the accumulated scroll delta
|
||||
var isScrolling = false; // variable to track if scroll is already in progress
|
||||
const divToScrollHorizontally = document.getElementById(id);
|
||||
function scrollLoop() {
|
||||
// Scroll the div horizontally by a fraction of the accumulated scroll delta
|
||||
divToScrollHorizontally.scrollLeft += scrollDelta * 0.1;
|
||||
|
||||
// Reduce the accumulated scroll delta by a fraction
|
||||
scrollDelta *= 0.9;
|
||||
// Reduce the accumulated scroll delta by a fraction
|
||||
scrollDelta *= 0.9;
|
||||
|
||||
// If scroll delta is still significant, continue the scroll loop
|
||||
if (Math.abs(scrollDelta) > 0.1) {
|
||||
requestAnimationFrame(scrollLoop);
|
||||
} else {
|
||||
isScrolling = false; // Reset scroll in progress flag
|
||||
}
|
||||
// If scroll delta is still significant, continue the scroll loop
|
||||
if (Math.abs(scrollDelta) > 0.1) {
|
||||
requestAnimationFrame(scrollLoop);
|
||||
} else {
|
||||
isScrolling = false; // Reset scroll in progress flag
|
||||
}
|
||||
}
|
||||
|
||||
divToScrollHorizontally.addEventListener("wheel", function (e) {
|
||||
e.preventDefault(); // prevent default mousewheel behavior
|
||||
|
||||
divToScrollHorizontally.addEventListener("wheel", function(e) {
|
||||
e.preventDefault(); // prevent default mousewheel behavior
|
||||
// Accumulate the horizontal scroll delta
|
||||
scrollDelta -= e.deltaX || e.wheelDeltaX || -e.deltaY || -e.wheelDeltaY;
|
||||
|
||||
// Accumulate the horizontal scroll delta
|
||||
scrollDelta -= e.deltaX || e.wheelDeltaX || -e.deltaY || -e.wheelDeltaY;
|
||||
|
||||
// If scroll is not already in progress, start the scroll loop
|
||||
if (!isScrolling) {
|
||||
isScrolling = true;
|
||||
requestAnimationFrame(scrollLoop);
|
||||
}
|
||||
});
|
||||
}
|
||||
// If scroll is not already in progress, start the scroll loop
|
||||
if (!isScrolling) {
|
||||
isScrolling = true;
|
||||
requestAnimationFrame(scrollLoop);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default scrollDivHorizontally;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +1,76 @@
|
||||
// Toggle search bar when the search icon is clicked
|
||||
document.querySelector('#search-icon').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
var searchBar = document.querySelector('#navbarSearch');
|
||||
searchBar.classList.toggle('show');
|
||||
document.querySelector("#search-icon").addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
var searchBar = document.querySelector("#navbarSearch");
|
||||
searchBar.classList.toggle("show");
|
||||
});
|
||||
window.onload = function() {
|
||||
var items = document.querySelectorAll('.dropdown-item, .nav-link');
|
||||
var dummyContainer = document.createElement('div');
|
||||
dummyContainer.style.position = 'absolute';
|
||||
dummyContainer.style.visibility = 'hidden';
|
||||
dummyContainer.style.whiteSpace = 'nowrap'; // Ensure we measure full width
|
||||
document.body.appendChild(dummyContainer);
|
||||
window.onload = function () {
|
||||
var items = document.querySelectorAll(".dropdown-item, .nav-link");
|
||||
var dummyContainer = document.createElement("div");
|
||||
dummyContainer.style.position = "absolute";
|
||||
dummyContainer.style.visibility = "hidden";
|
||||
dummyContainer.style.whiteSpace = "nowrap"; // Ensure we measure full width
|
||||
document.body.appendChild(dummyContainer);
|
||||
|
||||
var maxWidth = 0;
|
||||
var maxWidth = 0;
|
||||
|
||||
items.forEach(function(item) {
|
||||
var clone = item.cloneNode(true);
|
||||
dummyContainer.appendChild(clone);
|
||||
var width = clone.offsetWidth;
|
||||
if (width > maxWidth) {
|
||||
maxWidth = width;
|
||||
}
|
||||
dummyContainer.removeChild(clone);
|
||||
});
|
||||
items.forEach(function (item) {
|
||||
var clone = item.cloneNode(true);
|
||||
dummyContainer.appendChild(clone);
|
||||
var width = clone.offsetWidth;
|
||||
if (width > maxWidth) {
|
||||
maxWidth = width;
|
||||
}
|
||||
dummyContainer.removeChild(clone);
|
||||
});
|
||||
|
||||
document.body.removeChild(dummyContainer);
|
||||
document.body.removeChild(dummyContainer);
|
||||
|
||||
// Store max width for later use
|
||||
window.navItemMaxWidth = maxWidth;
|
||||
// Store max width for later use
|
||||
window.navItemMaxWidth = maxWidth;
|
||||
};
|
||||
|
||||
// Show search results as user types in search box
|
||||
document.querySelector('#navbarSearchInput').addEventListener('input', function(e) {
|
||||
var searchText = e.target.value.toLowerCase();
|
||||
var items = document.querySelectorAll('.dropdown-item, .nav-link');
|
||||
var resultsBox = document.querySelector('#searchResults');
|
||||
document.querySelector("#navbarSearchInput").addEventListener("input", function (e) {
|
||||
var searchText = e.target.value.toLowerCase();
|
||||
var items = document.querySelectorAll(".dropdown-item, .nav-link");
|
||||
var resultsBox = document.querySelector("#searchResults");
|
||||
|
||||
// Clear any previous results
|
||||
resultsBox.innerHTML = '';
|
||||
// Clear any previous results
|
||||
resultsBox.innerHTML = "";
|
||||
|
||||
items.forEach(function(item) {
|
||||
var titleElement = item.querySelector('.icon-text');
|
||||
var iconElement = item.querySelector('.icon');
|
||||
var itemHref = item.getAttribute('href');
|
||||
var tags = item.getAttribute('data-bs-tags') || ""; // If no tags, default to empty string
|
||||
items.forEach(function (item) {
|
||||
var titleElement = item.querySelector(".icon-text");
|
||||
var iconElement = item.querySelector(".icon");
|
||||
var itemHref = item.getAttribute("href");
|
||||
var tags = item.getAttribute("data-bs-tags") || ""; // If no tags, default to empty string
|
||||
|
||||
if (titleElement && iconElement && itemHref !== '#') {
|
||||
var title = titleElement.innerText;
|
||||
if ((title.toLowerCase().indexOf(searchText) !== -1 || tags.toLowerCase().indexOf(searchText) !== -1) && !resultsBox.querySelector(`a[href="${item.getAttribute('href')}"]`)) {
|
||||
var result = document.createElement('a');
|
||||
result.href = itemHref;
|
||||
result.classList.add('dropdown-item');
|
||||
if (titleElement && iconElement && itemHref !== "#") {
|
||||
var title = titleElement.innerText;
|
||||
if (
|
||||
(title.toLowerCase().indexOf(searchText) !== -1 || tags.toLowerCase().indexOf(searchText) !== -1) &&
|
||||
!resultsBox.querySelector(`a[href="${item.getAttribute("href")}"]`)
|
||||
) {
|
||||
var result = document.createElement("a");
|
||||
result.href = itemHref;
|
||||
result.classList.add("dropdown-item");
|
||||
|
||||
var resultIcon = document.createElement('img');
|
||||
resultIcon.src = iconElement.src;
|
||||
resultIcon.alt = 'icon';
|
||||
resultIcon.classList.add('icon');
|
||||
result.appendChild(resultIcon);
|
||||
var resultIcon = document.createElement("img");
|
||||
resultIcon.src = iconElement.src;
|
||||
resultIcon.alt = "icon";
|
||||
resultIcon.classList.add("icon");
|
||||
result.appendChild(resultIcon);
|
||||
|
||||
var resultText = document.createElement('span');
|
||||
resultText.textContent = title;
|
||||
resultText.classList.add('icon-text');
|
||||
result.appendChild(resultText);
|
||||
var resultText = document.createElement("span");
|
||||
resultText.textContent = title;
|
||||
resultText.classList.add("icon-text");
|
||||
result.appendChild(resultText);
|
||||
|
||||
resultsBox.appendChild(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
resultsBox.appendChild(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set the width of the search results box to the maximum width
|
||||
resultsBox.style.width = window.navItemMaxWidth + 'px';
|
||||
// Set the width of the search results box to the maximum width
|
||||
resultsBox.style.width = window.navItemMaxWidth + "px";
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +1,33 @@
|
||||
// Get the download option from local storage, or set it to 'sameWindow' if it doesn't exist
|
||||
var downloadOption = localStorage.getItem('downloadOption')
|
||||
|| 'sameWindow';
|
||||
var downloadOption = localStorage.getItem("downloadOption") || "sameWindow";
|
||||
|
||||
// Set the selected option in the dropdown
|
||||
document.getElementById('downloadOption').value = downloadOption;
|
||||
|
||||
document.getElementById("downloadOption").value = downloadOption;
|
||||
|
||||
// Save the selected option to local storage when the dropdown value changes
|
||||
document.getElementById('downloadOption').addEventListener(
|
||||
'change',
|
||||
function() {
|
||||
downloadOption = this.value;
|
||||
localStorage.setItem('downloadOption',
|
||||
downloadOption);
|
||||
});
|
||||
|
||||
|
||||
// Get the zipThreshold value from local storage, or set it to 0 if it doesn't exist
|
||||
var zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||
|
||||
// Set the value of the slider and the display span
|
||||
document.getElementById('zipThreshold').value = zipThreshold;
|
||||
document.getElementById('zipThresholdValue').textContent = zipThreshold;
|
||||
|
||||
|
||||
|
||||
// Save the selected value to local storage when the slider value changes
|
||||
document.getElementById('zipThreshold').addEventListener('input', function() {
|
||||
zipThreshold = this.value;
|
||||
document.getElementById('zipThresholdValue').textContent = zipThreshold;
|
||||
localStorage.setItem('zipThreshold', zipThreshold);
|
||||
document.getElementById("downloadOption").addEventListener("change", function () {
|
||||
downloadOption = this.value;
|
||||
localStorage.setItem("downloadOption", downloadOption);
|
||||
});
|
||||
|
||||
// Get the zipThreshold value from local storage, or set it to 0 if it doesn't exist
|
||||
var zipThreshold = parseInt(localStorage.getItem("zipThreshold"), 10) || 4;
|
||||
|
||||
var boredWaiting = localStorage.getItem('boredWaiting') || 'disabled';
|
||||
document.getElementById('boredWaiting').checked = boredWaiting === 'enabled';
|
||||
// Set the value of the slider and the display span
|
||||
document.getElementById("zipThreshold").value = zipThreshold;
|
||||
document.getElementById("zipThresholdValue").textContent = zipThreshold;
|
||||
|
||||
document.getElementById('boredWaiting').addEventListener('change', function() {
|
||||
boredWaiting = this.checked ? 'enabled' : 'disabled';
|
||||
localStorage.setItem('boredWaiting', boredWaiting);
|
||||
});
|
||||
// Save the selected value to local storage when the slider value changes
|
||||
document.getElementById("zipThreshold").addEventListener("input", function () {
|
||||
zipThreshold = this.value;
|
||||
document.getElementById("zipThresholdValue").textContent = zipThreshold;
|
||||
localStorage.setItem("zipThreshold", zipThreshold);
|
||||
});
|
||||
|
||||
var boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
||||
document.getElementById("boredWaiting").checked = boredWaiting === "enabled";
|
||||
|
||||
document.getElementById("boredWaiting").addEventListener("change", function () {
|
||||
boredWaiting = this.checked ? "enabled" : "disabled";
|
||||
localStorage.setItem("boredWaiting", boredWaiting);
|
||||
});
|
||||
|
||||
@@ -1,39 +1,38 @@
|
||||
|
||||
TabContainer = {
|
||||
initTabGroups() {
|
||||
const groups = document.querySelectorAll(".tab-group");
|
||||
const unloadedGroups = [...groups].filter(g => !g.initialised);
|
||||
unloadedGroups.forEach(group => {
|
||||
const containers = group.querySelectorAll(".tab-container");
|
||||
const tabTitles = [...containers].map(c => c.getAttribute("title"));
|
||||
initTabGroups() {
|
||||
const groups = document.querySelectorAll(".tab-group");
|
||||
const unloadedGroups = [...groups].filter((g) => !g.initialised);
|
||||
unloadedGroups.forEach((group) => {
|
||||
const containers = group.querySelectorAll(".tab-container");
|
||||
const tabTitles = [...containers].map((c) => c.getAttribute("title"));
|
||||
|
||||
const tabList = document.createElement("div");
|
||||
tabList.classList.add("tab-buttons");
|
||||
tabTitles.forEach(title => {
|
||||
const tabButton = document.createElement("button");
|
||||
tabButton.innerHTML = title;
|
||||
tabButton.onclick = e => {
|
||||
this.setActiveTab(e.target);
|
||||
}
|
||||
tabList.appendChild(tabButton);
|
||||
});
|
||||
group.prepend(tabList);
|
||||
const tabList = document.createElement("div");
|
||||
tabList.classList.add("tab-buttons");
|
||||
tabTitles.forEach((title) => {
|
||||
const tabButton = document.createElement("button");
|
||||
tabButton.innerHTML = title;
|
||||
tabButton.onclick = (e) => {
|
||||
this.setActiveTab(e.target);
|
||||
};
|
||||
tabList.appendChild(tabButton);
|
||||
});
|
||||
group.prepend(tabList);
|
||||
|
||||
this.setActiveTab(tabList.firstChild);
|
||||
this.setActiveTab(tabList.firstChild);
|
||||
|
||||
group.initialised = true;
|
||||
});
|
||||
},
|
||||
setActiveTab(tabButton) {
|
||||
const group = tabButton.closest(".tab-group")
|
||||
group.initialised = true;
|
||||
});
|
||||
},
|
||||
setActiveTab(tabButton) {
|
||||
const group = tabButton.closest(".tab-group");
|
||||
|
||||
group.querySelectorAll(".active").forEach(el => el.classList.remove("active"));
|
||||
group.querySelectorAll(".active").forEach((el) => el.classList.remove("active"));
|
||||
|
||||
tabButton.classList.add("active");
|
||||
group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active");
|
||||
},
|
||||
}
|
||||
tabButton.classList.add("active");
|
||||
group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active");
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
TabContainer.initTabGroups();
|
||||
})
|
||||
TabContainer.initTabGroups();
|
||||
});
|
||||
|
||||
503
src/main/resources/static/pdfjs/css/viewer.css
vendored
503
src/main/resources/static/pdfjs/css/viewer.css
vendored
@@ -116,7 +116,6 @@
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
:root {
|
||||
--annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
|
||||
--input-focus-border-color: Highlight;
|
||||
@@ -139,9 +138,7 @@
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
|
||||
.annotationLayer .choiceWidgetAnnotation select:required,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:required {
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required {
|
||||
outline: 1.5px solid selectedItem;
|
||||
}
|
||||
|
||||
@@ -228,9 +225,7 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer
|
||||
:is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder)
|
||||
> a:hover {
|
||||
.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) > a:hover {
|
||||
opacity: 0.2;
|
||||
background-color: rgba(255, 255, 0, 1);
|
||||
box-shadow: 0 2px 10px rgba(255, 255, 0, 1);
|
||||
@@ -268,9 +263,7 @@
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
|
||||
.annotationLayer .choiceWidgetAnnotation select:required,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:required {
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required {
|
||||
outline: 1.5px solid red;
|
||||
}
|
||||
|
||||
@@ -288,9 +281,7 @@ input:required {
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea)[disabled],
|
||||
.annotationLayer .choiceWidgetAnnotation select[disabled],
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input[disabled] {
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input[disabled] {
|
||||
background: none;
|
||||
border: 2px solid var(--input-disabled-border-color);
|
||||
cursor: not-allowed;
|
||||
@@ -298,9 +289,7 @@ input[disabled] {
|
||||
|
||||
.annotationLayer .textWidgetAnnotation :is(input, textarea):hover,
|
||||
.annotationLayer .choiceWidgetAnnotation select:hover,
|
||||
.annotationLayer
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton)
|
||||
input:hover {
|
||||
.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:hover {
|
||||
border: 2px solid var(--input-hover-border-color);
|
||||
}
|
||||
|
||||
@@ -489,7 +478,6 @@ input:hover {
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
||||
:root {
|
||||
--xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
|
||||
--xfa-focus-outline: auto;
|
||||
@@ -827,10 +815,7 @@ input:hover {
|
||||
--freetext-padding: 2px;
|
||||
--resizer-bg-color: var(--outline-color);
|
||||
--resizer-size: 6px;
|
||||
--resizer-shift: calc(
|
||||
0px - (var(--outline-width) + var(--resizer-size)) / 2 -
|
||||
var(--outline-around-width)
|
||||
);
|
||||
--resizer-shift: calc(0px - (var(--outline-width) + var(--resizer-size)) / 2 - var(--outline-around-width));
|
||||
--editorFreeText-editing-cursor: text;
|
||||
--editorInk-editing-cursor: url(../images/cursor-editorInk.svg) 0 16, pointer;
|
||||
|
||||
@@ -853,8 +838,7 @@ input:hover {
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 1.1), (min-resolution: 1.1dppx) {
|
||||
:root {
|
||||
--editorFreeText-editing-cursor: url(../images/cursor-editorFreeText.svg) 0 16,
|
||||
text;
|
||||
--editorFreeText-editing-cursor: url(../images/cursor-editorFreeText.svg) 0 16, text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,216 +1093,354 @@ input:hover {
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight {
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle {
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle {
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft {
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft {
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topLeft,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight {
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomRight {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle {
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomMiddle {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.topRight,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft {
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.bottomLeft {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.middleRight,
|
||||
.annotationEditorLayer[data-main-rotation="0"]
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="90"], [data-editor-rotation="270"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="90"]
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="0"], [data-editor-rotation="180"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="180"]
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
|
||||
:is([data-editor-rotation="270"], [data-editor-rotation="90"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft,
|
||||
.annotationEditorLayer[data-main-rotation="270"]
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft {
|
||||
:is([data-editor-rotation="180"], [data-editor-rotation="0"])
|
||||
> .resizers
|
||||
> .resizer.middleLeft {
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
) .altText {
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
)
|
||||
.altText {
|
||||
rotate: 270deg;
|
||||
}
|
||||
|
||||
[dir="ltr"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
) .altText {
|
||||
[dir="ltr"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
)
|
||||
.altText {
|
||||
inset-inline-start: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[dir="ltr"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
) .altText.small {
|
||||
[dir="ltr"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
)
|
||||
.altText.small {
|
||||
inset-inline-start: calc(100% + 8px);
|
||||
inset-block-start: 100%;
|
||||
}
|
||||
|
||||
[dir="rtl"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
) .altText {
|
||||
[dir="rtl"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
)
|
||||
.altText {
|
||||
inset-block-end: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[dir="rtl"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
) .altText.small {
|
||||
[dir="rtl"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="180"]
|
||||
)
|
||||
.altText.small {
|
||||
inset-inline-start: -8px;
|
||||
inset-block-start: 0;
|
||||
}
|
||||
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="270"]
|
||||
) .altText {
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="270"]
|
||||
)
|
||||
.altText {
|
||||
rotate: 180deg;
|
||||
|
||||
inset-block-end: calc(100% - 8px);
|
||||
@@ -1326,64 +1448,74 @@ input:hover {
|
||||
}
|
||||
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="270"]
|
||||
) .altText.small {
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="0"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="270"]
|
||||
)
|
||||
.altText.small {
|
||||
inset-inline-start: 100%;
|
||||
inset-block-start: -8px;
|
||||
}
|
||||
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
) .altText {
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
)
|
||||
.altText {
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
[dir="ltr"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
) .altText {
|
||||
[dir="ltr"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
)
|
||||
.altText {
|
||||
inset-block-end: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[dir="ltr"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
) .altText.small {
|
||||
[dir="ltr"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
)
|
||||
.altText.small {
|
||||
inset-inline-start: -8px;
|
||||
inset-block-start: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
) .altText {
|
||||
[dir="rtl"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
)
|
||||
.altText {
|
||||
inset-inline-start: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[dir="rtl"] .annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
) .altText.small {
|
||||
[dir="rtl"]
|
||||
.annotationEditorLayer
|
||||
:is(
|
||||
[data-main-rotation="0"] [data-editor-rotation="270"],
|
||||
[data-main-rotation="90"] [data-editor-rotation="180"],
|
||||
[data-main-rotation="180"] [data-editor-rotation="90"],
|
||||
[data-main-rotation="270"] [data-editor-rotation="0"]
|
||||
)
|
||||
.altText.small {
|
||||
inset-inline-start: calc(100% + 8px);
|
||||
inset-block-start: 100%;
|
||||
}
|
||||
@@ -1421,7 +1553,6 @@ input:hover {
|
||||
}
|
||||
|
||||
.altText.small {
|
||||
|
||||
inset-block-end: unset;
|
||||
inset-inline-start: 0;
|
||||
inset-block-start: calc(100% + 8px);
|
||||
@@ -1515,7 +1646,6 @@ input:hover {
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.altText .tooltip.show {
|
||||
--alt-text-tooltip-bg: #1c1b22;
|
||||
--alt-text-tooltip-fg: #fbfbfe;
|
||||
@@ -1524,7 +1654,6 @@ input:hover {
|
||||
}
|
||||
|
||||
@media screen and (forced-colors: active) {
|
||||
|
||||
.altText .tooltip.show {
|
||||
--alt-text-tooltip-bg: Canvas;
|
||||
--alt-text-tooltip-fg: CanvasText;
|
||||
@@ -1581,7 +1710,6 @@ input:hover {
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
#altTextDialog {
|
||||
--dialog-bg-color: #1c1b22;
|
||||
--dialog-border-color: #1c1b22;
|
||||
@@ -1604,7 +1732,6 @@ input:hover {
|
||||
}
|
||||
|
||||
@media screen and (forced-colors: active) {
|
||||
|
||||
#altTextDialog {
|
||||
--dialog-bg-color: Canvas;
|
||||
--dialog-border-color: CanvasText;
|
||||
@@ -2022,8 +2149,8 @@ input:hover {
|
||||
--toolbar-border-color: rgba(184, 184, 184, 1);
|
||||
--toolbar-box-shadow: 0 1px 0 var(--toolbar-border-color);
|
||||
--toolbar-border-bottom: none;
|
||||
--toolbarSidebar-box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgba(0, 0, 0, 0.25),
|
||||
0 1px 0 rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.1);
|
||||
--toolbarSidebar-box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(0, 0, 0, 0.15),
|
||||
0 0 1px rgba(0, 0, 0, 0.1);
|
||||
--toolbarSidebar-border-bottom: none;
|
||||
--button-hover-color: rgba(221, 222, 223, 1);
|
||||
--toggled-btn-color: rgba(0, 0, 0, 1);
|
||||
@@ -2319,8 +2446,7 @@ body {
|
||||
font: message-box;
|
||||
}
|
||||
|
||||
:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer)
|
||||
:is(input, button, select),
|
||||
:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer) :is(input, button, select),
|
||||
.secondaryToolbar :is(input, button, a, select) {
|
||||
outline: none;
|
||||
font: message-box;
|
||||
@@ -2417,19 +2543,18 @@ body {
|
||||
height: 100%;
|
||||
width: calc(100% + 150px);
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
var(--progressBar-blend-color) 0,
|
||||
var(--progressBar-bg-color) 5px,
|
||||
var(--progressBar-bg-color) 45px,
|
||||
var(--progressBar-color) 55px,
|
||||
var(--progressBar-color) 95px,
|
||||
var(--progressBar-blend-color) 100px
|
||||
135deg,
|
||||
var(--progressBar-blend-color) 0,
|
||||
var(--progressBar-bg-color) 5px,
|
||||
var(--progressBar-bg-color) 45px,
|
||||
var(--progressBar-color) 55px,
|
||||
var(--progressBar-color) 95px,
|
||||
var(--progressBar-blend-color) 100px
|
||||
);
|
||||
animation: progressIndeterminate 1s linear infinite;
|
||||
}
|
||||
|
||||
#outerContainer.sidebarResizing
|
||||
:is(#sidebarContainer, #viewerContainer, #loadingBar) {
|
||||
#outerContainer.sidebarResizing :is(#sidebarContainer, #viewerContainer, #loadingBar) {
|
||||
/* Improve responsiveness and avoid visual glitches when the sidebar is resized. */
|
||||
transition-duration: 0s;
|
||||
}
|
||||
@@ -2600,8 +2725,9 @@ body {
|
||||
.doorHanger,
|
||||
.doorHangerRight {
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 5px var(--doorhanger-border-color),
|
||||
0 0 0 1px var(--doorhanger-border-color);
|
||||
box-shadow:
|
||||
0 1px 5px var(--doorhanger-border-color),
|
||||
0 0 0 1px var(--doorhanger-border-color);
|
||||
border: var(--doorhanger-border-color-whcm);
|
||||
}
|
||||
|
||||
@@ -3455,8 +3581,7 @@ dialog :link {
|
||||
cursor: grab !important;
|
||||
}
|
||||
|
||||
.grab-to-pan-grab
|
||||
*:not(input):not(textarea):not(button):not(select):not(:link) {
|
||||
.grab-to-pan-grab *:not(input):not(textarea):not(button):not(select):not(:link) {
|
||||
cursor: inherit !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user