Compare commits

..

28 Commits

Author SHA1 Message Date
Johannes Meyer
ac844e6464 composer.json: Raise ipl/orm requirement 2025-07-14 13:53:18 +02:00
Johannes Meyer
2afd0f67eb Update README.md 2025-05-22 13:18:57 +02:00
Johannes Meyer
84c91fbac0 composer.json: Raise ipl-web requirement 2025-05-22 12:57:40 +02:00
Johannes Meyer
3e895ee7e6 RELEASE.md: Update docker example 2025-05-22 11:25:22 +02:00
Johannes Meyer
7b1ea02863 Remove patch for ramsey/collection
It's obsolte now since the raise to PHP 8.2
2025-05-21 13:15:39 +02:00
Johannes Meyer
ce45fede7e Raise required PHP version to 8.2 2025-05-21 13:15:29 +02:00
Johannes Meyer
ca92d8e26e composer.json: Raise required versions 2024-07-15 09:51:48 +02:00
Johannes Meyer
611ca4161b make-release.sh: Properly handle file names with whitespace 2023-12-13 16:24:13 +01:00
Johannes Meyer
42dff4b0f6
Merge pull request #25 from Icinga/fix-autoloading
Fix autoloading
2023-10-27 09:47:10 +02:00
Johannes Meyer
b89aa9dfab Transfer ramsey/collection patch from icinga-php-thirdparty 2023-10-27 09:43:48 +02:00
Johannes Meyer
65a24000de Revert "Merge pull request #22 from Icinga/avoid-child-dependency-installs"
This reverts commit 71c4555ff2a5cceecb6e4b23bb5b3354c22c7444, reversing
changes made to 435e443a4122da64f92baaa054d65c36bebab77f.
2023-10-27 09:26:48 +02:00
Johannes Meyer
71c4555ff2
Merge pull request #22 from Icinga/avoid-child-dependency-installs
Avoid child dependency installs
2023-10-19 16:46:12 +02:00
Johannes Meyer
666262b018 Make sure no release contains thirdparty libraries 2023-10-19 16:43:02 +02:00
Johannes Meyer
7330e414a6 Add metapackage to avoid child dependency installs 2023-10-19 16:42:37 +02:00
Johannes Meyer
435e443a41 Require latest ipl releases 2023-09-21 11:41:57 +02:00
Johannes Meyer
51a905fcfe make-snapshot.sh: Don't override config.platform of composer.json 2023-08-04 08:41:11 +02:00
Johannes Meyer
2f5fc7ea9d composer.json: Raise php platform requirement..
..to what icinga-php-thirdparty requires
2023-08-04 08:18:44 +02:00
Johannes Meyer
7610682215 Require ipl-web v0.8.0 2023-05-15 10:38:20 +02:00
Johannes Meyer
77c423f41c Require latest ipl releases 2023-03-22 11:00:10 +01:00
Yonas Habteab
1aa0681e0f Require ipl\scheduler 2023-03-21 17:38:01 +01:00
Johannes Meyer
e5ef360ca4 default branch name is now main everywhere 2023-03-21 17:34:44 +01:00
Johannes Meyer
28bc9342a5 create-snapshot: Upgrade actions/checkout 2023-03-01 09:16:19 +01:00
Johannes Meyer
e13e8de224 create-snapshot: Run at 18 o'clock 2023-03-01 09:15:19 +01:00
Johannes Meyer
5b2f19db5e make-snapshot.sh: Make sure ipl parts are properly updated 2023-03-01 09:09:48 +01:00
Eric Lippmann
5e038a1d56
export-ignore: Fix typo 2023-01-24 15:18:12 +01:00
Johannes Meyer
ec69390abd Require ipl-sql v0.6.0 2022-12-13 15:08:54 +01:00
Johannes Meyer
43db4ed1b9 Raise version to 0.10.1 2022-12-13 15:04:30 +01:00
Eric Lippmann
ee11cd45f0 Export ignore
Remove Git-related files, `bin/` and `RELEASE.md` from archives.
2022-12-12 09:00:56 +01:00
322 changed files with 45 additions and 315647 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
.git* export-ignore
bin/ export-ignore
RELEASE.md export-ignore

View File

@ -2,8 +2,8 @@ name: Create Snapshot
on:
schedule:
# Every day at 4pm
- cron: "0 16 * * *"
# Every day at 6pm
- cron: "0 18 * * *"
workflow_dispatch:
jobs:
@ -14,7 +14,7 @@ jobs:
steps:
- name: Checkout code base
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@ -5,13 +5,14 @@ This project bundles all Icinga PHP libraries into one piece and can be integrat
## Requirements
* [Icinga Web 2](https://github.com/Icinga/icingaweb2) (>= 2.9)
* PHP (>= 7.2)
* PHP (>= 8.2)
## Bundled Parts
* [ipl-html](https://github.com/Icinga/ipl-html)
* [ipl-i18n](https://github.com/Icinga/ipl-i18n)
* [ipl-orm](https://github.com/Icinga/ipl-orm)
* [ipl-scheduler](https://github.com/Icinga/ipl-scheduler)
* [ipl-sql](https://github.com/Icinga/ipl-sql)
* [ipl-stdlib](https://github.com/Icinga/ipl-stdlib)
* [ipl-validator](https://github.com/Icinga/ipl-validator)
@ -24,8 +25,8 @@ path for Icinga Web 2 installations is: `/usr/share/icinga-php`
Download or clone this repository there (e.g. `/usr/share/icinga-php/ipl`) and you're done.
> **Note**: Do NOT install the GIT master, it will not work! Checking out a
> branch like `stable/0.9.1` or a tag like `v0.9.1` is fine.
> **Note**: Do NOT use the default branch, it will not work! Checking out a
> branch like `stable/0.16.0` or a tag like `v0.16.0` is fine.
### Examples
@ -33,7 +34,7 @@ Download or clone this repository there (e.g. `/usr/share/icinga-php/ipl`) and y
```sh
INSTALL_PATH="/usr/share/icinga-php/ipl"
INSTALL_VERSION="v0.9.1"
INSTALL_VERSION="v0.16.0"
mkdir "$INSTALL_PATH" \
&& wget -q "https://github.com/Icinga/icinga-php-library/archive/$INSTALL_VERSION.tar.gz" -O - \
| tar xfz - -C "$INSTALL_PATH" --strip-components 1
@ -43,6 +44,6 @@ mkdir "$INSTALL_PATH" \
```
INSTALL_PATH="/usr/share/icinga-php/ipl"
INSTALL_VERSION="stable/0.9.1"
INSTALL_VERSION="stable/0.16.0"
git clone https://github.com/Icinga/icinga-php-library.git "$INSTALL_PATH" --branch "$INSTALL_VERSION"
```

View File

@ -8,4 +8,4 @@ e.g.
## Docker Example
docker run -it -v $(pwd):/tmp/pwd -w /tmp/pwd -v $(realpath ~/.gitconfig):/tmp/user/.gitconfig -e "HOME=/tmp/user" -u $(id -u):$(id -g) dev-docker_web72 bin/make-release.sh 1.0.0 --no-tag
docker run -it -v $(pwd):/tmp/pwd -w /tmp/pwd -v $(realpath ~/.gitconfig):/tmp/user/.gitconfig -e "HOME=/tmp/user" -u $(id -u):$(id -g) dev-docker_web82 bin/make-release.sh 1.0.0 --no-tag

View File

@ -1 +0,0 @@
v0.10.0

View File

@ -1,35 +0,0 @@
:root, :host {
--fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free";
--fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free";
}
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 400;
font-display: block;
src: url('@{iplWebAssets}/font/awesome/fa-regular-400.woff2') format('woff2'),
url('@{iplWebAssets}/font/awesome/fa-regular-400.ttf') format('truetype');
}
.far,
.fa-regular {
font-family: 'Font Awesome 6 Free';
font-weight: 400;
}
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url('@{iplWebAssets}/font/awesome/fa-solid-900.woff2') format('woff2'),
url('@{iplWebAssets}/font/awesome/fa-solid-900.ttf') format('truetype');
}
.fa,
.fas,
.fa-solid {
font-family: 'Font Awesome 6 Free';
font-weight: 900;
}

View File

@ -1,148 +0,0 @@
@ball-pad: 1/6em;
.ball {
border-radius: 50%;
display: inline-block;
text-align: center;
}
.ball-size-xs {
height: 1/3em;
width: 1/3em;
}
.ball-size-s {
height: 0.5em;
width: 0.5em;
}
.ball-size-m {
height: 0.75em;
width: 0.75em;
line-height: 0;
i.icon:before {
font-size: .75 - @ball-pad * 2;
line-height: 1em;
}
}
.ball-size-ml {
height: 1em;
width: 1em;
line-height: 0;
i.icon {
line-height: 0.3;
&:before {
font-size: 0.8 - @ball-pad * 2;
line-height: 1 - @ball-pad * 2;
}
}
}
.ball-size-l {
height: 1.5em;
width: 1.5em;
line-height: 1em;
i.icon:before {
font-size: 1 - @ball-pad * 2;
line-height: 1.5 - @ball-pad * 2;
}
}
.ball-size-xl {
width: 2em;
height: 2em;
i.icon:before {
line-height: 2 - @ball-pad * 2;
}
}
.ball-outline(@color) {
border: @ball-pad solid @color;
color: @color;
}
.ball-solid(@color) {
background-color: @color;
color: var(--default-text-color-inverted, @default-text-color-inverted);
padding: @ball-pad;
}
.state-ball {
.ball();
&.state-pending:not(.ball-size-l):not(.ball-size-xl) {
.ball-solid(var(--state-pending, @state-pending));
}
&.state-pending.ball-size-l,
&.state-pending.ball-size-xl {
.ball-outline(var(--state-pending, @state-pending));
}
&.state-up:not(.ball-size-l):not(.ball-size-xl) {
.ball-solid(var(--state-up, @state-up));
}
&.state-up.ball-size-l,
&.state-up.ball-size-xl {
.ball-outline(var(--state-up, @state-up));
}
&.state-down {
.ball-solid(var(--state-down, @state-down));
}
&.state-ok:not(.ball-size-l):not(.ball-size-xl) {
.ball-solid(var(--state-ok, @state-ok));
}
&.state-ok.ball-size-l,
&.state-ok.ball-size-xl {
.ball-outline(var(--state-ok, @state-ok));
}
&.state-warning {
.ball-solid(var(--state-warning, @state-warning));
}
&.state-critical {
.ball-solid(var(--state-critical, @state-critical));
}
&.state-unknown {
.ball-solid(var(--state-unknown, @state-unknown));
}
&.handled {
opacity: 0.6;
}
i {
text-align: center;
display: block;
&:before {
margin-right: 0;
}
}
// Specific icon styles
&.ball-size-l i {
&.fa-sitemap:before {
font-size: 8px; // px to ignore browser min font-size
}
}
&.ball-size-xl i {
&.fa-sitemap:before {
font-size: .857em;
line-height: (2 - @ball-pad * 2) / .857;
}
}
}

View File

@ -1,34 +0,0 @@
.cancel-button {
display: inline-flex;
align-items: baseline;
padding: .5em 1em;
.appearance(none);
.rounded-corners();
line-height: normal;
cursor: pointer;
background: var(--cancel-button-bg, @cancel-button-bg);
border: 1px solid var(--cancel-button-border-color, @cancel-button-border-color);
color: var(--cancel-button-color, @cancel-button-color);
&:focus,
&:hover {
background-color: var(--cancel-button-hover-bg, @cancel-button-hover-bg);
color: var(--cancel-button-hover-color, @cancel-button-hover-color);
}
&[disabled] {
background: none;
cursor: default;
border: 1px solid var(--control-disabled-color, @control-disabled-color);
color: var(--control-disabled-color, @control-disabled-color);
&:focus,
&:hover {
background: none;
color: var(--control-disabled-color, @control-disabled-color);
}
}
}

View File

@ -1,76 +0,0 @@
.pagination-control {
li > a {
color: var(--control-color, @control-color);
border-radius: .25em;
}
li > a:hover {
background: var(--control-hover-bg, @control-hover-bg);
}
.previous-page,
.next-page {
padding: .5em .25em;
i {
display: block;
}
i:before {
margin: 0;
}
}
.previous-page > i {
margin-left: -.125em;
}
.next-page > i {
margin-right: -.125em;
}
}
// Style
.control-button {
.appearance(none);
background: none;
border: none;
color: var(--control-color, @control-color);
.rounded-corners();
&:hover, &:focus, &.active {
background-color: var(--control-hover-bg, @control-hover-bg);
text-decoration: none;
}
&.disabled {
color: var(--control-disabled-color, @control-disabled-color);
&:hover {
background: none;
}
}
i.icon:before {
color: inherit;
}
}
// Layout
.control-button {
display: inline-block;
padding: .25em .5em;
> i.icon {
display: inline-flex;
align-items: center;
height: 100%;
}
i.icon:before {
margin-right: 0;
}
}

View File

@ -1,9 +0,0 @@
.flatpickr-input + .input {
padding-right: 2em;
& + .fa-calendar {
margin: .5em 1em 0 -3.5em;
padding: 0 .5em 0 1em;
pointer-events: none;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
.horizontal-key-value {
display: flex;
padding: .25em 0;
align-items: baseline;
.key {
color: var(--default-text-color-light, @default-text-color-light);
flex: 0 0 auto;
white-space: nowrap;
width: 12em;
}
.value {
color: var(--default-text-color, @default-text-color);
flex: 1 1 auto;
}
}

View File

@ -1,36 +0,0 @@
@font-face {
font-family: 'Icinga-Icons';
src: url('@{iplWebAssets}/font/Icinga-Icons.eot');
src: url('@{iplWebAssets}/font/Icinga-Icons.eot') format('embedded-opentype'),
url('@{iplWebAssets}/font/Icinga-Icons.ttf') format('truetype'),
url('@{iplWebAssets}/font/Icinga-Icons.woff') format('woff'),
url('@{iplWebAssets}/font/Icinga-Icons.svg') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^="iicon-"]:before, [class*=" iicon-"]:before {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'Icinga-Icons';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1em;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iicon-minimal:before {
content: "\e900";
}
.iicon-detailed:before {
content: "\e901";
}
.iicon-default:before {
content: "\e902";
}

View File

@ -1,12 +0,0 @@
i.icon {
vertical-align: middle; // Firefox will place icons weird otherwise
&:before {
display: inline-block;
min-width: 1em;
margin-right: .2em;
text-align: center;
text-decoration: inherit;
}
}

View File

@ -1,23 +0,0 @@
.card() {
&.card {
.rounded-corners(.5em);
border: 1px solid var(--card-border-color, @card-border-color);
.card-header {
display: flex;
align-items: baseline;
justify-content: space-between;
padding: .5em;
border-bottom: 1px solid var(--card-border-color, @card-border-color);
.meta span {
font-size: 11/12em;
}
}
.card-body {
padding: .5em;
}
}
}

View File

@ -1,20 +0,0 @@
.rounded-corners(@border-radius: 0.4em) {
border-radius: @border-radius;
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
.appearance(@appearance) {
-webkit-appearance: @appearance;
-moz-appearance: @appearance;
-ms-appearance: @appearance;
appearance: @appearance;
}
.box-shadow(@x: 0.2em; @y: 0.2em; @blur: 0.2em; @spread: 0; @color: rgba(83, 83, 83, 0.25)) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}

View File

@ -1,31 +0,0 @@
.state-badges() {
&.state-badges {
padding: 0;
ul {
padding: 0;
}
li {
display: inline-block;
}
li > ul > li:first-child:not(:last-child) .state-badge {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
li > ul > li:last-child:not(:first-child) .state-badge {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
> li:not(:last-child) {
margin-right: .25em;
}
li > ul > li:last-child {
margin-left: 1px;
}
}
}

View File

@ -1,316 +0,0 @@
// Style
.search-bar {
.rounded-corners(.25em);
background: var(--searchbar-bg, @searchbar-bg);
// Reset all input styles
input, [type="button"] {
.appearance(none);
border: none;
background: none;
}
// Submit button styles
input[type=submit],
button[type=submit],
button:not([type]) {
background: var(--primary-button-bg, @primary-button-bg);
color: var(--primary-button-color, @primary-button-color);
border-top-right-radius: .25em;
border-bottom-right-radius: .25em;
}
// General input styles
input:focus {
outline-offset: -1px;
}
// Hide the submit button, it must exist, but shouldn't be shown to the user
input[type=submit][value="hidden"] {
display: none;
}
// Left-most search dropdown style
button.search-options {
i.icon:before {
font-size: 1.2em;
margin-right: 0;
color: var(--control-color, @control-color);
}
&:disabled {
i.icon:before {
color: var(--control-disabled-color, @control-disabled-color);
}
}
}
// Scrollbar style
.filter-input-area {
// Firefox
scrollbar-width: thin;
scrollbar-color: var(--searchbar-scrollbar-bg, @searchbar-scrollbar-bg) transparent;
&::-webkit-scrollbar {
display: none;
height: .5em;
}
&:hover::-webkit-scrollbar {
display: initial;
}
&::-webkit-scrollbar-thumb {
border-radius: .25em;
background: var(--searchbar-scrollbar-bg, @searchbar-scrollbar-bg);
}
}
// Term styles
.filter-condition {
button {
border-radius: .4em 0 0 .4em;
background-color: var(--search-condition-remove-bg, @search-condition-remove-bg);
color: var(--search-condition-remove-color, @search-condition-remove-color);
&:after {
content: "";
position: absolute;
width: .4em;
height: 100%;
right: 0;
top: 0;
background-color: var(--searchbar-bg, @searchbar-bg);
border: .2em solid var(--search-condition-remove-bg, @search-condition-remove-bg);
border-width: 0 0 0 .2em;
border-top-left-radius: .4em;
border-bottom-left-radius: .4em;
}
}
input {
background-color: var(--search-term-bg, @search-term-bg);
color: var(--search-term-color, @search-term-color);
}
}
.terms > .filter-condition:first-child button {
border-radius: 0 .4em .4em 0;
&:before {
content: "";
position: absolute;
width: .4em;
height: 100%;
left: 0;
top: 0;
background-color: var(--searchbar-bg, @searchbar-bg);
border: .2em solid var(--search-condition-remove-bg, @search-condition-remove-bg);
border-width: 0 .2em 0 0;
border-top-right-radius: .4em;
border-bottom-right-radius: .4em;
}
&:after {
content: none;
}
}
.logical_operator,
.grouping_operator_open,
.grouping_operator_close {
input {
.rounded-corners();
background-color: var(--search-logical-operator-bg, @search-logical-operator-bg);
color: var(--search-logical-operator-color, @search-logical-operator-color);
}
}
.operator,
.logical_operator,
.grouping_operator_open,
.grouping_operator_close {
input {
text-align: center;
}
}
[data-index] input:invalid {
background-color: var(--search-term-invalid-bg, @search-term-invalid-bg);
color: var(--search-term-invalid-color, @search-term-invalid-color);
}
[data-index] input:disabled {
background-color: var(--search-term-disabled-bg, @search-term-disabled-bg);
}
.column input {
.rounded-corners(.4em);
}
.column:not(:last-of-type),
.column.last-term {
input {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
.operator:last-of-type:not(.last-term) input {
.rounded-corners(.4em);
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.value input {
.rounded-corners(.4em);
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.highlighted input {
background-color: var(--search-term-highlighted-bg, @search-term-highlighted-bg);
color: var(--search-term-highlighted-color, @search-term-highlighted-color);
}
.selected input {
background-color: var(--search-term-selected-bg, @search-term-selected-bg);
color: var(--search-term-selected-color, @search-term-selected-color);
font-style: italic;
}
ul.comma-separated {
display: inline;
padding: 0;
list-style-type: none;
li {
display: inline;
&:not(:first-of-type):before {
display: inline;
content: ', ';
}
}
}
}
// Layout
.search-bar {
height: 2em;
display: flex;
position: relative; // Required for the suggestions
button.search-options {
line-height: 1em;
}
.filter-input-area {
overflow: auto hidden;
overflow-x: overlay; // Not invalid, but proprietary feature by chrome/webkit
display: flex;
width: 100%;
height: ~"calc(2em + 10px)"; // Search bar height + approximate scrollbar height
padding: 2/12em; // 2 (px) desired / default font size (px)
// Lets inputs grow based on their contents, Inspired by https://css-tricks.com/auto-growing-inputs-textareas/
label {
position: relative;
display: inline-block;
min-width: 2em;
&::after,
input {
width: auto;
padding: 0 .5em;
resize: none;
}
input {
width: 100%;
position: absolute;
line-height: 20/12; // 20 (px) desired / default font size (px)
}
&::after {
height: 0;
content: attr(data-label);
visibility: hidden;
white-space: nowrap;
padding: 0 7/12em; // 7 (px) desired / default font size (px)
}
}
> label {
flex: 1 0 auto;
&::after,
input {
max-width: none;
min-width: 8em;
}
}
}
.terms {
display: inline;
flex-shrink: 0;
.filter-chain,
.filter-condition {
display: inline;
}
.filter-condition {
position: relative;
button {
display: none;
z-index: 1;
width: ~"calc(2em + 2px)";
padding: .15em .6em .15em .4em;
position: absolute;
left: ~"calc(-2em - 2px)"; // That's min-width + margin-right of an operator
line-height: 16/12; // 16 (px) desired / default font size (px)
i:before {
margin-right: 0;
}
}
&:not(._hover_delay):hover button {
display: inline;
}
}
> .filter-condition:first-child button {
padding: .15em .4em .15em .6em;
left: auto;
right: ~"calc(-2em - 1px)"; // That's min-width + margin-left of an operator
}
label {
margin-right: 1px;
&.logical_operator,
&.grouping_operator_open,
&.grouping_operator_close {
margin-left: 1px; // adds up to 2px with the previous term
margin-right: 2px;
}
}
}
&.disabled {
.terms .filter-condition:hover button {
display: none;
}
}
.search-suggestions {
// 2 (px) desired / default font-size to match .filter-input outline-offset (-1px) + outline-width (3px)
margin-top: 2/12em;
}
}

View File

@ -1,131 +0,0 @@
// Style
.search-suggestions {
background: var(--suggestions-bg, @suggestions-bg);
border: 1px solid var(--suggestions-border-color, @suggestions-border-color);
border-bottom-right-radius: .5em;
border-bottom-left-radius: .5em;
> ul {
list-style-type: none;
> li {
border-top: 1px solid var(--suggestions-separation-bg, @suggestions-separation-bg);
}
> li.suggestion-title + li {
border: none;
}
> li:not(.default) + li.suggestion-title {
border: none;
}
}
.default {
color: var(--suggestions-default-opt-color, @suggestions-default-opt-color);
font-style: italic;
[type="button"] {
background-color: var(--suggestions-default-opt-bg, @suggestions-default-opt-bg);
}
}
.suggestion-title {
color: var(--suggestions-color, @suggestions-color);
font-size: 80%;
}
.failure-message {
font-weight: bold;
em {
font-weight: normal;
color: var(--suggestions-failure-message-color, @suggestions-failure-message-color);
}
}
.nothing-to-suggest {
color: var(--suggestions-color, @suggestions-color);
}
.relation-path {
padding: 0 .2em;
background-color: var(--suggestions-relation-path-bg, @suggestions-relation-path-bg);
}
[type="button"] {
.appearance(none);
border: none;
background: none;
}
[type="button"]:focus {
background: var(--suggestions-focus-bg, @suggestions-focus-bg);
color: var(--suggestions-focus-color, @suggestions-focus-color);
outline: none;
.relation-path {
background-color: var(--suggestions-relation-path-focus-bg, @suggestions-relation-path-focus-bg);
}
}
[type="button"]:not(:focus):hover {
background: var(--suggestions-hover-bg, @suggestions-hover-bg);
}
}
// Layout
.search-suggestions {
z-index: 2; // Required so that nothing else can overlap it (such as opaque elements and the impact overlay)
position: absolute;
overflow: auto;
min-width: 5em;
&:empty {
display: none;
}
> ul {
margin: 0;
padding: 0;
li.suggestion-title {
padding: 1.25em .625em 0 .625em;
}
li.failure-message {
padding: .5em 1em;
em {
margin-right: .5em;
}
}
li.nothing-to-suggest {
padding: .5em 1em;
}
}
[type="button"] {
padding: .5em 1em;
display: block;
width: 100%;
text-align: left;
&[data-class="operator"], &[data-class="logical_operator"] {
text-align: center;
}
&.has-details {
display: flex;
align-items: baseline;
justify-content: space-between;
}
.relation-path {
margin-left: .5em;
&::first-line {
font-size: .8em;
}
}
}
}

View File

@ -1,267 +0,0 @@
// Style
.search-editor {
ul, ol {
list-style-type: none;
}
fieldset {
border: none;
}
button, input[type="submit"] {
.appearance(none);
background: none;
&:not(.cancel-button) {
border: none;
}
}
select:not([multiple]) {
.appearance(none);
padding-right: 1.5625em;
background-image: url('@{iplWebAssets}/img/select-icon-text-color.svg');
background-repeat: no-repeat;
background-position: right center;
background-size: contain;
.rounded-corners(0);
}
i.icon:before {
color: var(--search-editor-control-color, @search-editor-control-color);
}
.drag-initiator {
cursor: grab;
}
input[type="text"], select {
border: none;
background: var(--search-term-bg, @search-term-bg);
color: var(--search-term-color, @search-term-color);
text-overflow: ellipsis;
}
:not(fieldset) > select {
.rounded-corners();
}
fieldset > input[data-type="column"] {
.rounded-corners(.4em 0 0 .4em);
}
fieldset > input[data-type="value"] {
.rounded-corners(0 .4em .4em 0);
}
.search-error {
input:invalid {
background: var(--search-term-invalid-bg, @search-term-invalid-bg);
}
.search-errors {
color: var(--search-term-invalid-color, @search-term-invalid-color);
font-weight: bold;
}
}
li > select:not([multiple]) {
background-color: var(--search-logical-operator-bg, @search-logical-operator-bg);
color: var(--search-logical-operator-color, @search-logical-operator-color);
.rounded-corners();
}
.sortable-ghost {
border: dashed .2em var(--search-editor-drag-outline-color, @search-editor-drag-outline-color);
fieldset {
opacity: .5;
}
}
.buttons {
ul {
.rounded-corners();
.box-shadow(0, 0, .5em);
border: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color);
background: var(--search-editor-context-menu-bg, @search-editor-context-menu-bg);
li:not(:first-child) {
border-top: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color);
}
button:hover {
background: var(--primary-button-bg, @primary-button-bg);
color: var(--primary-button-color, @primary-button-color);
}
// Add rounded corners to buttons as well, otherwise their
// background is not rounded and overlaps the list's corners
:first-child button {
.rounded-corners();
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
:last-child button {
.rounded-corners();
border-top-left-radius: 0;
border-top-right-radius: 0;
}
&:before {
// The left pointing arrow
border-bottom: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color);
border-left: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color);
background: var(--search-editor-context-menu-bg, @search-editor-context-menu-bg);
}
}
&:hover i.icon:before {
.rounded-corners();
background: var(--primary-button-bg, @primary-button-bg);
color: var(--primary-button-color, @primary-button-color);
}
}
input[type="submit"] {
.rounded-corners();
background: var(--primary-button-bg, @primary-button-bg);
color: var(--primary-button-color, @primary-button-color);
&:hover {
background: var(--primary-button-hover-bg, @primary-button-hover-bg);
}
}
}
// Layout
.search-editor-opener + a.modal-opener {
display: none;
}
.search-editor {
padding: 1em;
@item-spacing: .5em;
ul, ol {
width: 100%;
margin: 0;
padding: 0;
}
li {
display: flex;
> :not(:first-child) {
margin-left: @item-spacing;
}
}
ol {
padding-left: 1em;
padding-bottom: @item-spacing;
> li:first-child,
> :not(.filter-chain) + li {
margin-top: @item-spacing;
}
}
input[type="text"], select {
padding: 0 .5em;
}
li > select {
margin-right: auto;
}
fieldset {
display: flex;
flex: 1 1 auto;
margin: 0;
padding: 0;
input[data-type="value"] {
flex: 1 1 auto;
}
> :not(:first-child) {
margin-left: .1em;
}
}
input, button, select {
height: 28/12em; // Target Pixels @ default font size / default font size
}
.search-errors {
margin-left: .5em;
}
i.icon:before {
margin: 0;
font-size: 1.5em;
line-height: 1.5;
}
.buttons {
position: relative;
ul {
position: absolute;
right: 32/12em; // Target distance @ default font size / default font size
z-index: 1;
width: auto;
padding: 0;
display: none;
button {
z-index: 1;
width: 100%;
text-align: left;
white-space: nowrap;
}
&:before {
// The left pointing arrow
content: "";
display: block;
height: 1em;
transform: rotate(-135deg);
width: 1em;
z-index: 1;
position: absolute;
top: ((28/12)/2)-.5em; // ((First row pixels @ default font size / default font size) / 2) - own half width
right: -.5em;
}
}
&:hover ul {
display: block;
}
i.icon:before {
padding: ((28/18)-1)/2em; // (Container pixels / default font size) - line height / (padding-top,padding-bottom)
line-height: 1;
}
}
.cancel-button {
margin-top: 2em - @item-spacing;
}
input[type="submit"] {
float: right;
width: 6em;
margin-top: 2em - @item-spacing;
}
input[type="submit"]:not(:last-of-type) {
display: none;
}
}

View File

@ -1,47 +0,0 @@
.state-badge {
.rounded-corners();
color: var(--default-text-color-inverted, @default-text-color-inverted);
display: inline-block;
font-size: 1em;
min-width: 2em;
padding: .25em;
text-align: center;
&.handled {
opacity: .8;
}
&.state-critical {
background-color: var(--state-critical, @state-critical);
}
&.state-down {
background-color: var(--state-down, @state-down);
}
&.state-ok {
background-color: var(--state-ok, @state-ok);
}
&.state-pending {
background-color: var(--state-pending, @state-pending);
}
&.state-unknown {
background-color: var(--state-unknown, @state-unknown);
}
&.state-up {
background-color: var(--state-up, @state-up);
}
&.state-warning {
background-color: var(--state-warning, @state-warning);
}
}
a .state-badge {
&:not(.disabled):hover {
filter: brightness(80%);
}
}

View File

@ -1,166 +0,0 @@
/*
RECOMMENDATION:
Please do not use the base color variables directly,
define a new variable instead that assigns the value of this base variable.
Examples:
- @base-color: red;
- @my-new-var: @base-color;
- @my-second-new-var: @base-color;
Do not use the same variable for different use cases, but define a new variable for each use case.
NOTICE:
Color vars identification:
- Vars with `-bg` suffix are background-color vars. Please use only for setting bg-color.
- Vars with `-color` suffix are color vars. Please use only for setting fg-color.
MODE SUPPORT:
The standard LESS variables represent the dark mode. The LESS detached ruleset `@iplWebLightRules`
contains CSS variables that represent the light mode. It must be used explicitly to have any effect.
If you use media queries to support modes, just call the ruleset inside your media query:
@media (prefers-color-scheme: light) {
@iplWebLightRules();
}
*/
@default-bg: #282E39;
@base-gray: #c4c4c4;
@base-gray-light: #5c5c5c;
@base-gray-lighter: #4b4b4b;
@base-disabled: #9a9a9a;
@base-primary-color: #00C3ED;
@base-primary-bg: #00C3ED;
@default-text-color: #fff;
@default-text-color-light: fade(@default-text-color, 75%);
@default-text-color-inverted: @default-bg;
@state-ok: #44bb77;
@state-up: @state-ok;
@state-warning: #ffaa44;
@state-critical: #ff5566;
@state-down: @state-critical;
@state-pending: #77aaff;
@state-unknown: #aa44ff;
@primary-button-color: @default-text-color-inverted;
@primary-button-bg: @base-primary-bg;
@primary-button-hover-bg: #0081a6;
@search-term-bg: @base-gray;
@search-term-color: @default-text-color-inverted;
@search-term-selected-bg: @base-disabled;
@search-term-invalid-bg: @state-critical;
@search-term-invalid-color: @default-text-color-inverted;
@search-term-disabled-bg: @base-disabled;
@search-term-selected-color: @base-gray-light;
@search-term-highlighted-bg: @base-primary-bg;
@search-term-highlighted-color: @default-text-color-inverted;
@search-condition-remove-bg: @state-critical;
@search-condition-remove-color: @default-text-color-inverted;
@search-logical-operator-bg: @base-gray-light;
@search-logical-operator-color: @default-text-color-light;
@searchbar-bg: #404d72;
@searchbar-scrollbar-bg: @base-gray-light;
@search-editor-control-color: @base-gray-light;
@search-editor-logical-op-bg: @base-gray-light;
@search-editor-context-menu-border-color: @base-gray-light;
@search-editor-context-menu-bg: @default-bg;
@search-editor-drag-outline-color: @base-gray;
@control-color: @base-primary-color;
@control-hover-bg: @base-gray-lighter;
@control-disabled-color: @base-disabled;
@cancel-button-bg: none;
@cancel-button-border-color: @state-critical;
@cancel-button-color: @state-critical;
@cancel-button-hover-bg: @state-critical;
@cancel-button-hover-color: @default-text-color-inverted;
@suggestions-bg: @default-bg;
@suggestions-color: @default-text-color-light;
@suggestions-focus-bg: @base-primary-bg;
@suggestions-focus-color: @default-text-color-inverted;
@suggestions-default-opt-bg: fade(@base-primary-bg, 10%);
@suggestions-default-opt-color: @default-text-color-light;
@suggestions-hover-bg: fade(@base-primary-bg, 30%);
@suggestions-border-color: @base-gray-light;
@suggestions-separation-bg: @base-gray-lighter;
@suggestions-failure-message-color: @default-text-color-light;
@suggestions-relation-path-bg: @base-gray-light;
@suggestions-relation-path-focus-bg: @base-gray;
@card-border-color: @base-gray-light;
@iplWebLightRules: {
:root {
--base-gray: #819398;
--base-gray-light: #d0d3da;
--base-gray-lighter: #e8ecef;
--base-disabled: var(--base-gray-light);
--base-remove-bg: @state-critical;
--default-text-color: #535353;
--default-text-color-light: fade(#535353, 75%); // --default-text-color
--default-text-color-inverted: #F5F9FA;
--primary-button-color: var(--default-text-color-inverted);
--primary-button-bg: @primary-button-bg;
--primary-button-hover-bg: @primary-button-hover-bg;
--searchbar-bg: #DEECF1;
--searchbar-scrollbar-bg: var(--base-gray-light);
--search-term-bg: var(--base-gray-light);
--search-term-color: var(--default-text-color);
--search-term-selected-bg: var(--base-disabled);
--search-term-invalid-bg: var(--base-remove-bg);
--search-term-invalid-color: var(--default-text-color-inverted);
--search-term-disabled-bg: var(--base-gray-light);
--search-term-selected-color: var(--base-gray);
--search-term-highlighted-bg: var(--primary-button-bg);
--search-term-highlighted-color: var(--default-text-color-inverted);
--search-condition-remove-bg: var(--base-remove-bg);
--search-condition-remove-color: var(--default-text-color-inverted);
--search-logical-operator-bg: fade(#819398, 50%); // --base-gray
--search-logical-operator-color: var(--default-text-color-light);
--search-editor-control-color: var(--base-gray-light);
--search-editor-logical-op-bg: var(--base-gray-light);
--search-editor-context-menu-border-color: var(--base-gray-light);
--search-editor-context-menu-bg: var(--default-text-color-inverted);
--search-editor-drag-outline-color: var(--base-gray);
--control-color: var(--primary-button-bg);
--control-hover-bg: var(--base-gray-lighter);
--control-disabled-color: var(--base-gray-light);
--cancel-button-hover-color: var(--default-text-color-inverted);
--suggestions-bg: var(--default-text-color-inverted);
--suggestions-color: var(--default-text-color-light);
--suggestions-focus-bg: var(--primary-button-bg);
--suggestions-focus-color: var(--default-text-color-inverted);
--suggestions-default-opt-bg: fade(@primary-button-bg, 10%);
--suggestions-default-opt-color: var(--default-text-color-light);
--suggestions-hover-bg: fade(@primary-button-bg, 30%);
--suggestions-border-color: var(--base-gray-light);
--suggestions-separation-bg: var(--base-gray-lighter);
--suggestions-failure-message-color: var(--default-text-color-light);
--suggestions-relation-path-bg: var(--base-gray-lighter);
--suggestions-relation-path-focus-bg: var(--base-gray);
--card-border-color: var(--base-gray-light);
}
};

View File

@ -1,791 +0,0 @@
.flatpickr-calendar {
background: transparent;
opacity: 0;
display: none;
text-align: center;
visibility: hidden;
padding: 0;
-webkit-animation: none;
animation: none;
direction: ltr;
border: 0;
font-size: 14px;
line-height: 24px;
border-radius: 5px;
position: absolute;
width: 307.875px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-ms-touch-action: manipulation;
touch-action: manipulation;
background: #fff;
-webkit-box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);
box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);
}
.flatpickr-calendar.open,
.flatpickr-calendar.inline {
opacity: 1;
max-height: 640px;
visibility: visible;
}
.flatpickr-calendar.open {
display: inline-block;
z-index: 99999;
}
.flatpickr-calendar.animate.open {
-webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
}
.flatpickr-calendar.inline {
display: block;
position: relative;
top: 2px;
}
.flatpickr-calendar.static {
position: absolute;
top: calc(100% + 2px);
}
.flatpickr-calendar.static.open {
z-index: 999;
display: block;
}
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7) {
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) {
-webkit-box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
}
.flatpickr-calendar .hasWeeks .dayContainer,
.flatpickr-calendar .hasTime .dayContainer {
border-bottom: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.flatpickr-calendar .hasWeeks .dayContainer {
border-left: 0;
}
.flatpickr-calendar.hasTime .flatpickr-time {
height: 40px;
border-top: 1px solid #e6e6e6;
}
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {
height: auto;
}
.flatpickr-calendar:before,
.flatpickr-calendar:after {
position: absolute;
display: block;
pointer-events: none;
border: solid transparent;
content: '';
height: 0;
width: 0;
left: 22px;
}
.flatpickr-calendar.rightMost:before,
.flatpickr-calendar.arrowRight:before,
.flatpickr-calendar.rightMost:after,
.flatpickr-calendar.arrowRight:after {
left: auto;
right: 22px;
}
.flatpickr-calendar.arrowCenter:before,
.flatpickr-calendar.arrowCenter:after {
left: 50%;
right: 50%;
}
.flatpickr-calendar:before {
border-width: 5px;
margin: 0 -5px;
}
.flatpickr-calendar:after {
border-width: 4px;
margin: 0 -4px;
}
.flatpickr-calendar.arrowTop:before,
.flatpickr-calendar.arrowTop:after {
bottom: 100%;
}
.flatpickr-calendar.arrowTop:before {
border-bottom-color: #e6e6e6;
}
.flatpickr-calendar.arrowTop:after {
border-bottom-color: #fff;
}
.flatpickr-calendar.arrowBottom:before,
.flatpickr-calendar.arrowBottom:after {
top: 100%;
}
.flatpickr-calendar.arrowBottom:before {
border-top-color: #e6e6e6;
}
.flatpickr-calendar.arrowBottom:after {
border-top-color: #fff;
}
.flatpickr-calendar:focus {
outline: 0;
}
.flatpickr-wrapper {
position: relative;
display: inline-block;
}
.flatpickr-months {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.flatpickr-months .flatpickr-month {
background: transparent;
color: rgba(0,0,0,0.9);
fill: rgba(0,0,0,0.9);
height: 34px;
line-height: 1;
text-align: center;
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow: hidden;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month {
text-decoration: none;
cursor: pointer;
position: absolute;
top: 0;
height: 34px;
padding: 10px;
z-index: 3;
color: rgba(0,0,0,0.9);
fill: rgba(0,0,0,0.9);
}
.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,
.flatpickr-months .flatpickr-next-month.flatpickr-disabled {
display: none;
}
.flatpickr-months .flatpickr-prev-month i,
.flatpickr-months .flatpickr-next-month i {
position: relative;
}
.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month.flatpickr-prev-month {
/*
/*rtl:begin:ignore*/
/*
*/
left: 0;
/*
/*rtl:end:ignore*/
/*
*/
}
/*
/*rtl:begin:ignore*/
/*
/*rtl:end:ignore*/
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,
.flatpickr-months .flatpickr-next-month.flatpickr-next-month {
/*
/*rtl:begin:ignore*/
/*
*/
right: 0;
/*
/*rtl:end:ignore*/
/*
*/
}
/*
/*rtl:begin:ignore*/
/*
/*rtl:end:ignore*/
.flatpickr-months .flatpickr-prev-month:hover,
.flatpickr-months .flatpickr-next-month:hover {
color: #959ea9;
}
.flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-months .flatpickr-next-month:hover svg {
fill: #f64747;
}
.flatpickr-months .flatpickr-prev-month svg,
.flatpickr-months .flatpickr-next-month svg {
width: 14px;
height: 14px;
}
.flatpickr-months .flatpickr-prev-month svg path,
.flatpickr-months .flatpickr-next-month svg path {
-webkit-transition: fill 0.1s;
transition: fill 0.1s;
fill: inherit;
}
.numInputWrapper {
position: relative;
height: auto;
}
.numInputWrapper input,
.numInputWrapper span {
display: inline-block;
}
.numInputWrapper input {
width: 100%;
}
.numInputWrapper input::-ms-clear {
display: none;
}
.numInputWrapper input::-webkit-outer-spin-button,
.numInputWrapper input::-webkit-inner-spin-button {
margin: 0;
-webkit-appearance: none;
}
.numInputWrapper span {
position: absolute;
right: 0;
width: 14px;
padding: 0 4px 0 2px;
height: 50%;
line-height: 50%;
opacity: 0;
cursor: pointer;
border: 1px solid rgba(57,57,57,0.15);
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.numInputWrapper span:hover {
background: rgba(0,0,0,0.1);
}
.numInputWrapper span:active {
background: rgba(0,0,0,0.2);
}
.numInputWrapper span:after {
display: block;
content: "";
position: absolute;
}
.numInputWrapper span.arrowUp {
top: 0;
border-bottom: 0;
}
.numInputWrapper span.arrowUp:after {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid rgba(57,57,57,0.6);
top: 26%;
}
.numInputWrapper span.arrowDown {
top: 50%;
}
.numInputWrapper span.arrowDown:after {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid rgba(57,57,57,0.6);
top: 40%;
}
.numInputWrapper span svg {
width: inherit;
height: auto;
}
.numInputWrapper span svg path {
fill: rgba(0,0,0,0.5);
}
.numInputWrapper:hover {
background: rgba(0,0,0,0.05);
}
.numInputWrapper:hover span {
opacity: 1;
}
.flatpickr-current-month {
font-size: 135%;
line-height: inherit;
font-weight: 300;
color: inherit;
position: absolute;
width: 75%;
left: 12.5%;
padding: 7.48px 0 0 0;
line-height: 1;
height: 34px;
display: inline-block;
text-align: center;
-webkit-transform: translate3d(0px, 0px, 0px);
transform: translate3d(0px, 0px, 0px);
}
.flatpickr-current-month span.cur-month {
font-family: inherit;
font-weight: 700;
color: inherit;
display: inline-block;
margin-left: 0.5ch;
padding: 0;
}
.flatpickr-current-month span.cur-month:hover {
background: rgba(0,0,0,0.05);
}
.flatpickr-current-month .numInputWrapper {
width: 6ch;
width: 7ch\0;
display: inline-block;
}
.flatpickr-current-month .numInputWrapper span.arrowUp:after {
border-bottom-color: rgba(0,0,0,0.9);
}
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
border-top-color: rgba(0,0,0,0.9);
}
.flatpickr-current-month input.cur-year {
background: transparent;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
cursor: text;
padding: 0 0 0 0.5ch;
margin: 0;
display: inline-block;
font-size: inherit;
font-family: inherit;
font-weight: 300;
line-height: inherit;
height: auto;
border: 0;
border-radius: 0;
vertical-align: initial;
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
.flatpickr-current-month input.cur-year:focus {
outline: 0;
}
.flatpickr-current-month input.cur-year[disabled],
.flatpickr-current-month input.cur-year[disabled]:hover {
font-size: 100%;
color: rgba(0,0,0,0.5);
background: transparent;
pointer-events: none;
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
appearance: menulist;
background: transparent;
border: none;
border-radius: 0;
box-sizing: border-box;
color: inherit;
cursor: pointer;
font-size: inherit;
font-family: inherit;
font-weight: 300;
height: auto;
line-height: inherit;
margin: -1px 0 0 0;
outline: none;
padding: 0 0 0 0.5ch;
position: relative;
vertical-align: initial;
-webkit-box-sizing: border-box;
-webkit-appearance: menulist;
-moz-appearance: menulist;
width: auto;
}
.flatpickr-current-month .flatpickr-monthDropdown-months:focus,
.flatpickr-current-month .flatpickr-monthDropdown-months:active {
outline: none;
}
.flatpickr-current-month .flatpickr-monthDropdown-months:hover {
background: rgba(0,0,0,0.05);
}
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {
background-color: transparent;
outline: none;
padding: 0;
}
.flatpickr-weekdays {
background: transparent;
text-align: center;
overflow: hidden;
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 28px;
}
.flatpickr-weekdays .flatpickr-weekdaycontainer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
span.flatpickr-weekday {
cursor: default;
font-size: 90%;
background: transparent;
color: rgba(0,0,0,0.54);
line-height: 1;
margin: 0;
text-align: center;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
font-weight: bolder;
}
.dayContainer,
.flatpickr-weeks {
padding: 1px 0 0 0;
}
.flatpickr-days {
position: relative;
overflow: hidden;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: start;
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
width: 307.875px;
}
.flatpickr-days:focus {
outline: 0;
}
.dayContainer {
padding: 0;
outline: 0;
text-align: left;
width: 307.875px;
min-width: 307.875px;
max-width: 307.875px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
display: -ms-flexbox;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-wrap: wrap;
-ms-flex-pack: justify;
-webkit-justify-content: space-around;
justify-content: space-around;
-webkit-transform: translate3d(0px, 0px, 0px);
transform: translate3d(0px, 0px, 0px);
opacity: 1;
}
.dayContainer + .dayContainer {
-webkit-box-shadow: -1px 0 0 #e6e6e6;
box-shadow: -1px 0 0 #e6e6e6;
}
.flatpickr-day {
background: none;
border: 1px solid transparent;
border-radius: 150px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #393939;
cursor: pointer;
font-weight: 400;
width: 14.2857143%;
-webkit-flex-basis: 14.2857143%;
-ms-flex-preferred-size: 14.2857143%;
flex-basis: 14.2857143%;
max-width: 39px;
height: 39px;
line-height: 39px;
margin: 0;
display: inline-block;
position: relative;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
}
.flatpickr-day.inRange,
.flatpickr-day.prevMonthDay.inRange,
.flatpickr-day.nextMonthDay.inRange,
.flatpickr-day.today.inRange,
.flatpickr-day.prevMonthDay.today.inRange,
.flatpickr-day.nextMonthDay.today.inRange,
.flatpickr-day:hover,
.flatpickr-day.prevMonthDay:hover,
.flatpickr-day.nextMonthDay:hover,
.flatpickr-day:focus,
.flatpickr-day.prevMonthDay:focus,
.flatpickr-day.nextMonthDay:focus {
cursor: pointer;
outline: 0;
background: #e6e6e6;
border-color: #e6e6e6;
}
.flatpickr-day.today {
border-color: #959ea9;
}
.flatpickr-day.today:hover,
.flatpickr-day.today:focus {
border-color: #959ea9;
background: #959ea9;
color: #fff;
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected.inRange,
.flatpickr-day.startRange.inRange,
.flatpickr-day.endRange.inRange,
.flatpickr-day.selected:focus,
.flatpickr-day.startRange:focus,
.flatpickr-day.endRange:focus,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover,
.flatpickr-day.selected.prevMonthDay,
.flatpickr-day.startRange.prevMonthDay,
.flatpickr-day.endRange.prevMonthDay,
.flatpickr-day.selected.nextMonthDay,
.flatpickr-day.startRange.nextMonthDay,
.flatpickr-day.endRange.nextMonthDay {
background: #569ff7;
-webkit-box-shadow: none;
box-shadow: none;
color: #fff;
border-color: #569ff7;
}
.flatpickr-day.selected.startRange,
.flatpickr-day.startRange.startRange,
.flatpickr-day.endRange.startRange {
border-radius: 50px 0 0 50px;
}
.flatpickr-day.selected.endRange,
.flatpickr-day.startRange.endRange,
.flatpickr-day.endRange.endRange {
border-radius: 0 50px 50px 0;
}
.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),
.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),
.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)) {
-webkit-box-shadow: -10px 0 0 #569ff7;
box-shadow: -10px 0 0 #569ff7;
}
.flatpickr-day.selected.startRange.endRange,
.flatpickr-day.startRange.startRange.endRange,
.flatpickr-day.endRange.startRange.endRange {
border-radius: 50px;
}
.flatpickr-day.inRange {
border-radius: 0;
-webkit-box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
}
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.flatpickr-disabled:hover,
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay,
.flatpickr-day.notAllowed,
.flatpickr-day.notAllowed.prevMonthDay,
.flatpickr-day.notAllowed.nextMonthDay {
color: rgba(57,57,57,0.3);
background: transparent;
border-color: transparent;
cursor: default;
}
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.flatpickr-disabled:hover {
cursor: not-allowed;
color: rgba(57,57,57,0.1);
}
.flatpickr-day.week.selected {
border-radius: 0;
-webkit-box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;
box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;
}
.flatpickr-day.hidden {
visibility: hidden;
}
.rangeMode .flatpickr-day {
margin-top: 1px;
}
.flatpickr-weekwrapper {
float: left;
}
.flatpickr-weekwrapper .flatpickr-weeks {
padding: 0 12px;
-webkit-box-shadow: 1px 0 0 #e6e6e6;
box-shadow: 1px 0 0 #e6e6e6;
}
.flatpickr-weekwrapper .flatpickr-weekday {
float: none;
width: 100%;
line-height: 28px;
}
.flatpickr-weekwrapper span.flatpickr-day,
.flatpickr-weekwrapper span.flatpickr-day:hover {
display: block;
width: 100%;
max-width: none;
color: rgba(57,57,57,0.3);
background: transparent;
cursor: default;
border: none;
}
.flatpickr-innerContainer {
display: block;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
}
.flatpickr-rContainer {
display: inline-block;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.flatpickr-time {
text-align: center;
outline: 0;
display: block;
height: 0;
line-height: 40px;
max-height: 40px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.flatpickr-time:after {
content: "";
display: table;
clear: both;
}
.flatpickr-time .numInputWrapper {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
width: 40%;
height: 40px;
float: left;
}
.flatpickr-time .numInputWrapper span.arrowUp:after {
border-bottom-color: #393939;
}
.flatpickr-time .numInputWrapper span.arrowDown:after {
border-top-color: #393939;
}
.flatpickr-time.hasSeconds .numInputWrapper {
width: 26%;
}
.flatpickr-time.time24hr .numInputWrapper {
width: 49%;
}
.flatpickr-time input {
background: transparent;
-webkit-box-shadow: none;
box-shadow: none;
border: 0;
border-radius: 0;
text-align: center;
margin: 0;
padding: 0;
height: inherit;
line-height: inherit;
color: #393939;
font-size: 14px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
.flatpickr-time input.flatpickr-hour {
font-weight: bold;
}
.flatpickr-time input.flatpickr-minute,
.flatpickr-time input.flatpickr-second {
font-weight: 400;
}
.flatpickr-time input:focus {
outline: 0;
border: 0;
}
.flatpickr-time .flatpickr-time-separator,
.flatpickr-time .flatpickr-am-pm {
height: inherit;
float: left;
line-height: inherit;
color: #393939;
font-weight: bold;
width: 2%;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center;
}
.flatpickr-time .flatpickr-am-pm {
outline: 0;
width: 18%;
cursor: pointer;
text-align: center;
font-weight: 400;
}
.flatpickr-time input:hover,
.flatpickr-time .flatpickr-am-pm:hover,
.flatpickr-time input:focus,
.flatpickr-time .flatpickr-am-pm:focus {
background: #eee;
}
.flatpickr-input[readonly] {
cursor: pointer;
}
@-webkit-keyframes fpFadeInDown {
from {
opacity: 0;
-webkit-transform: translate3d(0, -20px, 0);
transform: translate3d(0, -20px, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes fpFadeInDown {
from {
opacity: 0;
-webkit-transform: translate3d(0, -20px, 0);
transform: translate3d(0, -20px, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}

View File

@ -1,327 +0,0 @@
/**
* This file's only purpose is to make the flatpickr themeable. DO NOT add ANY custom style here!
* Also, DO NOT re-arrange the CSS blocks to make them more LESS like. They're based off of the
* pre-compiled flatpickr.css file and so can easily identified when updating to a new version.
*
* Non-standard LESS variables were added to allow usage of CSS variables. All of them hold a
* value calculated by LESS functions. If not temporarily stored in another LESS variable,
* they wouldn't be available to CSS variable usage.
*
* Latest state from version: v4.6.9
*/
@fp-calendarBackground: #ffffff;
@fp-calendarBorderColor: #e6e6e6;
@fp-arrowColor: fadeout(@fp-dayForeground, 40%); // Non-standard variable
@fp-arrow_hover_color: #f64747;
@fp-monthForeground: fadeout(black, 10%);
@fp-monthBackground: transparent;
@fp-weekdaysBackground: transparent;
@fp-weekdaysForeground: fadeout(black, 46%);
@fp-weekNumberForeground: fadeout(@fp-dayForeground, 70%); // Non-standard variable
@fp-dayForeground: #393939;
@fp-dayHoverBackground: #e6e6e6;
@fp-disabledDayForeground: fadeout(@fp-dayForeground, 90%); // Non-standard variable
@fp-outsideRangeDayForeground: @fp-weekNumberForeground; // Non-standard variable
@fp-selectedDayBackground: #569FF7;
@fp-todayColor: #959ea9;
@fp-timeHoverBg: lighten(@fp-dayHoverBackground, 3); // Non-standard variable
@fp-invertedBg: black;
@fp-hoverInvertedBg: fadeout(@fp-invertedBg, 95%); // Non-standard variable
@fp-numChooserSvgFillColor: fadeout(@fp-monthForeground, 50%); // Non-standard variable
@fp-hoverNumChooserBg: fadeout(@fp-invertedBg, 90%); // Non-standard variable
@fp-numChooserBorderColor: fadeout(@fp-dayForeground, 85%); // Non-standard variable
.icinga-datetime-picker {
&.flatpickr-calendar {
background: @fp-calendarBackground;
background: var(--fp-calendarBackground, @fp-calendarBackground);
box-shadow: 1px 0 0 @fp-calendarBorderColor,
-1px 0 0 @fp-calendarBorderColor,
0 1px 0 @fp-calendarBorderColor,
0 -1px 0 @fp-calendarBorderColor,
0 3px 13px fadeout(black, 92%);
box-shadow: 1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor),
-1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor),
0 1px 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor),
0 -1px 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor),
0 3px 13px fadeout(black, 92%);
}
&.flatpickr-calendar.arrowTop:before {
border-bottom-color: @fp-calendarBorderColor;
border-bottom-color: var(--fp-calendarBorderColor, @fp-calendarBorderColor);
}
&.flatpickr-calendar.arrowTop:after {
border-bottom-color: @fp-calendarBackground;
border-bottom-color: var(--fp-calendarBackground, @fp-calendarBackground);
}
&.flatpickr-calendar.arrowBottom:before {
border-top-color: @fp-calendarBorderColor;
border-top-color: var(--fp-calendarBorderColor, @fp-calendarBorderColor);
}
&.flatpickr-calendar.arrowBottom:after {
border-top-color: @fp-calendarBackground;
border-top-color: var(--fp-calendarBackground, @fp-calendarBackground);
}
&.flatpickr-calendar.hasTime .flatpickr-time {
border-top-color: @fp-calendarBorderColor;
border-top-color: var(--fp-calendarBorderColor, @fp-calendarBorderColor);
}
.dayContainer + .dayContainer {
-webkit-box-shadow: -1px 0 0 @fp-calendarBorderColor;
-webkit-box-shadow: -1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor);
box-shadow: -1px 0 0 @fp-calendarBorderColor;
box-shadow: -1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor);
}
.flatpickr-day {
color: @fp-dayForeground;
color: var(--fp-dayForeground, @fp-dayForeground);
}
.flatpickr-day.today {
border-color: @fp-todayColor;
border-color: var(--fp-todayColor, @fp-todayColor);
}
.flatpickr-day.today:hover,
.flatpickr-day.today:focus {
border-color: @fp-todayColor;
border-color: var(--fp-todayColor, @fp-todayColor);
background: @fp-todayColor;
background: var(--fp-todayColor, @fp-todayColor);
color: @fp-calendarBackground;
color: var(--fp-calendarBackground, @fp-calendarBackground);
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected.inRange,
.flatpickr-day.startRange.inRange,
.flatpickr-day.endRange.inRange,
.flatpickr-day.selected:focus,
.flatpickr-day.startRange:focus,
.flatpickr-day.endRange:focus,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover,
.flatpickr-day.selected.prevMonthDay,
.flatpickr-day.startRange.prevMonthDay,
.flatpickr-day.endRange.prevMonthDay,
.flatpickr-day.selected.nextMonthDay,
.flatpickr-day.startRange.nextMonthDay,
.flatpickr-day.endRange.nextMonthDay {
color: @fp-calendarBackground;
color: var(--fp-calendarBackground, @fp-calendarBackground);
}
.flatpickr-day.inRange,
.flatpickr-day.prevMonthDay.inRange,
.flatpickr-day.nextMonthDay.inRange,
.flatpickr-day.today.inRange,
.flatpickr-day.prevMonthDay.today.inRange,
.flatpickr-day.nextMonthDay.today.inRange,
.flatpickr-day:hover,
.flatpickr-day.prevMonthDay:hover,
.flatpickr-day.nextMonthDay:hover,
.flatpickr-day:focus,
.flatpickr-day.nextMonthDay:focus {
background: @fp-dayHoverBackground;
background: var(--fp-dayHoverBackground, @fp-dayHoverBackground);
border-color: @fp-dayHoverBackground;
border-color: var(--fp-dayHoverBackground, @fp-dayHoverBackground);
}
.flatpickr-day.inRange {
-webkit-box-shadow: -5px 0 0 @fp-dayHoverBackground, 5px 0 0 @fp-dayHoverBackground;
-webkit-box-shadow: -5px 0 0 var(--fp-dayHoverBackground, @fp-dayHoverBackground),
5px 0 0 var(--fp-dayHoverBackground, @fp-dayHoverBackground);
box-shadow: -5px 0 0 @fp-dayHoverBackground, 5px 0 0 @fp-dayHoverBackground;
box-shadow: -5px 0 0 var(--fp-dayHoverBackground, @fp-dayHoverBackground),
5px 0 0 var(--fp-dayHoverBackground, @fp-dayHoverBackground);
}
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay,
.flatpickr-day.notAllowed,
.flatpickr-day.notAllowed.prevMonthDay,
.flatpickr-day.notAllowed.nextMonthDay {
color: @fp-outsideRangeDayForeground;
color: var(--fp-outsideRangeDayForeground, @fp-outsideRangeDayForeground);
}
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.flatpickr-disabled:hover {
color: @fp-disabledDayForeground;
color: var(--fp-disabledDayForeground, @fp-disabledDayForeground);
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected.inRange,
.flatpickr-day.startRange.inRange,
.flatpickr-day.endRange.inRange,
.flatpickr-day.selected:focus,
.flatpickr-day.startRange:focus,
.flatpickr-day.endRange:focus,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover,
.flatpickr-day.selected.prevMonthDay,
.flatpickr-day.startRange.prevMonthDay,
.flatpickr-day.endRange.prevMonthDay,
.flatpickr-day.selected.nextMonthDay,
.flatpickr-day.startRange.nextMonthDay,
.flatpickr-day.endRange.nextMonthDay {
background: @fp-selectedDayBackground;
background: var(--fp-selectedDayBackground, @fp-selectedDayBackground);
border-color: @fp-selectedDayBackground;
border-color: var(--fp-selectedDayBackground, @fp-selectedDayBackground);
}
.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),
.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),
.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)) {
-webkit-box-shadow: -10px 0 0 @fp-selectedDayBackground;
-webkit-box-shadow: -10px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground);
box-shadow: -10px 0 0 @fp-selectedDayBackground;
box-shadow: -10px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground);
}
.flatpickr-day.week.selected {
-webkit-box-shadow: -5px 0 0 @fp-selectedDayBackground, 5px 0 0 @fp-selectedDayBackground;
-webkit-box-shadow: -5px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground),
5px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground);
box-shadow: -5px 0 0 @fp-selectedDayBackground, 5px 0 0 @fp-selectedDayBackground;
box-shadow: -5px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground),
5px 0 0 var(--fp-selectedDayBackground, @fp-selectedDayBackground);
}
.flatpickr-weekwrapper .flatpickr-weeks {
-webkit-box-shadow: 1px 0 0 @fp-calendarBorderColor;
-webkit-box-shadow: 1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor);
box-shadow: 1px 0 0 @fp-calendarBorderColor;
box-shadow: 1px 0 0 var(--fp-calendarBorderColor, @fp-calendarBorderColor);
}
.flatpickr-weekwrapper span.flatpickr-day,
.flatpickr-weekwrapper span.flatpickr-day:hover {
color: @fp-weekNumberForeground;
color: var(--fp-weekNumberForeground, @fp-weekNumberForeground);
}
.flatpickr-weekdays {
background: @fp-weekdaysBackground;
background: var(--fp-weekdaysBackground, @fp-weekdaysBackground);
}
span.flatpickr-weekday {
background: @fp-monthBackground;
background: var(--fp-monthBackground, @fp-monthBackground);
color: @fp-weekdaysForeground;
color: var(--fp-weekdaysForeground, @fp-weekdaysForeground);
}
.flatpickr-months .flatpickr-month {
background: @fp-monthBackground;
background: var(--fp-monthBackground, @fp-monthBackground);
color: @fp-monthForeground;
color: var(--fp-monthForeground, @fp-monthForeground);
fill: @fp-monthForeground;
fill: var(--fp-monthForeground, @fp-monthForeground);
}
.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month {
color: @fp-monthForeground;
color: var(--fp-monthForeground, @fp-monthForeground);
fill: @fp-monthForeground;
fill: var(--fp-monthForeground, @fp-monthForeground);
}
.flatpickr-months .flatpickr-prev-month:hover,
.flatpickr-months .flatpickr-next-month:hover {
color: @fp-todayColor;
color: var(--fp-todayColor, @fp-todayColor);
}
.flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-months .flatpickr-next-month:hover svg {
fill: @fp-arrow_hover_color;
fill: var(--fp-arrow_hover_color, @fp-arrow_hover_color);
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
background: @fp-monthBackground;
background: var(--fp-monthBackground, @fp-monthBackground);
}
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {
background-color: @fp-monthBackground;
background-color: var(--fp-monthBackground, @fp-monthBackground);
}
.flatpickr-current-month .numInputWrapper span.arrowUp:after {
border-bottom-color: @fp-monthForeground;
border-bottom-color: var(--fp-monthForeground, @fp-monthForeground);
}
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
border-top-color: @fp-monthForeground;
border-top-color: var(--fp-monthForeground, @fp-monthForeground);
}
.numInputWrapper span {
border-color: @fp-numChooserBorderColor;
border-color: var(--fp-numChooserBorderColor, @fp-numChooserBorderColor);
}
.numInputWrapper span:hover {
background: @fp-hoverNumChooserBg;
background: var(--fp-hoverNumChooserBg, @fp-hoverNumChooserBg);
}
.numInputWrapper span:active {
background: @fp-hoverNumChooserBg;
background: var(--fp-hoverNumChooserBg, @fp-hoverNumChooserBg);
}
.numInputWrapper span svg path {
fill: @fp-numChooserSvgFillColor;
fill: var(--fp-numChooserSvgFillColor, @fp-numChooserSvgFillColor);
}
.numInputWrapper span.arrowUp:after {
border-bottom-color: @fp-arrowColor;
border-bottom-color: var(--fp-arrowColor, @fp-arrowColor);
}
.numInputWrapper span.arrowDown:after {
border-top-color: @fp-arrowColor;
border-top-color: var(--fp-arrowColor, @fp-arrowColor);
}
.numInputWrapper:hover {
background: @fp-hoverInvertedBg;
background: var(--fp-hoverInvertedBg, @fp-hoverInvertedBg);
}
.flatpickr-current-month span.cur-month:hover {
background: @fp-hoverInvertedBg;
background: var(--fp-hoverInvertedBg, @fp-hoverInvertedBg);
}
.flatpickr-current-month .flatpickr-monthDropdown-months:hover {
background: @fp-hoverInvertedBg;
background: var(--fp-hoverInvertedBg, @fp-hoverInvertedBg);
}
.flatpickr-time input:hover,
.flatpickr-time .flatpickr-am-pm:hover,
.flatpickr-time input:focus,
.flatpickr-time .flatpickr-am-pm:focus {
background: @fp-timeHoverBg;
background: var(--fp-timeHoverBg, @fp-timeHoverBg);
}
.flatpickr-time .numInputWrapper span.arrowUp:after {
border-bottom-color: @fp-dayForeground;
border-bottom-color: var(--fp-dayForeground, @fp-dayForeground);
}
.flatpickr-time .numInputWrapper span.arrowDown:after {
border-top-color: @fp-dayForeground;
border-top-color: var(--fp-dayForeground, @fp-dayForeground);
}
.flatpickr-time input {
color: @fp-dayForeground;
color: var(--fp-dayForeground, @fp-dayForeground);
}
.flatpickr-time .flatpickr-time-separator,
.flatpickr-time .flatpickr-am-pm {
color: @fp-dayForeground;
color: var(--fp-dayForeground, @fp-dayForeground);
}
}

View File

@ -1,17 +0,0 @@
.vertical-key-value {
display: inline-block;
line-height: .75;
text-align: center;
vertical-align: middle;
.key {
font-size: 10/12em;
color: var(--default-text-color-light, @default-text-color-light);
}
.value {
color: var(--default-text-color, @default-text-color);
font-size: 1.5em;
font-weight: bold;
}
}

View File

@ -1,161 +0,0 @@
define(function () {
"use strict";
class notjQuery {
/**
* Create a new notjQuery object
*
* @param {Element} element
*/
constructor(element) {
if (! element) {
throw new Error("Can't create a notjQuery object for `" + element + "`");
}
this.element = element;
}
/**
* Add an event listener to the element
*
* @param {string} type
* @param {string} selector
* @param {function} handler
* @param {object} context
*/
on(type, selector, handler, context = null) {
if (typeof selector === 'function') {
context = handler;
handler = selector;
selector = null;
}
if (selector === null) {
this.element.addEventListener(type, e => {
if (type === 'focusin' && e.target.receivesCustomFocus) {
// Ignore native focus event if a custom one follows
if (e instanceof FocusEvent) {
delete e.target.receivesCustomFocus;
e.stopImmediatePropagation();
return;
}
}
if (context === null) {
handler.apply(e.currentTarget, [e]);
} else {
handler.apply(context, [e]);
}
});
} else {
this.element.addEventListener(type, e => {
if (type === 'focusin' && e.target.receivesCustomFocus) {
// Ignore native focus event if a custom one follows
if (e instanceof FocusEvent) {
delete e.target.receivesCustomFocus;
e.stopImmediatePropagation();
return;
}
}
Object.defineProperty(e, 'currentTarget', { value: e.currentTarget, writable: true });
let currentParent = e.currentTarget.parentNode;
for (let target = e.target; target && target !== currentParent; target = target.parentNode) {
if (target.matches(selector)) {
e.currentTarget = target;
if (context === null) {
handler.apply(target, [e]);
} else {
handler.apply(context, [e]);
}
break;
}
}
}, false);
}
}
/**
* Trigger a custom event on the element, asynchronously
*
* The event will bubble and is not cancelable.
*
* @param {string} type
* @param {{}} detail
*/
trigger(type, detail = null) {
setTimeout(() => {
this.element.dispatchEvent(new CustomEvent(type, {
cancelable: true, // TODO: this should depend on whether it's a native or custom event
bubbles: true,
detail: detail
}));
}, 0);
}
/**
* Focus the element
*
* Any other option than `preventScroll` is used as `event.detail`.
*
* @param {{}} options
*/
focus(options = {}) {
let { preventScroll = false, ...data } = options;
const hasData = Object.keys(data).length > 0;
if (hasData) {
this.element.receivesCustomFocus = true;
}
// Put separately on the event loop because focus() forces layout.
setTimeout(() => this.element.focus({ preventScroll: preventScroll }), 0);
if (hasData) {
this.trigger('focusin', data);
}
}
/**
* Render the element string as DOM Element
*
* @param {string} html
* @return {Element}
*/
static render(html) {
if (typeof html !== 'string') {
throw new Error("Can\'t render `" + html + "`");
}
let template = document.createElement('template');
template.innerHTML = html;
return template.content.firstChild;
}
}
/**
* Return a notjQuery object for the given element
*
* @param {Element} element
* @return {notjQuery}
*/
let factory = function (element) {
return new notjQuery(element);
}
// Define the static methods on the factory
for (let name of Object.getOwnPropertyNames(notjQuery)) {
if (['length', 'prototype', 'name'].includes(name)) {
continue;
}
Object.defineProperty(factory, name, {
value: notjQuery[name]
});
}
return factory;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,62 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ar = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Arabic = {
weekdays: {
shorthand: ["أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
longhand: [
"الأحد",
"الاثنين",
"الثلاثاء",
"الأربعاء",
"الخميس",
"الجمعة",
"السبت",
],
},
months: {
shorthand: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
longhand: [
"يناير",
"فبراير",
"مارس",
"أبريل",
"مايو",
"يونيو",
"يوليو",
"أغسطس",
"سبتمبر",
"أكتوبر",
"نوفمبر",
"ديسمبر",
],
},
firstDayOfWeek: 6,
rangeSeparator: " إلى ",
weekAbbreviation: "Wk",
scrollTitle: "قم بالتمرير للزيادة",
toggleTitle: "اضغط للتبديل",
amPM: ["ص", "م"],
yearAriaLabel: "سنة",
monthAriaLabel: "شهر",
hourAriaLabel: "ساعة",
minuteAriaLabel: "دقيقة",
time_24hr: false,
};
fp.l10ns.ar = Arabic;
var ar = fp.l10ns;
exports.Arabic = Arabic;
exports.default = ar;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,70 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.de = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var German = {
weekdays: {
shorthand: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
longhand: [
"Sonntag",
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
],
},
months: {
shorthand: [
"Jan",
"Feb",
"Mär",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dez",
],
longhand: [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
],
},
firstDayOfWeek: 1,
weekAbbreviation: "KW",
rangeSeparator: " bis ",
scrollTitle: "Zum Ändern scrollen",
toggleTitle: "Zum Umschalten klicken",
time_24hr: true,
};
fp.l10ns.de = German;
var de = fp.l10ns;
exports.German = German;
exports.default = de;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,70 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.es = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Spanish = {
weekdays: {
shorthand: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"],
longhand: [
"Domingo",
"Lunes",
"Martes",
"Miércoles",
"Jueves",
"Viernes",
"Sábado",
],
},
months: {
shorthand: [
"Ene",
"Feb",
"Mar",
"Abr",
"May",
"Jun",
"Jul",
"Ago",
"Sep",
"Oct",
"Nov",
"Dic",
],
longhand: [
"Enero",
"Febrero",
"Marzo",
"Abril",
"Mayo",
"Junio",
"Julio",
"Agosto",
"Septiembre",
"Octubre",
"Noviembre",
"Diciembre",
],
},
ordinal: function () {
return "º";
},
firstDayOfWeek: 1,
rangeSeparator: " a ",
time_24hr: true,
};
fp.l10ns.es = Spanish;
var es = fp.l10ns;
exports.Spanish = Spanish;
exports.default = es;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,69 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fi = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Finnish = {
firstDayOfWeek: 1,
weekdays: {
shorthand: ["su", "ma", "ti", "ke", "to", "pe", "la"],
longhand: [
"sunnuntai",
"maanantai",
"tiistai",
"keskiviikko",
"torstai",
"perjantai",
"lauantai",
],
},
months: {
shorthand: [
"tammi",
"helmi",
"maalis",
"huhti",
"touko",
"kesä",
"heinä",
"elo",
"syys",
"loka",
"marras",
"joulu",
],
longhand: [
"tammikuu",
"helmikuu",
"maaliskuu",
"huhtikuu",
"toukokuu",
"kesäkuu",
"heinäkuu",
"elokuu",
"syyskuu",
"lokakuu",
"marraskuu",
"joulukuu",
],
},
ordinal: function () {
return ".";
},
time_24hr: true,
};
fp.l10ns.fi = Finnish;
var fi = fp.l10ns;
exports.Finnish = Finnish;
exports.default = fi;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,75 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fr = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var French = {
firstDayOfWeek: 1,
weekdays: {
shorthand: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
longhand: [
"dimanche",
"lundi",
"mardi",
"mercredi",
"jeudi",
"vendredi",
"samedi",
],
},
months: {
shorthand: [
"janv",
"févr",
"mars",
"avr",
"mai",
"juin",
"juil",
"août",
"sept",
"oct",
"nov",
"déc",
],
longhand: [
"janvier",
"février",
"mars",
"avril",
"mai",
"juin",
"juillet",
"août",
"septembre",
"octobre",
"novembre",
"décembre",
],
},
ordinal: function (nth) {
if (nth > 1)
return "";
return "er";
},
rangeSeparator: " au ",
weekAbbreviation: "Sem",
scrollTitle: "Défiler pour augmenter la valeur",
toggleTitle: "Cliquer pour basculer",
time_24hr: true,
};
fp.l10ns.fr = French;
var fr = fp.l10ns;
exports.French = French;
exports.default = fr;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,71 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.it = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Italian = {
weekdays: {
shorthand: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
longhand: [
"Domenica",
"Lunedì",
"Martedì",
"Mercoledì",
"Giovedì",
"Venerdì",
"Sabato",
],
},
months: {
shorthand: [
"Gen",
"Feb",
"Mar",
"Apr",
"Mag",
"Giu",
"Lug",
"Ago",
"Set",
"Ott",
"Nov",
"Dic",
],
longhand: [
"Gennaio",
"Febbraio",
"Marzo",
"Aprile",
"Maggio",
"Giugno",
"Luglio",
"Agosto",
"Settembre",
"Ottobre",
"Novembre",
"Dicembre",
],
},
firstDayOfWeek: 1,
ordinal: function () { return "°"; },
rangeSeparator: " al ",
weekAbbreviation: "Se",
scrollTitle: "Scrolla per aumentare",
toggleTitle: "Clicca per cambiare",
time_24hr: true,
};
fp.l10ns.it = Italian;
var it = fp.l10ns;
exports.Italian = Italian;
exports.default = it;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,71 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ja = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Japanese = {
weekdays: {
shorthand: ["日", "月", "火", "水", "木", "金", "土"],
longhand: [
"日曜日",
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日",
],
},
months: {
shorthand: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
longhand: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
},
time_24hr: true,
rangeSeparator: " から ",
monthAriaLabel: "月",
amPM: ["午前", "午後"],
yearAriaLabel: "年",
hourAriaLabel: "時間",
minuteAriaLabel: "分",
};
fp.l10ns.ja = Japanese;
var ja = fp.l10ns;
exports.Japanese = Japanese;
exports.default = ja;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,66 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pt = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Portuguese = {
weekdays: {
shorthand: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
longhand: [
"Domingo",
"Segunda-feira",
"Terça-feira",
"Quarta-feira",
"Quinta-feira",
"Sexta-feira",
"Sábado",
],
},
months: {
shorthand: [
"Jan",
"Fev",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ago",
"Set",
"Out",
"Nov",
"Dez",
],
longhand: [
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro",
],
},
rangeSeparator: " até ",
time_24hr: true,
};
fp.l10ns.pt = Portuguese;
var pt = fp.l10ns;
exports.Portuguese = Portuguese;
exports.default = pt;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,75 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ru = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Russian = {
weekdays: {
shorthand: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
longhand: [
"Воскресенье",
"Понедельник",
"Вторник",
"Среда",
"Четверг",
"Пятница",
"Суббота",
],
},
months: {
shorthand: [
"Янв",
"Фев",
"Март",
"Апр",
"Май",
"Июнь",
"Июль",
"Авг",
"Сен",
"Окт",
"Ноя",
"Дек",
],
longhand: [
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь",
],
},
firstDayOfWeek: 1,
ordinal: function () {
return "";
},
rangeSeparator: " — ",
weekAbbreviation: "Нед.",
scrollTitle: "Прокрутите для увеличения",
toggleTitle: "Нажмите для переключения",
amPM: ["ДП", "ПП"],
yearAriaLabel: "Год",
time_24hr: true,
};
fp.l10ns.ru = Russian;
var ru = fp.l10ns;
exports.Russian = Russian;
exports.default = ru;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,66 +0,0 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.icinga ? define(["exports"], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.uk = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Ukrainian = {
firstDayOfWeek: 1,
weekdays: {
shorthand: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
longhand: [
"Неділя",
"Понеділок",
"Вівторок",
"Середа",
"Четвер",
"П'ятниця",
"Субота",
],
},
months: {
shorthand: [
"Січ",
"Лют",
"Бер",
"Кві",
"Тра",
"Чер",
"Лип",
"Сер",
"Вер",
"Жов",
"Лис",
"Гру",
],
longhand: [
"Січень",
"Лютий",
"Березень",
"Квітень",
"Травень",
"Червень",
"Липень",
"Серпень",
"Вересень",
"Жовтень",
"Листопад",
"Грудень",
],
},
time_24hr: true,
};
fp.l10ns.uk = Ukrainian;
var uk = fp.l10ns;
exports.Ukrainian = Ukrainian;
exports.default = uk;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@ -1,899 +0,0 @@
define(["../notjQuery", "Completer"], function ($, Completer) {
"use strict";
class BaseInput {
constructor(input) {
this.input = input;
this.disabled = false;
this.separator = '';
this.usedTerms = [];
this.completer = null;
this.lastCompletedTerm = null;
this._dataInput = null;
this._termInput = null;
this._termContainer = null;
}
get dataInput() {
if (this._dataInput === null) {
this._dataInput = document.querySelector(this.input.dataset.dataInput);
}
return this._dataInput;
}
get termInput() {
if (this._termInput === null) {
this._termInput = document.querySelector(this.input.dataset.termInput);
}
return this._termInput;
}
get termContainer() {
if (this._termContainer === null) {
this._termContainer = document.querySelector(this.input.dataset.termContainer);
}
return this._termContainer;
}
bind() {
// Form submissions
$(this.input.form).on('submit', this.onSubmit, this);
$(this.input.form).on(
'click', 'button:not([type]), button[type="submit"], input[type="submit"]', this.onButtonClick, this);
// User interactions
$(this.input).on('input', this.onInput, this);
$(this.input).on('keydown', this.onKeyDown, this);
$(this.input).on('keyup', this.onKeyUp, this);
$(this.input).on('blur', this.onInputBlur, this);
$(this.input).on('focusin', this.onTermFocus, this);
$(this.termContainer).on('input', '[data-label]', this.onInput, this);
$(this.termContainer).on('keydown', '[data-label]', this.onKeyDown, this);
$(this.termContainer).on('keyup', '[data-label]', this.onKeyUp, this);
$(this.termContainer).on('focusout', '[data-index]', this.onTermFocusOut, this);
$(this.termContainer).on('focusin', '[data-index]', this.onTermFocus, this);
// Copy/Paste
$(this.input).on('paste', this.onPaste, this);
$(this.input).on('copy', this.onCopyAndCut, this);
$(this.input).on('cut', this.onCopyAndCut, this);
// Should terms be completed?
if (this.input.dataset.suggestUrl) {
if (this.completer === null) {
this.completer = new Completer(this.input, true);
this.completer.bind(this.termContainer);
}
$(this.input).on('suggestion', this.onSuggestion, this);
$(this.input).on('completion', this.onCompletion, this);
$(this.termContainer).on('suggestion', '[data-label]', this.onSuggestion, this);
$(this.termContainer).on('completion', '[data-label]', this.onCompletion, this);
}
return this;
}
refresh(input) {
if (input === this.input) {
// If the DOM node is still the same, nothing has changed
return;
}
this._termInput = null;
this._termContainer = null;
this.input = input;
this.bind();
if (this.completer !== null) {
this.completer.refresh(input, this.termContainer);
}
if (! this.restoreTerms()) {
this.reset();
}
}
reset() {
this.usedTerms = [];
this.lastCompletedTerm = null;
this.togglePlaceholder();
this.termInput.value = '';
this.termContainer.innerHTML = '';
}
destroy() {
this._termContainer = null;
this._termInput = null;
this.input = null;
if (this.completer !== null) {
this.completer.destroy();
this.completer = null;
}
}
disable() {
this.disabled = true;
this.input.disabled = true;
this.input.form.classList.add('disabled');
this.termContainer.querySelectorAll('[data-index]').forEach(el => el.firstChild.disabled = true);
if (this.completer !== null) {
this.completer.reset();
}
}
enable() {
this.input.disabled = false;
this.input.form.classList.remove('disabled');
this.termContainer.querySelectorAll('[data-index]').forEach(el => el.firstChild.disabled = false);
this.disabled = false;
}
restoreTerms() {
if (this.hasTerms()) {
this.usedTerms.forEach((termData, termIndex) => this.addTerm(termData, termIndex));
this.togglePlaceholder();
this.clearPartialTerm(this.input);
} else {
this.registerTerms();
this.togglePlaceholder();
}
return this.hasTerms();
}
registerTerms() {
this.termContainer.querySelectorAll('[data-index]').forEach((label) => {
let termData = { ...label.dataset };
delete termData.index;
if (label.className) {
termData['class'] = label.className;
}
if (label.title) {
termData['title'] = label.title;
}
this.registerTerm(this.decodeTerm(termData), label.dataset.index);
});
}
registerTerm(termData, termIndex = null) {
if (termIndex !== null) {
this.usedTerms.splice(termIndex, 0, termData);
return termIndex;
} else {
return this.usedTerms.push(termData) - 1;
}
}
updateTerms(changedTerms) {
// Reset the data input, otherwise the value remains and is sent continuously with subsequent requests
this.dataInput.value = '';
for (const termIndex of Object.keys(changedTerms)) {
let label = this.termContainer.querySelector(`[data-index="${ termIndex }"]`);
if (! label) {
continue;
}
let input = label.firstChild;
let termData = changedTerms[termIndex];
if (termData.label) {
this.writePartialTerm(termData.label, input);
}
this.updateTermData(termData, input);
this.usedTerms[termIndex] = termData;
}
}
clearPartialTerm(input) {
if (this.completer !== null) {
this.completer.reset();
}
this.writePartialTerm('', input);
}
writePartialTerm(value, input) {
input.value = value;
this.updateTermData({ label: value }, input);
}
readPartialTerm(input) {
return input.value.trim();
}
readFullTerm(input, termIndex = null) {
let value = this.readPartialTerm(input);
if (! value) {
return false;
}
let termData = {};
if (termIndex !== null) {
termData = { ...this.usedTerms[termIndex] };
}
termData.label = value;
termData.search = value;
if (this.lastCompletedTerm !== null) {
if (termData.label === this.lastCompletedTerm.label) {
Object.assign(termData, this.lastCompletedTerm);
}
this.lastCompletedTerm = null;
}
return termData;
}
exchangeTerm() {
if (this.completer !== null) {
this.completer.reset();
}
let termData = this.readFullTerm(this.input);
if (! termData) {
return {};
}
let addedTerms = {};
if (Array.isArray(termData)) {
for (let data of termData) {
this.addTerm(data);
addedTerms[this.usedTerms.length - 1] = data;
}
} else {
this.addTerm(termData);
addedTerms[this.usedTerms.length - 1] = termData;
}
this.clearPartialTerm(this.input);
return addedTerms;
}
insertTerm(termData, termIndex) {
this.reIndexTerms(termIndex, 1, true);
this.registerTerm(termData, termIndex);
return this.insertRenderedTerm(this.renderTerm(termData, termIndex));
}
insertRenderedTerm(label) {
let next = this.termContainer.querySelector(`[data-index="${ label.dataset.index + 1 }"]`);
this.termContainer.insertBefore(label, next);
return label;
}
addTerm(termData, termIndex = null) {
if (termIndex === null) {
termIndex = this.registerTerm(termData);
}
this.addRenderedTerm(this.renderTerm(termData, termIndex));
}
addRenderedTerm(label) {
this.termContainer.appendChild(label);
}
hasTerms() {
return this.usedTerms.length > 0;
}
hasSyntaxError(input) {
if (typeof input === 'undefined') {
input = this.input;
}
return 'hasSyntaxError' in input.dataset;
}
clearSyntaxError(input) {
if (typeof input === 'undefined') {
input = this.input;
}
delete input.dataset.hasSyntaxError;
input.removeAttribute('pattern');
input.removeAttribute('title');
}
getQueryString() {
return this.termsToQueryString(this.usedTerms);
}
saveTerm(input, updateDOM = true, force = false) {
let termIndex = input.parentNode.dataset.index;
let termData = this.readFullTerm(input, termIndex);
// Only save if something has changed, unless forced
if (termData === false) {
console.warn('[BaseInput] Input is empty, cannot save');
} else if (force || this.usedTerms[termIndex].label !== termData.label) {
let oldTermData = this.usedTerms[termIndex];
this.usedTerms[termIndex] = termData;
this.updateTermData(termData, input);
return oldTermData;
}
return false;
}
updateTermData(termData, input) {
let label = input.parentNode;
label.dataset.label = termData.label;
if (!! termData.search || termData.search === '') {
label.dataset.search = termData.search;
}
if (!! termData.title) {
label.title = termData.title;
} else {
label.title = '';
}
}
termsToQueryString(terms) {
return terms.map(e => this.encodeTerm(e).search).join(this.separator).trim();
}
lastTerm() {
if (! this.hasTerms()) {
return null;
}
return this.usedTerms[this.usedTerms.length - 1];
}
popTerm() {
let lastTermIndex = this.usedTerms.length - 1;
return this.removeTerm(this.termContainer.querySelector(`[data-index="${ lastTermIndex }"]`));
}
removeTerm(label, updateDOM = true) {
if (this.completer !== null) {
this.completer.reset();
}
let termIndex = Number(label.dataset.index);
// Re-index following remaining terms
this.reIndexTerms(termIndex);
// Cut the term's data
let [termData] = this.usedTerms.splice(termIndex, 1);
// Avoid saving the term, it's removed after all
label.firstChild.skipSaveOnBlur = true;
if (updateDOM) {
// Remove it from the DOM
this.removeRenderedTerm(label);
}
return termData;
}
removeRenderedTerm(label) {
label.remove();
}
removeRange(labels) {
let from = Number(labels[0].dataset.index);
let to = Number(labels[labels.length - 1].dataset.index);
let deleteCount = to - from + 1;
if (to < this.usedTerms.length - 1) {
// Only re-index if there's something left
this.reIndexTerms(to, deleteCount);
}
let removedData = this.usedTerms.splice(from, deleteCount);
this.removeRenderedRange(labels);
let removedTerms = {};
for (let i = from; removedData.length; i++) {
removedTerms[i] = removedData.shift();
}
return removedTerms;
}
removeRenderedRange(labels) {
labels.forEach(label => this.removeRenderedTerm(label));
}
reIndexTerms(from, howMuch = 1, forward = false) {
if (forward) {
for (let i = this.usedTerms.length - 1; i >= from; i--) {
let label = this.termContainer.querySelector(`[data-index="${ i }"]`);
label.dataset.index = `${ i + howMuch }`;
}
} else {
for (let i = ++from; i < this.usedTerms.length; i++) {
let label = this.termContainer.querySelector(`[data-index="${ i }"]`);
label.dataset.index = `${ i - howMuch }`;
}
}
}
complete(input, data) {
if (this.completer !== null) {
$(input).trigger('complete', data);
}
}
selectTerms() {
this.termContainer.querySelectorAll('[data-index]').forEach(el => el.classList.add('selected'));
}
deselectTerms() {
this.termContainer.querySelectorAll('.selected').forEach(el => el.classList.remove('selected'));
}
clearSelectedTerms() {
if (this.hasTerms()) {
let labels = this.termContainer.querySelectorAll('.selected');
if (labels.length) {
return this.removeRange(Array.from(labels));
}
}
return {};
}
togglePlaceholder() {
let placeholder = '';
if (! this.hasTerms()) {
if (this.input.dataset.placeholder) {
placeholder = this.input.dataset.placeholder;
} else {
return;
}
} else if (this.input.placeholder) {
if (! this.input.dataset.placeholder) {
this.input.dataset.placeholder = this.input.placeholder;
}
}
this.input.placeholder = placeholder;
}
renderTerm(termData, termIndex) {
let label = $.render('<label><input type="text"></label>');
if (termData.class) {
label.classList.add(termData.class);
}
if (termData.title) {
label.title = termData.title;
}
label.dataset.label = termData.label;
label.dataset.search = termData.search;
label.dataset.index = termIndex;
label.firstChild.value = termData.label;
return label;
}
encodeTerm(termData) {
termData = { ...termData };
termData.search = encodeURIComponent(termData.search);
return termData;
}
decodeTerm(termData) {
termData.search = decodeURIComponent(termData.search);
return termData;
}
shouldNotAutoSubmit() {
return 'noAutoSubmit' in this.input.dataset;
}
autoSubmit(input, changeType, changedTerms) {
if (this.shouldNotAutoSubmit()) {
return;
}
if (changeType === 'save') {
// Replace old term data with the new one, as required by the backend
for (const termIndex of Object.keys(changedTerms)) {
changedTerms[termIndex] = this.usedTerms[termIndex];
}
}
this.dataInput.value = JSON.stringify({
type: changeType,
terms: changedTerms
});
if (Object.keys(changedTerms).length) {
$(this.input.form).trigger('submit', { submittedBy: input });
}
}
submitTerms(terms) {
$(this.input.form).trigger(
'submit',
{ terms: terms }
);
}
moveFocusForward(from = null) {
let toFocus;
let inputs = Array.from(this.termContainer.querySelectorAll('input'));
if (from === null) {
let focused = this.termContainer.querySelector('input:focus');
from = inputs.indexOf(focused);
}
if (from === -1) {
toFocus = inputs.shift();
} else if (from + 1 < inputs.length) {
toFocus = inputs[from + 1];
} else {
toFocus = this.input;
}
toFocus.selectionStart = toFocus.selectionEnd = 0;
$(toFocus).focus();
return toFocus;
}
moveFocusBackward(from = null) {
let toFocus;
let inputs = Array.from(this.termContainer.querySelectorAll('input'));
if (from === null) {
let focused = this.termContainer.querySelector('input:focus');
from = inputs.indexOf(focused);
}
if (from === -1) {
toFocus = inputs.pop();
} else if (from > 0 && from - 1 < inputs.length) {
toFocus = inputs[from - 1];
} else {
toFocus = this.input;
}
toFocus.selectionStart = toFocus.selectionEnd = toFocus.value.length;
$(toFocus).focus();
return toFocus;
}
/**
* Event listeners
*/
onSubmit(event) {
// Unset the input's name, to prevent its submission (It may actually have a name, as no-js fallback)
this.input.name = '';
// Set the hidden input's value, it's what's sent
if (event.detail && 'terms' in event.detail) {
this.termInput.value = event.detail.terms;
} else {
let renderedTerms = this.termsToQueryString(this.usedTerms);
if (this.hasSyntaxError()) {
renderedTerms += this.input.value;
}
this.termInput.value = renderedTerms;
}
// Enable the hidden input, otherwise it's not submitted
this.termInput.disabled = false;
}
onSuggestion(event) {
let data = event.detail;
let input = event.target;
let termData;
if (typeof data === 'object') {
termData = data;
} else {
termData = { label: data, search: data };
}
this.lastCompletedTerm = termData;
this.writePartialTerm(termData.label, input);
}
onCompletion(event) {
let input = event.target;
let termData = event.detail;
let termIndex = Number(input.parentNode.dataset.index);
this.lastCompletedTerm = termData;
this.writePartialTerm(termData.label, input);
if (termIndex >= 0) {
this.autoSubmit(input, 'save', { [termIndex]: this.saveTerm(input, false, true) });
} else {
this.autoSubmit(input, 'exchange', this.exchangeTerm());
this.togglePlaceholder();
}
}
onInput(event) {
let input = event.target;
let isTerm = input.parentNode.dataset.index >= 0;
let termData = { label: this.readPartialTerm(input) };
this.updateTermData(termData, input);
if (! input.value && this.hasSyntaxError(input)) {
this.clearSyntaxError(input);
}
if (! this.hasSyntaxError(input)) {
this.complete(input, { term: termData });
}
if (! isTerm) {
this.autoSubmit(this.input, 'remove', this.clearSelectedTerms());
this.togglePlaceholder();
}
}
onKeyDown(event) {
let input = event.target;
let termIndex = Number(input.parentNode.dataset.index);
if (this.hasSyntaxError(input) && ! (/[A-Z]/.test(event.key.charAt(0)) || event.ctrlKey || event.metaKey)) {
// Clear syntax error flag if the user types entirely new input after having selected the entire input
// (This way the input isn't empty but switches from input to input immediately, causing the clearing
// in onInput to not work)
if (input.selectionEnd - input.selectionStart === input.value.length) {
this.clearSyntaxError(input);
}
}
let removedTerms;
switch (event.key) {
case ' ':
if (! this.readPartialTerm(input)) {
this.complete(input, { term: { label: '' } });
event.preventDefault();
}
break;
case 'Backspace':
removedTerms = this.clearSelectedTerms();
if (termIndex >= 0 && ! input.value) {
let removedTerm = this.removeTerm(input.parentNode);
if (removedTerm !== false) {
input = this.moveFocusBackward(termIndex);
if (event.ctrlKey || event.metaKey) {
this.clearPartialTerm(input);
} else {
this.writePartialTerm(input.value.slice(0, -1), input);
}
removedTerms[termIndex] = removedTerm;
event.preventDefault();
}
} else if (isNaN(termIndex)) {
if (! input.value && this.hasTerms()) {
let termData = this.popTerm();
if (! event.ctrlKey && ! event.metaKey) {
// Removing the last char programmatically is not
// necessary since the browser default is not prevented
this.writePartialTerm(termData.label, input);
}
removedTerms[this.usedTerms.length] = termData;
}
}
this.togglePlaceholder();
this.autoSubmit(input, 'remove', removedTerms);
break;
case 'Delete':
removedTerms = this.clearSelectedTerms();
if (termIndex >= 0 && ! input.value) {
let removedTerm = this.removeTerm(input.parentNode);
if (removedTerm !== false) {
input = this.moveFocusForward(termIndex - 1);
if (event.ctrlKey || event.metaKey) {
this.clearPartialTerm(input);
} else {
this.writePartialTerm(input.value.slice(1), input);
}
removedTerms[termIndex] = removedTerm;
event.preventDefault();
}
}
this.togglePlaceholder();
this.autoSubmit(input, 'remove', removedTerms);
break;
case 'Enter':
if (termIndex >= 0) {
if (this.readPartialTerm(input)) {
this.saveTerm(input, false);
} else {
this.removeTerm(input.parentNode, false);
}
}
break;
case 'ArrowLeft':
if (input.selectionStart === 0 && this.hasTerms()) {
event.preventDefault();
this.moveFocusBackward();
}
break;
case 'ArrowRight':
if (input.selectionStart === input.value.length && this.hasTerms()) {
event.preventDefault();
this.moveFocusForward();
}
break;
case 'a':
if ((event.ctrlKey || event.metaKey) && ! this.readPartialTerm(input)) {
this.selectTerms();
}
}
}
onKeyUp(event) {
if (event.target.parentNode.dataset.index >= 0) {
return;
}
switch (event.key) {
case 'End':
case 'ArrowLeft':
case 'ArrowRight':
this.deselectTerms();
break;
case 'Home':
if (this.input.selectionStart === 0 && this.input.selectionEnd === 0) {
if (event.shiftKey) {
this.selectTerms();
} else {
this.deselectTerms();
}
}
break;
case 'Delete':
this.autoSubmit(event.target, 'remove', this.clearSelectedTerms());
this.togglePlaceholder();
break;
}
}
onInputBlur() {
this.deselectTerms();
}
onTermFocusOut(event) {
let input = event.target;
if (this.hasSyntaxError(input)) {
return;
}
// skipSaveOnBlur is set if the input is about to be removed anyway.
// If we remove the input as well, the other removal will fail without
// any chance to handle it. (Element.remove() blurs the input)
if (typeof input.skipSaveOnBlur === 'undefined' || ! input.skipSaveOnBlur) {
setTimeout(() => {
if (this.completer === null || ! this.completer.isBeingCompleted(input)) {
let termIndex = Number(input.parentNode.dataset.index);
if (this.readPartialTerm(input)) {
let previousTerm = this.saveTerm(input);
if (previousTerm !== false) {
this.autoSubmit(input, 'save', { [termIndex]: previousTerm });
}
} else {
this.autoSubmit(input, 'remove', { [termIndex]: this.removeTerm(input.parentNode) });
}
}
}, 0);
}
}
onTermFocus(event) {
if (event.detail.scripted) {
// Only request suggestions if the user manually focuses the term
return;
}
this.deselectTerms();
let input = event.target;
if (! this.hasSyntaxError(input) && ! this.completer.isBeingCompleted(input, false)) {
// Only request suggestions if the input is valid and not already being completed
let value = this.readPartialTerm(input);
this.complete(input, { trigger: 'script', term: { label: value } });
}
}
onButtonClick(event) {
if (! this.hasSyntaxError()) {
// Register current input value, otherwise it's not included
this.exchangeTerm();
}
if (this.hasTerms()) {
this.input.required = false;
// This is not part of `onSubmit()` because otherwise it would override what `autoSubmit()` does
this.dataInput.value = JSON.stringify({ type: 'submit', terms: this.usedTerms });
} else if (typeof this.input.dataset.manageRequired !== 'undefined') {
this.input.required = true;
}
}
onPaste(event) {
if (this.hasTerms() || this.input.value) {
return;
}
this.submitTerms(event.clipboardData.getData('text/plain'));
event.preventDefault();
}
onCopyAndCut(event) {
if (! this.hasTerms()) {
return;
}
let data = '';
let selectedTerms = this.termContainer.querySelectorAll('.selected');
if (selectedTerms.length) {
data = Array.from(selectedTerms).map(label => label.dataset.search).join(this.separator);
}
if (this.input.selectionStart < this.input.selectionEnd) {
data += this.separator + this.input.value.slice(this.input.selectionStart, this.input.selectionEnd);
}
event.clipboardData.setData('text/plain', data);
event.preventDefault();
if (event.type === 'cut') {
this.clearPartialTerm(this.input);
this.autoSubmit(this.input, 'remove', this.clearSelectedTerms());
this.togglePlaceholder();
}
}
}
return BaseInput;
});

View File

@ -1,523 +0,0 @@
define(["../notjQuery"], function ($) {
"use strict";
class Completer {
constructor(input, instrumented = false) {
this.input = input;
this.instrumented = instrumented;
this.nextSuggestion = null;
this.activeSuggestion = null;
this.suggestionKiller = null;
this.completedInput = null;
this.completedValue = null;
this.completedData = null;
this._termSuggestions = null;
}
get termSuggestions() {
if (this._termSuggestions === null) {
this._termSuggestions = document.querySelector(this.input.dataset.termSuggestions);
}
return this._termSuggestions;
}
bind(to = null) {
// Form submissions
$(this.input.form).on('submit', this.onSubmit, this);
// User interactions
$(this.termSuggestions).on('focusout', '[type="button"]', this.onFocusOut, this);
$(this.termSuggestions).on('click', '[type="button"]', this.onSuggestionClick, this);
$(this.termSuggestions).on('keydown', '[type="button"]', this.onSuggestionKeyDown, this);
if (this.instrumented) {
if (to !== null) {
$(to).on('focusout', 'input[type="text"]', this.onFocusOut, this);
$(to).on('keydown', 'input[type="text"]', this.onKeyDown, this);
$(to).on('complete', 'input[type="text"]', this.onComplete, this);
}
$(this.input).on('complete', this.onComplete, this);
} else {
$(this.input).on('input', this.onInput, this);
}
$(this.input).on('focusout', this.onFocusOut, this);
$(this.input).on('keydown', this.onKeyDown, this);
return this;
}
refresh(input, bindTo = null) {
if (input === this.input) {
// If the DOM node is still the same, nothing has changed
return;
}
this._termSuggestions = null;
this.abort();
this.input = input;
this.bind(bindTo);
}
reset() {
this.abort();
this.hideSuggestions();
}
destroy() {
this._termSuggestions = null;
this.input = null;
}
renderSuggestions(html) {
let template = document.createElement('template');
template.innerHTML = html;
return template.content;
}
showSuggestions(suggestions, input) {
this.termSuggestions.innerHTML = '';
this.termSuggestions.appendChild(suggestions);
this.termSuggestions.style.display = '';
let containingBlock = this.termSuggestions.offsetParent || document.body;
let containingBlockRect = containingBlock.getBoundingClientRect();
let inputRect = input.getBoundingClientRect();
let inputPosX = inputRect.left - containingBlockRect.left;
let inputPosY = inputRect.bottom - containingBlockRect.top;
let suggestionWidth = this.termSuggestions.offsetWidth;
let maxAvailableHeight = document.body.clientHeight - inputRect.bottom;
let localMarginBottom = window.getComputedStyle(this.termSuggestions).marginBottom;
this.termSuggestions.style.top = `${ inputPosY }px`;
this.termSuggestions.style.maxHeight = `calc(${maxAvailableHeight}px - ${localMarginBottom})`;
if (inputPosX + suggestionWidth > containingBlockRect.right - containingBlockRect.left) {
this.termSuggestions.style.left =
`${ containingBlockRect.right - containingBlockRect.left - suggestionWidth }px`;
} else {
this.termSuggestions.style.left = `${ inputPosX }px`;
}
}
hasSuggestions() {
return this.termSuggestions.childNodes.length > 0;
}
hideSuggestions() {
if (this.nextSuggestion !== null || this.activeSuggestion !== null) {
return;
}
if (this.suggestionKiller !== null) {
// onFocusOut initiates this timer in order to hide the suggestions if the user
// doesn't navigate them. Since it does this by checking after a short interval
// if the focus is inside the suggestions, the interval has to be long enough to
// have a chance to detect the focus. `focusout` runs before `blur` and `focus`,
// so this may lead to a race condition which is addressed by the timeout. Though,
// to not close the newly opened suggestions of the next input the timer has to
// be cancelled here since it's purpose is already fulfilled.
clearTimeout(this.suggestionKiller);
this.suggestionKiller = null;
}
this.termSuggestions.style.display = 'none';
this.termSuggestions.innerHTML = '';
this.completedInput = null;
this.completedValue = null;
this.completedData = null;
}
prepareCompletionData(input, data = null) {
if (data === null) {
data = { term: { ...input.dataset } };
data.term.label = input.value;
}
let value = data.term.label;
data.term.search = value;
data.term.label = this.addWildcards(value);
if (input.parentElement instanceof HTMLFieldSetElement) {
for (let element of input.parentElement.elements) {
if (element !== input
&& element.name !== input.name + '-search'
&& (element.name.substr(-7) === '-search'
|| typeof input.form[element.name + '-search'] === 'undefined')
) {
// Make sure we'll use a key that the server can understand..
let dataName = element.name;
if (dataName.substr(-7) === '-search') {
dataName = dataName.substr(0, dataName.length - 7);
}
if (dataName.substr(0, input.parentElement.name.length) === input.parentElement.name) {
dataName = dataName.substr(input.parentElement.name.length);
}
if (! dataName in data || element.value) {
data[dataName] = element.value;
}
}
}
}
return [value, data];
}
addWildcards(value) {
if (! value) {
return '*';
}
if (value.slice(0, 1) !== '*' && value.slice(-1) !== '*') {
return '*' + value + '*';
}
return value;
}
abort() {
if (this.activeSuggestion !== null) {
this.activeSuggestion.abort();
this.activeSuggestion = null;
}
if (this.nextSuggestion !== null) {
clearTimeout(this.nextSuggestion);
this.nextSuggestion = null;
}
}
requestCompletion(input, data, trigger = 'user') {
this.abort();
this.nextSuggestion = setTimeout(() => {
let req = new XMLHttpRequest();
req.open('POST', this.input.dataset.suggestUrl, true);
req.setRequestHeader('Content-Type', 'application/json');
if (typeof icinga !== 'undefined') {
let windowId = icinga.ui.getWindowId();
let containerId = icinga.ui.getUniqueContainerId(this.termSuggestions);
if (containerId) {
req.setRequestHeader('X-Icinga-WindowId', windowId + '_' + containerId);
} else {
req.setRequestHeader('X-Icinga-WindowId', windowId);
}
}
req.addEventListener('loadend', () => {
if (req.readyState > 0) {
if (req.responseText) {
let suggestions = this.renderSuggestions(req.responseText);
if (trigger === 'script') {
// If the suggestions are to be displayed due to a scripted event,
// show them only if the completed input is still focused..
if (document.activeElement === input) {
this.showSuggestions(suggestions, input);
}
} else {
this.showSuggestions(suggestions, input);
}
} else {
this.hideSuggestions();
}
}
this.activeSuggestion = null;
this.nextSuggestion = null;
});
req.send(JSON.stringify(data));
this.activeSuggestion = req;
}, 200);
}
suggest(input, value, data = {}) {
if (this.instrumented) {
if (! Object.keys(data).length) {
data = value;
}
$(input).trigger('suggestion', data);
} else {
input.value = value;
}
}
complete(input, value, data) {
$(input).focus({ scripted: true });
if (this.instrumented) {
if (! Object.keys(data).length) {
data = value;
}
$(input).trigger('completion', data);
} else {
input.value = value;
for (let name in data) {
let dataElement = input.form[input.name + '-' + name];
if (typeof dataElement !== 'undefined') {
if (dataElement instanceof RadioNodeList) {
dataElement = dataElement[dataElement.length - 1];
}
dataElement.value = data[name];
} else if (name === 'title') {
input.title = data[name];
}
}
}
this.hideSuggestions();
}
moveToSuggestion(backwards = false) {
let focused = this.termSuggestions.querySelector('[type="button"]:focus');
let inputs = Array.from(this.termSuggestions.querySelectorAll('[type="button"]'));
let input;
if (focused !== null) {
let sibling = inputs[backwards ? inputs.indexOf(focused) - 1 : inputs.indexOf(focused) + 1];
if (sibling) {
input = sibling;
} else {
input = this.completedInput;
}
} else {
input = inputs[backwards ? inputs.length - 1 : 0];
}
$(input).focus();
if (this.completedValue !== null) {
if (input === this.completedInput) {
this.suggest(this.completedInput, this.completedValue);
} else {
this.suggest(this.completedInput, input.value, { ...input.dataset });
}
}
return input;
}
isBeingCompleted(input, activeElement = null) {
if (activeElement === null) {
activeElement = document.activeElement;
}
return input === this.completedInput && (
(! activeElement && this.hasSuggestions())
|| (activeElement && this.termSuggestions.contains(activeElement))
);
}
/**
* Event listeners
*/
onSubmit(event) {
// Reset all states, the user is about to navigate away
this.reset();
}
onFocusOut(event) {
if (this.completedInput === null) {
// If there are multiple instances of Completer bound to the same suggestion container
// all of them try to handle the event. Though, only one of them is responsible and
// that's the one which has a completed input set.
return;
}
let input = event.target;
let completedInput = this.completedInput;
this.suggestionKiller = setTimeout(() => {
if (completedInput !== this.completedInput) {
// Don't hide another input's suggestions
} else if (document.activeElement !== completedInput
&& ! this.termSuggestions.contains(document.activeElement)
) {
// Hide the suggestions if the user doesn't navigate them
if (input !== completedInput) {
// Restore input if a suggestion lost focus
this.suggest(completedInput, this.completedValue);
}
this.hideSuggestions();
}
}, 250);
}
onSuggestionKeyDown(event) {
if (this.completedInput === null) {
return;
}
switch (event.key) {
case 'Escape':
$(this.completedInput).focus({ scripted: true });
this.suggest(this.completedInput, this.completedValue);
break;
case 'Tab':
event.preventDefault();
this.moveToSuggestion(event.shiftKey);
break;
case 'ArrowLeft':
case 'ArrowUp':
event.preventDefault();
this.moveToSuggestion(true);
break;
case 'ArrowRight':
case 'ArrowDown':
event.preventDefault();
this.moveToSuggestion();
break;
}
}
onSuggestionClick(event) {
if (this.completedInput === null) {
return;
}
let input = event.currentTarget;
this.complete(this.completedInput, input.value, { ...input.dataset });
}
onKeyDown(event) {
let suggestions;
switch (event.key) {
case ' ':
if (this.instrumented) {
break;
}
let input = event.target;
if (! input.value) {
if (input.minLength <= 0) {
let [value, data] = this.prepareCompletionData(input);
this.completedInput = input;
this.completedValue = value;
this.completedData = data;
this.requestCompletion(input, data);
}
event.preventDefault();
}
break;
case 'Tab':
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
if (suggestions.length === 1) {
event.preventDefault();
let input = event.target;
let suggestion = suggestions[0];
this.complete(input, suggestion.value, { ...suggestion.dataset });
}
break;
case 'Enter':
let defaultSuggestion = this.termSuggestions.querySelector('.default > [type="button"]');
if (defaultSuggestion !== null) {
event.preventDefault();
let input = event.target;
this.complete(input, defaultSuggestion.value, { ...defaultSuggestion.dataset });
}
break;
case 'Escape':
if (this.hasSuggestions()) {
this.hideSuggestions()
event.preventDefault();
}
break;
case 'ArrowUp':
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
if (suggestions.length) {
event.preventDefault();
this.moveToSuggestion(true);
}
break;
case 'ArrowDown':
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
if (suggestions.length) {
event.preventDefault();
this.moveToSuggestion();
}
break;
default:
if (/[A-Z]/.test(event.key.charAt(0)) || event.key === '"') {
// Ignore control keys not resulting in new input data
break;
}
let typedSuggestion = this.termSuggestions.querySelector(`[value="${ event.key }"]`);
if (typedSuggestion !== null) {
this.hideSuggestions();
}
}
}
onInput(event) {
let input = event.target;
if (input.minLength > 0 && input.value.length < input.minLength) {
return;
}
// Set the input's value as search value. This ensures that if the user doesn't
// choose a suggestion, an up2date contextual value will be transmitted with
// completion requests and the server can properly identify a new value upon submit
input.dataset.search = input.value;
if (typeof input.form[input.name + '-search'] !== 'undefined') {
let dataElement = input.form[input.name + '-search'];
if (dataElement instanceof RadioNodeList) {
dataElement = dataElement[dataElement.length - 1];
}
dataElement.value = input.value;
}
let [value, data] = this.prepareCompletionData(input);
this.completedInput = input;
this.completedValue = value;
this.completedData = data;
this.requestCompletion(input, data);
}
onComplete(event) {
let input = event.target;
let { trigger = 'user' , ...detail } = event.detail;
let [value, data] = this.prepareCompletionData(input, detail);
this.completedInput = input;
this.completedValue = value;
this.completedData = data;
if (typeof data.suggestions !== 'undefined') {
this.showSuggestions(data.suggestions, input);
} else {
this.requestCompletion(input, data, trigger);
}
}
}
return Completer;
});

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
define(["../notjQuery"], function ($) {
"use strict";
class SearchBar {
constructor(form) {
this.form = form;
this.filterInput = null;
}
bind() {
$(this.form.parentNode).on('click', '[data-search-editor-url]', this.onOpenerClick, this);
return this;
}
refresh(form) {
if (form === this.form) {
// If the DOM node is still the same, nothing has changed
return;
}
this.form = form;
this.bind();
}
destroy() {
this.form = null;
this.filterInput = null;
}
setFilterInput(filterInput) {
this.filterInput = filterInput;
return this;
}
onOpenerClick(event) {
let opener = event.currentTarget;
let editorUrl = opener.dataset.searchEditorUrl;
let filterQueryString = this.filterInput.getQueryString();
let layout = document.getElementById('layout');
editorUrl += (editorUrl.indexOf('?') > -1 ? '&' : '?') + filterQueryString;
// Disable pointer events to block further function calls
opener.style.pointerEvents = 'none';
let observer = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.type === 'childList') {
mutation.removedNodes.forEach((node) => {
// Remove the pointerEvent none style to make the button clickable again
// after the modal has been removed
if (node.id === 'modal') {
opener.style.pointerEvents = '';
observer.disconnect();
}
});
}
}
});
observer.observe(layout, {childList: true});
// The search editor should open in a modal. We simulate a click on an anchor
// appropriately prepared so that Icinga Web 2 will handle it natively.
let a = document.createElement('a');
a.classList.add('modal-opener');
a.href = editorUrl;
a.dataset.noIcingaAjax = '';
a.dataset.icingaModal = '';
opener.parentNode.insertBefore(a, opener.nextSibling);
a.click();
a.remove();
}
}
return SearchBar;
});

View File

@ -1,79 +0,0 @@
define(["../notjQuery", "../vendor/Sortable"], function ($, Sortable) {
"use strict";
class SearchEditor {
constructor(form) {
this.form = form;
}
bind() {
$(this.form).on('end', this.onRuleDropped, this);
this.form.querySelectorAll('ol').forEach(sortable => {
let options = {
scroll: true,
group: 'rules',
direction: 'vertical',
invertSwap: true,
handle: '.drag-initiator'
};
Sortable.create(sortable, options);
});
return this;
}
refresh(form) {
if (form === this.form) {
// If the DOM node is still the same, nothing has changed
return;
}
this.form = form;
this.bind();
}
destroy() {
this.form = null;
this.filterInput = null;
}
onRuleDropped(event) {
if (event.to === event.from && event.newIndex === event.oldIndex) {
// The user dropped the rule at its previous position
return;
}
let placement = 'before';
let neighbour = event.to.querySelector(':scope > :nth-child(' + (event.newIndex + 2) + ')');
if (! neighbour) {
// User dropped the rule at the end of a group
placement = 'after';
neighbour = event.to.querySelector(':scope > :nth-child(' + event.newIndex + ')')
if (! neighbour) {
// User dropped the rule into an empty group
placement = 'to';
neighbour = event.to.closest('[id]');
}
}
// It's a submit element, the very first one, otherwise Icinga Web 2 sends another "structural-change"
this.form.insertBefore(
$.render(
'<input type="hidden" name="structural-change[1]" value="' + placement + ':' + neighbour.id + '">'
),
this.form.firstChild
);
this.form.insertBefore(
$.render('<input type="submit" name="structural-change[0]" value="move-rule:' + event.item.id + '">'),
this.form.firstChild
);
$(this.form).trigger('submit');
}
}
return SearchEditor;
});

View File

@ -1,128 +0,0 @@
define(["BaseInput"], function (BaseInput) {
"use strict";
class TermInput extends BaseInput {
constructor(input) {
super(input);
this.separator = ' ';
this.ignoreSpaceUntil = null;
this.ignoreSpaceSince = null;
}
reset() {
super.reset();
this.ignoreSpaceUntil = null;
this.ignoreSpaceSince = null;
}
writePartialTerm(value, input) {
if (this.ignoreSpaceUntil !== null && this.ignoreSpaceSince === 0) {
value = this.ignoreSpaceUntil + value;
}
super.writePartialTerm(value, input);
}
readFullTerm(input, termIndex = null) {
let termData = super.readFullTerm(input, termIndex);
if (this.ignoreSpaceUntil !== null && termData.label[this.ignoreSpaceSince] === this.ignoreSpaceUntil) {
if (termData.label.length - 1 === this.ignoreSpaceSince
|| termData.label.slice(-1) !== this.ignoreSpaceUntil
|| (this.ignoreSpaceSince === 0 && (termData.label.length < 2
|| termData.label.slice(0, 1) !== this.ignoreSpaceUntil)
)
) {
return false;
}
}
return termData;
}
addTerm(termData, termIndex = null) {
if (this.ignoreSpaceUntil !== null) {
if (this.ignoreSpaceSince === 0 && termData.label[this.ignoreSpaceSince] === this.ignoreSpaceUntil) {
termData.label = termData.label.slice(1, -1);
}
this.ignoreSpaceUntil = null;
this.ignoreSpaceSince = null;
}
super.addTerm(termData, termIndex);
}
complete(input, data) {
data.exclude = this.usedTerms.map(termData => termData.search);
super.complete(input, data);
}
/**
* Event listeners
*/
onSubmit(event) {
super.onSubmit(event);
this.ignoreSpaceUntil = null;
this.ignoreSpaceSince = null;
}
onKeyDown(event) {
super.onKeyDown(event);
if (event.defaultPrevented) {
return;
}
let label = event.target.parentNode;
if (label.dataset.index >= 0) {
return;
}
if (event.key !== this.separator) {
return;
}
let addedTerms = this.exchangeTerm();
if (addedTerms.length) {
this.togglePlaceholder();
event.preventDefault();
this.autoSubmit(this.input, 'exchange', addedTerms);
}
}
onKeyUp(event) {
super.onKeyUp(event);
let label = event.target.parentNode;
if (label.dataset.index >= 0) {
return;
}
if (this.ignoreSpaceUntil !== null) {
// Reset if the user changes/removes the source char
let value = event.target.value;
if (value[this.ignoreSpaceSince] !== this.ignoreSpaceUntil) {
this.ignoreSpaceUntil = null;
this.ignoreSpaceSince = null;
}
}
let input = event.target;
switch (event.key) {
case '"':
case "'":
if (this.ignoreSpaceUntil === null) {
this.ignoreSpaceUntil = event.key;
this.ignoreSpaceSince = input.selectionStart - 1;
}
}
}
}
return TermInput;
});

Binary file not shown.

View File

@ -1,13 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="Icinga-Icons" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="minimal" d="M192.009 831.995c0-35.361-28.665-64.026-64.026-64.026s-64.026 28.665-64.026 64.026c0 35.361 28.665 64.026 64.026 64.026s64.026-28.665 64.026-64.026zM192.009 639.671c0-35.361-28.665-64.026-64.026-64.026s-64.026 28.665-64.026 64.026c0 35.361 28.665 64.026 64.026 64.026s64.026-28.665 64.026-64.026zM192.009 447.671c0-35.361-28.665-64.026-64.026-64.026s-64.026 28.665-64.026 64.026c0 35.361 28.665 64.026 64.026 64.026s64.026-28.665 64.026-64.026zM256.005 863.997h704.001v-64.005h-704.001v64.005zM256.005 479.674h704.001v-64.005h-704.001v64.005zM256.005 671.674h704.001v-64.005h-704.001v64.005zM256.005 287.674h704.001v-64.005h-704.001v64.005zM256.005 95.674h704.001v-64.005h-704.001v64.005zM192.009 255.348c0-35.361-28.665-64.026-64.026-64.026s-64.026 28.665-64.026 64.026c0 35.361 28.665 64.026 64.026 64.026s64.026-28.665 64.026-64.026zM192.009 63.671c0-35.361-28.665-64.026-64.026-64.026s-64.026 28.665-64.026 64.026c0 35.361 28.665 64.026 64.026 64.026s64.026-28.665 64.026-64.026z" />
<glyph unicode="&#xe901;" glyph-name="detailed" d="M320.007 831.679h639.993v-191.358h-639.993v191.358zM320.007 575.997h639.993v-63.992h-639.993v63.992zM256.014 736.317c0-53.041-42.998-96.039-96.039-96.039s-96.039 42.998-96.039 96.039c0 53.041 42.998 96.039 96.039 96.039s96.039-42.998 96.039-96.039zM256.014 287.992c0-53.041-42.998-96.039-96.039-96.039s-96.039 42.998-96.039 96.039c0 53.041 42.998 96.039 96.039 96.039s96.039-42.998 96.039-96.039zM320.007 384.004h639.993v-192.005h-639.993v192.005zM320.007 128.005h639.993v-63.992h-639.993v63.992z" />
<glyph unicode="&#xe902;" glyph-name="default" d="M256.015 767.992c0-53.041-42.998-96.039-96.039-96.039s-96.039 42.998-96.039 96.039c0 53.041 42.998 96.039 96.039 96.039s96.039-42.998 96.039-96.039zM384.001 864h576.002v-192.008h-576.002v192.008zM384.001 543.998h576.002v-192.008h-576.002v192.008zM384.001 223.998h576.002v-192.008h-576.002v192.008zM256.015 447.99c0-53.041-42.998-96.039-96.039-96.039s-96.039 42.998-96.039 96.039c0 53.041 42.998 96.039 96.039 96.039s96.039-42.998 96.039-96.039zM256.015 127.99c0-53.041-42.998-96.039-96.039-96.039s-96.039 42.998-96.039 96.039c0 53.041 42.998 96.039 96.039 96.039s96.039-42.998 96.039-96.039z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
<svg height="32" viewBox="0 0 24 32" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m5.20126707.78766623 4.45386238 4.20402191c.16721345.15783356.16291017.40979541-.00961164.56277256-.081158.0719638-.18974398.11220597-.3027668.11220597h-8.90772462c-.24025844 0-.43502639-.17818569-.43502639-.39798892 0-.10340014.04398717-.20274128.12264801-.27698961l4.45386234-4.20402191c.16721345-.15783357.44262326-.16177048.61514507-.00879333.00325382.00288518.00645805.00581661.00961165.00879333z" fill="#282E39" transform="matrix(1 0 0 -1 7 20.666667)"/></svg>

Before

Width:  |  Height:  |  Size: 559 B

View File

@ -1 +0,0 @@
<svg height="32" viewBox="0 0 24 32" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m5.20126707.78766623 4.45386238 4.20402191c.16721345.15783356.16291017.40979541-.00961164.56277256-.081158.0719638-.18974398.11220597-.3027668.11220597h-8.90772462c-.24025844 0-.43502639-.17818569-.43502639-.39798892 0-.10340014.04398717-.20274128.12264801-.27698961l4.45386234-4.20402191c.16721345-.15783357.44262326-.16177048.61514507-.00879333.00325382.00288518.00645805.00581661.00961165.00879333z" fill="#00c3ed" transform="matrix(1 0 0 -1 7 20.666667)"/></svg>

Before

Width:  |  Height:  |  Size: 558 B

View File

@ -35,15 +35,15 @@ rm -rf asset vendor
rm -f composer.lock
composer install --no-scripts || fail "composer install failed"
composer run-script post-update-cmd -- copy-assets
find vendor/ -type f -name "*.php" \
| grep -v '/examples/' \
| grep -v '/example/' \
| grep -v '/tests/' \
| grep -v '/test/' \
| xargs -L1 git add -f
find vendor/ -type f -name LICENSE | xargs -L1 git add -f
find vendor/ -type f -name '*.json' | xargs -L1 git add -f
find asset/ -type f | xargs -L1 git add -f
find vendor/ -type f -name "*.php" -print0 \
| grep -z -v '/examples/' \
| grep -z -v '/example/' \
| grep -z -v '/tests/' \
| grep -z -v '/test/' \
| xargs -0 -L1 git add -f
find vendor/ -type f -name LICENSE -print0 | xargs -0 -L1 git add -f
find vendor/ -type f -name '*.json' -print0 | xargs -0 -L1 git add -f
find asset/ -type f -print0 | xargs -0 -L1 git add -f
echo "v$VERSION" > VERSION
git add VERSION
git add composer.lock -f

View File

@ -21,16 +21,19 @@ fi
git checkout -b $BRANCH
git merge --no-ff -m "Merge latest tag, to make it reachable for git-describe" $LATEST_TAG
composer config platform.php $PHP_VERSION
composer require --no-update \
php:$PHP_VERSION \
ipl/html:"dev-master as 99.x-dev" \
ipl/i18n:"dev-master as 99.x-dev" \
ipl/orm:"dev-master as 99.x-dev" \
ipl/sql:"dev-master as 99.x-dev" \
ipl/stdlib:"dev-master as 99.x-dev" \
ipl/validator:"dev-master as 99.x-dev" \
ipl/web:"dev-master as 99.x-dev"
composer config minimum-stability dev
composer config prefer-stable true
git commit -a -m "Require dev-master everywhere"
composer require --no-update \
php:">=$PHP_VERSION" \
ipl/html:"dev-main as 99.x-dev" \
ipl/i18n:"dev-main as 99.x-dev" \
ipl/orm:"dev-main as 99.x-dev" \
ipl/scheduler:"dev-main as 99.x-dev" \
ipl/sql:"dev-main as 99.x-dev" \
ipl/stdlib:"dev-main as 99.x-dev" \
ipl/validator:"dev-main as 99.x-dev" \
ipl/web:"dev-main as 99.x-dev"
git commit -a -m "Require dev-main everywhere"
bin/make-release.sh "$NEXT_VERSION-dev" --no-checkout

View File

@ -7,18 +7,19 @@
"config": {
"sort-packages": true,
"platform": {
"php": "7.2"
"php": "8.2"
}
},
"require": {
"php": ">=7.2",
"ipl/html": "^0.6.0",
"php": ">=8.2",
"ipl/html": "^0.8.0",
"ipl/i18n": "^0.2.0",
"ipl/orm": "^0.4.0",
"ipl/sql": "^0.5.0",
"ipl/stdlib": "^0.12.0",
"ipl/validator": "^0.4.0",
"ipl/web": "^0.6.0"
"ipl/orm": "^0.7.0",
"ipl/scheduler": "^0.1.0",
"ipl/sql": "^0.7.0",
"ipl/stdlib": "^0.14.0",
"ipl/validator": "^0.5.0",
"ipl/web": "^0.11.0"
},
"require-dev": {
},

465
composer.lock generated
View File

@ -1,465 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "4dcf41bc81f084366c52bc6de627e4fb",
"packages": [
{
"name": "evenement/evenement",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/igorw/evenement.git",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"shasum": ""
},
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Evenement": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"description": "Événement is a very simple event dispatching library for PHP",
"keywords": [
"event-dispatcher",
"event-emitter"
],
"support": {
"issues": "https://github.com/igorw/evenement/issues",
"source": "https://github.com/igorw/evenement/tree/master"
},
"time": "2017-07-23T21:35:13+00:00"
},
{
"name": "fortawesome/font-awesome",
"version": "6.2.0",
"source": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome.git",
"reference": "d3a7818c253fcbafff9ebd1d4abb2866c192e1d7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FortAwesome/Font-Awesome/zipball/d3a7818c253fcbafff9ebd1d4abb2866c192e1d7",
"reference": "d3a7818c253fcbafff9ebd1d4abb2866c192e1d7",
"shasum": ""
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"CC-BY-4.0",
"OFL-1.1",
"MIT"
],
"authors": [
{
"name": "The Font Awesome Team",
"homepage": "https://github.com/orgs/FortAwesome/people"
}
],
"description": "The iconic font, CSS, and SVG framework",
"homepage": "https://fontawesome.com",
"keywords": [
"FontAwesome",
"awesome",
"bootstrap",
"font",
"icon",
"svg"
],
"support": {
"docs": "http://fontawesome.com/docs",
"email": "hello@fontawesome.com",
"issues": "https://github.com/FortAwesome/Font-Awesome/issues",
"source": "https://github.com/FortAwesome/Font-Awesome"
},
"time": "2022-08-31T21:02:43+00:00"
},
{
"name": "ipl/html",
"version": "v0.6.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-html.git",
"reference": "239b215ab81205f69d8df2663b0fecb138562547"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-html/zipball/239b215ab81205f69d8df2663b0fecb138562547",
"reference": "239b215ab81205f69d8df2663b0fecb138562547",
"shasum": ""
},
"require": {
"ipl/stdlib": ">=0.12.0",
"ipl/validator": ">=0.4.0",
"php": ">=7.2",
"psr/http-message": "~1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"ipl\\Html\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - HTML abstraction layer",
"homepage": "https://github.com/Icinga/ipl-html",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/Icinga/ipl-html/issues",
"source": "https://github.com/Icinga/ipl-html/tree/v0.6.0"
},
"time": "2022-06-15T08:17:00+00:00"
},
{
"name": "ipl/i18n",
"version": "v0.2.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-i18n.git",
"reference": "3ee2a8c0c38879cb743c866d9202f8620d4c2800"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-i18n/zipball/3ee2a8c0c38879cb743c866d9202f8620d4c2800",
"reference": "3ee2a8c0c38879cb743c866d9202f8620d4c2800",
"shasum": ""
},
"require": {
"ext-gettext": "*",
"ext-intl": "*",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"type": "library",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"ipl\\I18n\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Internationalization",
"homepage": "https://github.com/Icinga/ipl-i18n",
"keywords": [
"gettext",
"i18n",
"internationalization",
"localization",
"translation"
],
"support": {
"issues": "https://github.com/Icinga/ipl-i18n/issues",
"source": "https://github.com/Icinga/ipl-i18n/tree/v0.2.0"
},
"time": "2022-06-15T07:33:40+00:00"
},
{
"name": "ipl/orm",
"version": "v0.4.1",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-orm.git",
"reference": "0b76de078b9ebff608ce07b1ea051fa7d82f6261"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-orm/zipball/0b76de078b9ebff608ce07b1ea051fa7d82f6261",
"reference": "0b76de078b9ebff608ce07b1ea051fa7d82f6261",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ipl/sql": ">=0.5.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"require-dev": {
"ext-pdo_sqlite": "*"
},
"type": "library",
"autoload": {
"psr-4": {
"ipl\\Orm\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - ORM",
"homepage": "https://github.com/Icinga/ipl-orm",
"keywords": [
"database",
"orm",
"sql"
],
"support": {
"issues": "https://github.com/Icinga/ipl-orm/issues",
"source": "https://github.com/Icinga/ipl-orm/tree/v0.4.1"
},
"time": "2022-07-01T16:15:30+00:00"
},
{
"name": "ipl/sql",
"version": "v0.5.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-sql.git",
"reference": "cbe5d0854ef0612c7108b84b0864b4e69e81afd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-sql/zipball/cbe5d0854ef0612c7108b84b0864b4e69e81afd1",
"reference": "cbe5d0854ef0612c7108b84b0864b4e69e81afd1",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"type": "library",
"autoload": {
"psr-4": {
"ipl\\Sql\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - SQL abstraction layer",
"homepage": "https://github.com/Icinga/ipl-sql",
"keywords": [
"database",
"sql"
],
"support": {
"issues": "https://github.com/Icinga/ipl-sql/issues",
"source": "https://github.com/Icinga/ipl-sql/tree/v0.5.0"
},
"time": "2022-06-15T08:43:21+00:00"
},
{
"name": "ipl/stdlib",
"version": "v0.12.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-stdlib.git",
"reference": "d42a16122975a629ab7d60eff780b9fd9949545e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-stdlib/zipball/d42a16122975a629ab7d60eff780b9fd9949545e",
"reference": "d42a16122975a629ab7d60eff780b9fd9949545e",
"shasum": ""
},
"require": {
"evenement/evenement": "^3",
"ext-openssl": "*",
"php": ">=7.2"
},
"type": "library",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"ipl\\Stdlib\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ipl Standard Library",
"support": {
"issues": "https://github.com/Icinga/ipl-stdlib/issues",
"source": "https://github.com/Icinga/ipl-stdlib/tree/v0.12.0"
},
"time": "2022-06-15T07:29:19+00:00"
},
{
"name": "ipl/validator",
"version": "v0.4.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-validator.git",
"reference": "b8af9ef02654e04b63c6f28507a80270f5248ecb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-validator/zipball/b8af9ef02654e04b63c6f28507a80270f5248ecb",
"reference": "b8af9ef02654e04b63c6f28507a80270f5248ecb",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"ipl/i18n": ">=0.2.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"type": "library",
"autoload": {
"psr-4": {
"ipl\\Validator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Common validators and validator chaining",
"homepage": "https://github.com/Icinga/ipl-validator",
"support": {
"issues": "https://github.com/Icinga/ipl-validator/issues",
"source": "https://github.com/Icinga/ipl-validator/tree/v0.4.0"
},
"time": "2022-06-15T07:51:54+00:00"
},
{
"name": "ipl/web",
"version": "v0.6.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-web.git",
"reference": "ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-web/zipball/ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb",
"reference": "ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb",
"shasum": ""
},
"require": {
"ext-json": "*",
"fortawesome/font-awesome": "^6",
"ipl/html": ">=0.6.0",
"ipl/i18n": ">=0.2.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"type": "library",
"autoload": {
"psr-4": {
"ipl\\Web\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Web Components",
"homepage": "https://github.com/Icinga/ipl-web",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/Icinga/ipl-web/issues",
"source": "https://github.com/Icinga/ipl-web/tree/v0.6.0"
},
"time": "2022-09-05T11:47:43+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/master"
},
"time": "2016-08-06T14:39:51+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=7.2"
},
"platform-dev": [],
"platform-overrides": {
"php": "7.2"
},
"plugin-api-version": "2.3.0"
}

12
vendor/autoload.php vendored
View File

@ -1,12 +0,0 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
exit(1);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitbe48dd8f3931e20093e0530ca745d6b1::getLoader();

View File

@ -1,572 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
* @private
*/
function includeFile($file)
{
include $file;
}

View File

@ -1,352 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
$installed[] = self::$installed;
return $installed;
}
}

View File

@ -1,21 +0,0 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,10 +0,0 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

View File

@ -1,11 +0,0 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'a2c78434f64e5f5ed402f42eee19c025' => $vendorDir . '/ipl/stdlib/src/functions_include.php',
'6076de347104821999fcfc82c8f19bc5' => $vendorDir . '/ipl/i18n/src/functions_include.php',
);

View File

@ -1,11 +0,0 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Evenement' => array($vendorDir . '/evenement/evenement/src'),
'AssetLoader' => array($baseDir . '/'),
);

View File

@ -1,17 +0,0 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'ipl\\Web\\' => array($vendorDir . '/ipl/web/src'),
'ipl\\Validator\\' => array($vendorDir . '/ipl/validator/src'),
'ipl\\Stdlib\\' => array($vendorDir . '/ipl/stdlib/src'),
'ipl\\Sql\\' => array($vendorDir . '/ipl/sql/src'),
'ipl\\Orm\\' => array($vendorDir . '/ipl/orm/src'),
'ipl\\I18n\\' => array($vendorDir . '/ipl/i18n/src'),
'ipl\\Html\\' => array($vendorDir . '/ipl/html/src'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
);

View File

@ -1,57 +0,0 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitbe48dd8f3931e20093e0530ca745d6b1
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInitbe48dd8f3931e20093e0530ca745d6b1', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitbe48dd8f3931e20093e0530ca745d6b1', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::getInitializer($loader));
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirebe48dd8f3931e20093e0530ca745d6b1($fileIdentifier, $file);
}
return $loader;
}
}
/**
* @param string $fileIdentifier
* @param string $file
* @return void
*/
function composerRequirebe48dd8f3931e20093e0530ca745d6b1($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}

View File

@ -1,97 +0,0 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1
{
public static $files = array (
'a2c78434f64e5f5ed402f42eee19c025' => __DIR__ . '/..' . '/ipl/stdlib/src/functions_include.php',
'6076de347104821999fcfc82c8f19bc5' => __DIR__ . '/..' . '/ipl/i18n/src/functions_include.php',
);
public static $prefixLengthsPsr4 = array (
'i' =>
array (
'ipl\\Web\\' => 8,
'ipl\\Validator\\' => 14,
'ipl\\Stdlib\\' => 11,
'ipl\\Sql\\' => 8,
'ipl\\Orm\\' => 8,
'ipl\\I18n\\' => 9,
'ipl\\Html\\' => 9,
),
'P' =>
array (
'Psr\\Http\\Message\\' => 17,
),
);
public static $prefixDirsPsr4 = array (
'ipl\\Web\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/web/src',
),
'ipl\\Validator\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/validator/src',
),
'ipl\\Stdlib\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/stdlib/src',
),
'ipl\\Sql\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/sql/src',
),
'ipl\\Orm\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/orm/src',
),
'ipl\\I18n\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/i18n/src',
),
'ipl\\Html\\' =>
array (
0 => __DIR__ . '/..' . '/ipl/html/src',
),
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-message/src',
),
);
public static $prefixesPsr0 = array (
'E' =>
array (
'Evenement' =>
array (
0 => __DIR__ . '/..' . '/evenement/evenement/src',
),
),
'A' =>
array (
'AssetLoader' =>
array (
0 => __DIR__ . '/../..' . '/',
),
),
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::$prefixesPsr0;
$loader->classMap = ComposerStaticInitbe48dd8f3931e20093e0530ca745d6b1::$classMap;
}, null, ClassLoader::class);
}
}

View File

@ -1,477 +0,0 @@
{
"packages": [
{
"name": "evenement/evenement",
"version": "v3.0.1",
"version_normalized": "3.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/igorw/evenement.git",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
"shasum": ""
},
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
},
"time": "2017-07-23T21:35:13+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Evenement": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"description": "Événement is a very simple event dispatching library for PHP",
"keywords": [
"event-dispatcher",
"event-emitter"
],
"support": {
"issues": "https://github.com/igorw/evenement/issues",
"source": "https://github.com/igorw/evenement/tree/master"
},
"install-path": "../evenement/evenement"
},
{
"name": "fortawesome/font-awesome",
"version": "6.2.0",
"version_normalized": "6.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome.git",
"reference": "d3a7818c253fcbafff9ebd1d4abb2866c192e1d7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FortAwesome/Font-Awesome/zipball/d3a7818c253fcbafff9ebd1d4abb2866c192e1d7",
"reference": "d3a7818c253fcbafff9ebd1d4abb2866c192e1d7",
"shasum": ""
},
"time": "2022-08-31T21:02:43+00:00",
"type": "library",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
"license": [
"CC-BY-4.0",
"OFL-1.1",
"MIT"
],
"authors": [
{
"name": "The Font Awesome Team",
"homepage": "https://github.com/orgs/FortAwesome/people"
}
],
"description": "The iconic font, CSS, and SVG framework",
"homepage": "https://fontawesome.com",
"keywords": [
"FontAwesome",
"awesome",
"bootstrap",
"font",
"icon",
"svg"
],
"support": {
"docs": "http://fontawesome.com/docs",
"email": "hello@fontawesome.com",
"issues": "https://github.com/FortAwesome/Font-Awesome/issues",
"source": "https://github.com/FortAwesome/Font-Awesome"
},
"install-path": "../fortawesome/font-awesome"
},
{
"name": "ipl/html",
"version": "v0.6.0",
"version_normalized": "0.6.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-html.git",
"reference": "239b215ab81205f69d8df2663b0fecb138562547"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-html/zipball/239b215ab81205f69d8df2663b0fecb138562547",
"reference": "239b215ab81205f69d8df2663b0fecb138562547",
"shasum": ""
},
"require": {
"ipl/stdlib": ">=0.12.0",
"ipl/validator": ">=0.4.0",
"php": ">=7.2",
"psr/http-message": "~1.0"
},
"time": "2022-06-15T08:17:00+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ipl\\Html\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - HTML abstraction layer",
"homepage": "https://github.com/Icinga/ipl-html",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/Icinga/ipl-html/issues",
"source": "https://github.com/Icinga/ipl-html/tree/v0.6.0"
},
"install-path": "../ipl/html"
},
{
"name": "ipl/i18n",
"version": "v0.2.0",
"version_normalized": "0.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-i18n.git",
"reference": "3ee2a8c0c38879cb743c866d9202f8620d4c2800"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-i18n/zipball/3ee2a8c0c38879cb743c866d9202f8620d4c2800",
"reference": "3ee2a8c0c38879cb743c866d9202f8620d4c2800",
"shasum": ""
},
"require": {
"ext-gettext": "*",
"ext-intl": "*",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"time": "2022-06-15T07:33:40+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"ipl\\I18n\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Internationalization",
"homepage": "https://github.com/Icinga/ipl-i18n",
"keywords": [
"gettext",
"i18n",
"internationalization",
"localization",
"translation"
],
"support": {
"issues": "https://github.com/Icinga/ipl-i18n/issues",
"source": "https://github.com/Icinga/ipl-i18n/tree/v0.2.0"
},
"install-path": "../ipl/i18n"
},
{
"name": "ipl/orm",
"version": "v0.4.1",
"version_normalized": "0.4.1.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-orm.git",
"reference": "0b76de078b9ebff608ce07b1ea051fa7d82f6261"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-orm/zipball/0b76de078b9ebff608ce07b1ea051fa7d82f6261",
"reference": "0b76de078b9ebff608ce07b1ea051fa7d82f6261",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ipl/sql": ">=0.5.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"require-dev": {
"ext-pdo_sqlite": "*"
},
"time": "2022-07-01T16:15:30+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ipl\\Orm\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - ORM",
"homepage": "https://github.com/Icinga/ipl-orm",
"keywords": [
"database",
"orm",
"sql"
],
"support": {
"issues": "https://github.com/Icinga/ipl-orm/issues",
"source": "https://github.com/Icinga/ipl-orm/tree/v0.4.1"
},
"install-path": "../ipl/orm"
},
{
"name": "ipl/sql",
"version": "v0.5.0",
"version_normalized": "0.5.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-sql.git",
"reference": "cbe5d0854ef0612c7108b84b0864b4e69e81afd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-sql/zipball/cbe5d0854ef0612c7108b84b0864b4e69e81afd1",
"reference": "cbe5d0854ef0612c7108b84b0864b4e69e81afd1",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"time": "2022-06-15T08:43:21+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ipl\\Sql\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - SQL abstraction layer",
"homepage": "https://github.com/Icinga/ipl-sql",
"keywords": [
"database",
"sql"
],
"support": {
"issues": "https://github.com/Icinga/ipl-sql/issues",
"source": "https://github.com/Icinga/ipl-sql/tree/v0.5.0"
},
"install-path": "../ipl/sql"
},
{
"name": "ipl/stdlib",
"version": "v0.12.0",
"version_normalized": "0.12.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-stdlib.git",
"reference": "d42a16122975a629ab7d60eff780b9fd9949545e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-stdlib/zipball/d42a16122975a629ab7d60eff780b9fd9949545e",
"reference": "d42a16122975a629ab7d60eff780b9fd9949545e",
"shasum": ""
},
"require": {
"evenement/evenement": "^3",
"ext-openssl": "*",
"php": ">=7.2"
},
"time": "2022-06-15T07:29:19+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"ipl\\Stdlib\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "ipl Standard Library",
"support": {
"issues": "https://github.com/Icinga/ipl-stdlib/issues",
"source": "https://github.com/Icinga/ipl-stdlib/tree/v0.12.0"
},
"install-path": "../ipl/stdlib"
},
{
"name": "ipl/validator",
"version": "v0.4.0",
"version_normalized": "0.4.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-validator.git",
"reference": "b8af9ef02654e04b63c6f28507a80270f5248ecb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-validator/zipball/b8af9ef02654e04b63c6f28507a80270f5248ecb",
"reference": "b8af9ef02654e04b63c6f28507a80270f5248ecb",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"ipl/i18n": ">=0.2.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"time": "2022-06-15T07:51:54+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ipl\\Validator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Common validators and validator chaining",
"homepage": "https://github.com/Icinga/ipl-validator",
"support": {
"issues": "https://github.com/Icinga/ipl-validator/issues",
"source": "https://github.com/Icinga/ipl-validator/tree/v0.4.0"
},
"install-path": "../ipl/validator"
},
{
"name": "ipl/web",
"version": "v0.6.0",
"version_normalized": "0.6.0.0",
"source": {
"type": "git",
"url": "https://github.com/Icinga/ipl-web.git",
"reference": "ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Icinga/ipl-web/zipball/ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb",
"reference": "ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb",
"shasum": ""
},
"require": {
"ext-json": "*",
"fortawesome/font-awesome": "^6",
"ipl/html": ">=0.6.0",
"ipl/i18n": ">=0.2.0",
"ipl/stdlib": ">=0.12.0",
"php": ">=7.2"
},
"time": "2022-09-05T11:47:43+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ipl\\Web\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Icinga PHP Library - Web Components",
"homepage": "https://github.com/Icinga/ipl-web",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/Icinga/ipl-web/issues",
"source": "https://github.com/Icinga/ipl-web/tree/v0.6.0"
},
"install-path": "../ipl/web"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2016-08-06T14:39:51+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/master"
},
"install-path": "../psr/http-message"
}
],
"dev": true,
"dev-package-names": []
}

View File

@ -1,113 +0,0 @@
<?php return array(
'root' => array(
'name' => 'icinga/icinga-php-library',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '58eee4d45eebb65ea4cb97a17c848d6e4814c9c1',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'evenement/evenement' => array(
'pretty_version' => 'v3.0.1',
'version' => '3.0.1.0',
'reference' => '531bfb9d15f8aa57454f5f0285b18bec903b8fb7',
'type' => 'library',
'install_path' => __DIR__ . '/../evenement/evenement',
'aliases' => array(),
'dev_requirement' => false,
),
'fortawesome/font-awesome' => array(
'pretty_version' => '6.2.0',
'version' => '6.2.0.0',
'reference' => 'd3a7818c253fcbafff9ebd1d4abb2866c192e1d7',
'type' => 'library',
'install_path' => __DIR__ . '/../fortawesome/font-awesome',
'aliases' => array(),
'dev_requirement' => false,
),
'icinga/icinga-php-library' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '58eee4d45eebb65ea4cb97a17c848d6e4814c9c1',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/html' => array(
'pretty_version' => 'v0.6.0',
'version' => '0.6.0.0',
'reference' => '239b215ab81205f69d8df2663b0fecb138562547',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/html',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/i18n' => array(
'pretty_version' => 'v0.2.0',
'version' => '0.2.0.0',
'reference' => '3ee2a8c0c38879cb743c866d9202f8620d4c2800',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/i18n',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/orm' => array(
'pretty_version' => 'v0.4.1',
'version' => '0.4.1.0',
'reference' => '0b76de078b9ebff608ce07b1ea051fa7d82f6261',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/orm',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/sql' => array(
'pretty_version' => 'v0.5.0',
'version' => '0.5.0.0',
'reference' => 'cbe5d0854ef0612c7108b84b0864b4e69e81afd1',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/sql',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/stdlib' => array(
'pretty_version' => 'v0.12.0',
'version' => '0.12.0.0',
'reference' => 'd42a16122975a629ab7d60eff780b9fd9949545e',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/stdlib',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/validator' => array(
'pretty_version' => 'v0.4.0',
'version' => '0.4.0.0',
'reference' => 'b8af9ef02654e04b63c6f28507a80270f5248ecb',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/validator',
'aliases' => array(),
'dev_requirement' => false,
),
'ipl/web' => array(
'pretty_version' => 'v0.6.0',
'version' => '0.6.0.0',
'reference' => 'ded069e649f0c4dccca27b36bd6d6d3f34d5bfcb',
'type' => 'library',
'install_path' => __DIR__ . '/../ipl/web',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@ -1,26 +0,0 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70200)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@ -1,19 +0,0 @@
Copyright (c) 2011 Igor Wiedler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,29 +0,0 @@
{
"name": "evenement/evenement",
"description": "Événement is a very simple event dispatching library for PHP",
"keywords": ["event-dispatcher", "event-emitter"],
"license": "MIT",
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
},
"autoload": {
"psr-0": {
"Evenement": "src"
}
},
"autoload-dev": {
"psr-0": {
"Evenement": "tests"
},
"files": ["tests/Evenement/Tests/functions.php"]
}
}

View File

@ -1,17 +0,0 @@
<?php declare(strict_types=1);
/*
* This file is part of Evenement.
*
* (c) Igor Wiedler <igor@wiedler.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Evenement;
class EventEmitter implements EventEmitterInterface
{
use EventEmitterTrait;
}

View File

@ -1,22 +0,0 @@
<?php declare(strict_types=1);
/*
* This file is part of Evenement.
*
* (c) Igor Wiedler <igor@wiedler.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Evenement;
interface EventEmitterInterface
{
public function on($event, callable $listener);
public function once($event, callable $listener);
public function removeListener($event, callable $listener);
public function removeAllListeners($event = null);
public function listeners($event = null);
public function emit($event, array $arguments = []);
}

View File

@ -1,135 +0,0 @@
<?php declare(strict_types=1);
/*
* This file is part of Evenement.
*
* (c) Igor Wiedler <igor@wiedler.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Evenement;
use InvalidArgumentException;
trait EventEmitterTrait
{
protected $listeners = [];
protected $onceListeners = [];
public function on($event, callable $listener)
{
if ($event === null) {
throw new InvalidArgumentException('event name must not be null');
}
if (!isset($this->listeners[$event])) {
$this->listeners[$event] = [];
}
$this->listeners[$event][] = $listener;
return $this;
}
public function once($event, callable $listener)
{
if ($event === null) {
throw new InvalidArgumentException('event name must not be null');
}
if (!isset($this->onceListeners[$event])) {
$this->onceListeners[$event] = [];
}
$this->onceListeners[$event][] = $listener;
return $this;
}
public function removeListener($event, callable $listener)
{
if ($event === null) {
throw new InvalidArgumentException('event name must not be null');
}
if (isset($this->listeners[$event])) {
$index = \array_search($listener, $this->listeners[$event], true);
if (false !== $index) {
unset($this->listeners[$event][$index]);
if (\count($this->listeners[$event]) === 0) {
unset($this->listeners[$event]);
}
}
}
if (isset($this->onceListeners[$event])) {
$index = \array_search($listener, $this->onceListeners[$event], true);
if (false !== $index) {
unset($this->onceListeners[$event][$index]);
if (\count($this->onceListeners[$event]) === 0) {
unset($this->onceListeners[$event]);
}
}
}
}
public function removeAllListeners($event = null)
{
if ($event !== null) {
unset($this->listeners[$event]);
} else {
$this->listeners = [];
}
if ($event !== null) {
unset($this->onceListeners[$event]);
} else {
$this->onceListeners = [];
}
}
public function listeners($event = null): array
{
if ($event === null) {
$events = [];
$eventNames = \array_unique(
\array_merge(\array_keys($this->listeners), \array_keys($this->onceListeners))
);
foreach ($eventNames as $eventName) {
$events[$eventName] = \array_merge(
isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : [],
isset($this->onceListeners[$eventName]) ? $this->onceListeners[$eventName] : []
);
}
return $events;
}
return \array_merge(
isset($this->listeners[$event]) ? $this->listeners[$event] : [],
isset($this->onceListeners[$event]) ? $this->onceListeners[$event] : []
);
}
public function emit($event, array $arguments = [])
{
if ($event === null) {
throw new InvalidArgumentException('event name must not be null');
}
if (isset($this->listeners[$event])) {
foreach ($this->listeners[$event] as $listener) {
$listener(...$arguments);
}
}
if (isset($this->onceListeners[$event])) {
$listeners = $this->onceListeners[$event];
unset($this->onceListeners[$event]);
foreach ($listeners as $listener) {
$listener(...$arguments);
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"name": "fortawesome/font-awesome",
"description": "The iconic font, CSS, and SVG framework",
"keywords": ["font", "awesome", "fontawesome", "icon", "svg", "font", "bootstrap"],
"homepage": "https://fontawesome.com",
"authors": [
{
"name": "The Font Awesome Team",
"homepage": "https://github.com/orgs/FortAwesome/people"
}
],
"support": {
"email": "hello@fontawesome.com",
"issues": "https://github.com/FortAwesome/Font-Awesome/issues",
"source": "https://github.com/FortAwesome/Font-Awesome",
"docs": "http://fontawesome.com/docs"
},
"license": [
"CC-BY-4.0",
"OFL-1.1",
"MIT"
]
}

View File

@ -1,31 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {},
"version": "6.2.0",
"name": "@fortawesome/fontawesome-common-types",
"license": "MIT",
"types": "./index.d.ts",
"scripts": {
"postinstall": "node attribution.js"
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,32 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {},
"version": "6.2.0",
"name": "@fortawesome/fontawesome-free",
"main": "js/fontawesome.js",
"style": "css/fontawesome.css",
"license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
"scripts": {
"postinstall": "node attribution.js"
}
}

View File

@ -1,73 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.2.0"
},
"version": "6.2.0",
"name": "@fortawesome/fontawesome-svg-core",
"main": "index.js",
"module": "index.mjs",
"jsnext:main": "index.mjs",
"style": "styles.css",
"license": "MIT",
"types": "./index.d.ts",
"exports": {
".": {
"module": "./index.mjs",
"import": "./index.mjs",
"require": "./index.js",
"style": "./styles.css",
"default": "./index.js"
},
"./index": {
"module": "./index.mjs",
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index.js": {
"module": "./index.mjs",
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./plugins": {
"module": "./plugins.mjs",
"import": "./plugins.mjs",
"default": "./plugins.mjs"
},
"./import.macro": "./import.macro.js",
"./import.macro.js": "./import.macro.js",
"./styles": "./styles.css",
"./styles.css": "./styles.css",
"./package.json": "./package.json"
},
"sideEffects": [
"./index.js",
"./index.mjs",
"./styles.css"
],
"scripts": {
"postinstall": "node attribution.js"
}
}

View File

@ -1,56 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.2.0"
},
"version": "6.2.0",
"name": "@fortawesome/free-brands-svg-icons",
"main": "index.js",
"module": "index.mjs",
"jsnext:main": "index.mjs",
"license": "(CC-BY-4.0 AND MIT)",
"types": "./index.d.ts",
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index.js": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./package.json": "./package.json",
"./*": "./*.js"
},
"scripts": {
"postinstall": "node attribution.js"
}
}

View File

@ -1,56 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.2.0"
},
"version": "6.2.0",
"name": "@fortawesome/free-regular-svg-icons",
"main": "index.js",
"module": "index.mjs",
"jsnext:main": "index.mjs",
"license": "(CC-BY-4.0 AND MIT)",
"types": "./index.d.ts",
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index.js": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./package.json": "./package.json",
"./*": "./*.js"
},
"scripts": {
"postinstall": "node attribution.js"
}
}

View File

@ -1,56 +0,0 @@
{
"description": "The iconic font, CSS, and SVG framework",
"keywords": [
"font",
"awesome",
"fontawesome",
"icon",
"svg",
"bootstrap"
],
"homepage": "https://fontawesome.com",
"bugs": {
"url": "https://github.com/FortAwesome/Font-Awesome/issues"
},
"author": "The Font Awesome Team (https://github.com/orgs/FortAwesome/people)",
"repository": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome"
},
"engines": {
"node": ">=6"
},
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.2.0"
},
"version": "6.2.0",
"name": "@fortawesome/free-solid-svg-icons",
"main": "index.js",
"module": "index.mjs",
"jsnext:main": "index.mjs",
"license": "(CC-BY-4.0 AND MIT)",
"types": "./index.d.ts",
"sideEffects": false,
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./index.js": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js"
},
"./package.json": "./package.json",
"./*": "./*.js"
},
"scripts": {
"postinstall": "node attribution.js"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
The MIT License
Copyright (c) 2018 Icinga GmbH https://www.icinga.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,27 +0,0 @@
{
"name": "ipl/html",
"type": "library",
"description": "Icinga PHP Library - HTML abstraction layer",
"license": "MIT",
"keywords": ["html"],
"homepage": "https://github.com/Icinga/ipl-html",
"config": {
"sort-packages": true
},
"require": {
"php": ">=7.2",
"ipl/stdlib": ">=0.12.0",
"ipl/validator": ">=0.4.0",
"psr/http-message": "~1.0"
},
"autoload": {
"psr-4": {
"ipl\\Html\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"ipl\\Tests\\Html\\": "tests"
}
}
}

View File

@ -1,301 +0,0 @@
<?php
namespace ipl\Html;
use InvalidArgumentException;
/**
* HTML Attribute
*
* Every single HTML attribute is (or should be) an instance of this class.
* This guarantees that every attribute is safe and escaped correctly.
*
* Usually attributes are not instantiated directly, but created through an HTML
* element's exposed methods.
*/
class Attribute
{
/** @var string */
protected $name;
/** @var string|array|bool|null */
protected $value;
/**
* Create a new HTML attribute from the given name and value
*
* @param string $name The name of the attribute
* @param string|bool|array|null $value The value of the attribute
*
* @throws InvalidArgumentException If the name of the attribute contains special characters
*/
public function __construct($name, $value = null)
{
$this->setName($name)->setValue($value);
}
/**
* Create a new HTML attribute from the given name and value
*
* @param string $name The name of the attribute
* @param string|bool|array|null $value The value of the attribute
*
* @return static
*
* @throws InvalidArgumentException If the name of the attribute contains special characters
*/
public static function create($name, $value)
{
return new static($name, $value);
}
/**
* Create a new empty HTML attribute from the given name
*
* The value of the attribute will be null after construction.
*
* @param string $name The name of the attribute
*
* @return static
*
* @throws InvalidArgumentException If the name of the attribute contains special characters
*/
public static function createEmpty($name)
{
return new static($name, null);
}
/**
* Escape the name of an attribute
*
* Makes sure that the name of an attribute really is a string.
*
* @param string $name
*
* @return string
*/
public static function escapeName($name)
{
return (string) $name;
}
/**
* Escape the value of an attribute
*
* If the value is an array, returns the string representation
* of all array elements joined with the specified glue string.
*
* Values are escaped according to the HTML5 double-quoted attribute value syntax:
* {@link https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 }.
*
* @param string|array $value
* @param string $glue Glue string to join elements if value is an array
*
* @return string
*/
public static function escapeValue($value, $glue = ' ')
{
if (is_array($value)) {
$value = implode($glue, $value);
}
// We force double-quoted attribute value syntax so let's start by escaping double quotes
$value = str_replace('"', '&quot;', $value);
// In addition, values must not contain ambiguous ampersands
$value = preg_replace_callback(
'/&[0-9A-Z]+;/i',
function ($match) {
$subject = $match[0];
if (htmlspecialchars_decode($subject, ENT_COMPAT | ENT_HTML5) === $subject) {
// Ambiguous ampersand
return str_replace('&', '&amp;', $subject);
}
return $subject;
},
$value
);
return $value;
}
/**
* Get the name of the attribute
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set the name of the attribute
*
* @param string $name
*
* @return $this
*
* @throws InvalidArgumentException If the name contains special characters
*/
protected function setName($name)
{
if (! preg_match('/^[a-z][a-z0-9:-]*$/i', $name)) {
throw new InvalidArgumentException(sprintf(
'Attribute names with special characters are not yet allowed: %s',
$name
));
}
$this->name = $name;
return $this;
}
/**
* Get the value of the attribute
*
* @return string|bool|array|null
*/
public function getValue()
{
return $this->value;
}
/**
* Set the value of the attribute
*
* @param string|bool|array|null $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Add the given value(s) to the attribute
*
* @param string|array $value The value(s) to add
*
* @return $this
*/
public function addValue($value)
{
$this->value = array_merge((array) $this->value, (array) $value);
return $this;
}
/**
* Remove the given value(s) from the attribute
*
* The current value is set to null if it matches the value to remove
* or is in the array of values to remove.
*
* If the current value is an array, all elements are removed which
* match the value(s) to remove.
*
* Does nothing if there is no such value to remove.
*
* @param string|array $value The value(s) to remove
*
* @return $this
*/
public function removeValue($value)
{
$value = (array) $value;
$current = $this->getValue();
if (is_array($current)) {
$this->setValue(array_diff($current, $value));
} elseif (in_array($current, $value, true)) {
$this->setValue(null);
}
return $this;
}
/**
* Test and return true if the attribute is boolean, false otherwise
*
* @return bool
*/
public function isBoolean()
{
return is_bool($this->value);
}
/**
* Test and return true if the attribute is empty, false otherwise
*
* Null and the empty array will be considered empty.
*
* @return bool
*/
public function isEmpty()
{
return $this->value === null || $this->value === [];
}
/**
* Render the attribute to HTML
*
* If the value of the attribute is of type boolean, it will be rendered as
* {@link http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes boolean attribute}.
* Note that in this case if the value of the attribute is false, the empty string will be returned.
*
* If the value of the attribute is null or an empty array,
* the empty string will be returned as well.
*
* Escaping of the attribute's value takes place automatically using {@link Attribute::escapeValue()}.
*
* @return string
*/
public function render()
{
if ($this->isEmpty()) {
return '';
}
if ($this->isBoolean()) {
if ($this->value) {
return $this->renderName();
}
return '';
} else {
return sprintf(
'%s="%s"',
$this->renderName(),
$this->renderValue()
);
}
}
/**
* Render the name of the attribute to HTML
*
* @return string
*/
public function renderName()
{
return static::escapeName($this->name);
}
/**
* Render the value of the attribute to HTML
*
* @return string
*/
public function renderValue()
{
return static::escapeValue($this->value);
}
}

View File

@ -1,521 +0,0 @@
<?php
namespace ipl\Html;
use ArrayAccess;
use ArrayIterator;
use InvalidArgumentException;
use IteratorAggregate;
use Traversable;
use function ipl\Stdlib\get_php_type;
/**
* HTML attributes
*
* HTML attributes provide additional information about HTML elements, that configure the elements or adjust their
* behavior in various ways.
*
* Attributes usually come in name-value pairs and are rendered as name="value".
*/
class Attributes implements ArrayAccess, IteratorAggregate
{
/** @var Attribute[] */
protected $attributes = [];
/** @var callable[] */
protected $callbacks = [];
/** @var string */
protected $prefix = '';
/** @var callable[] */
protected $setterCallbacks = [];
/**
* Create new HTML attributes
*
* @param array $attributes
*/
public function __construct(array $attributes = null)
{
if (empty($attributes)) {
return;
}
foreach ($attributes as $key => $value) {
if ($value instanceof Attribute) {
$this->addAttribute($value);
} elseif (is_string($key)) {
$this->add($key, $value);
} elseif (is_array($value) && count($value) === 2) {
$this->add(array_shift($value), array_shift($value));
}
}
}
/**
* Create new HTML attributes
*
* @param array $attributes
*
* @return static
*/
public static function create(array $attributes = null)
{
return new static($attributes);
}
/**
* Ensure that the given attributes of mixed type are converted to an instance of attributes
*
* The conversion procedure is as follows:
*
* If the given attributes is already an instance of Attributes, returns the very same element.
* If the attributes are given as an array of attribute name-value pairs, they are used to
* construct and return a new Attributes instance.
* If the attributes are null, an empty new instance of Attributes is returned.
*
* @param array|static|null $attributes
*
* @return static
*
* @throws InvalidArgumentException In case the given attributes are of an unsupported type
*/
public static function wantAttributes($attributes)
{
if ($attributes instanceof self) {
return $attributes;
}
if (is_array($attributes)) {
return new static($attributes);
}
if ($attributes === null) {
return new static();
}
throw new InvalidArgumentException(sprintf(
'Attributes instance, array or null expected. Got %s instead.',
get_php_type($attributes)
));
}
/**
* Get the collection of attributes as array
*
* @return Attribute[]
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Merge the given attributes
*
* @param Attributes $attributes
*
* @return $this
*/
public function merge(Attributes $attributes)
{
foreach ($attributes as $attribute) {
$this->addAttribute($attribute);
}
foreach ($attributes->callbacks as $name => $getter) {
$setter = null;
if (isset($attributes->setterCallbacks[$name])) {
$setter = $attributes->setterCallbacks[$name];
}
$this->registerAttributeCallback($name, $getter, $setter);
}
return $this;
}
/**
* Return true if the attribute with the given name exists, false otherwise
*
* @param string $name
*
* @return bool
*/
public function has($name)
{
return array_key_exists($name, $this->attributes);
}
/**
* Get the attribute with the given name
*
* If the attribute does not yet exist, it is automatically created and registered to this Attributes instance.
*
* @param string $name
*
* @return Attribute
*
* @throws InvalidArgumentException If the attribute does not yet exist and its name contains special characters
*/
public function get($name)
{
if (! $this->has($name)) {
$this->attributes[$name] = Attribute::createEmpty($name);
}
return $this->attributes[$name];
}
/**
* Set the given attribute(s)
*
* If the attribute with the given name already exists, it gets overridden.
*
* @param string|array|Attribute|self $attribute The attribute(s) to add
* @param string|bool|array $value The value of the attribute
*
* @return $this
*
* @throws InvalidArgumentException If the attribute name contains special characters
*/
public function set($attribute, $value = null)
{
if ($attribute instanceof self) {
foreach ($attribute as $a) {
$this->setAttribute($a);
}
return $this;
}
if ($attribute instanceof Attribute) {
$this->setAttribute($attribute);
return $this;
}
if (is_array($attribute)) {
foreach ($attribute as $name => $value) {
$this->set($name, $value);
}
return $this;
}
if (array_key_exists($attribute, $this->setterCallbacks)) {
$callback = $this->setterCallbacks[$attribute];
$callback($value);
return $this;
}
$this->attributes[$attribute] = Attribute::create($attribute, $value);
return $this;
}
/**
* Add the given attribute(s)
*
* If an attribute with the same name already exists, the attribute's value will be added to the current value of
* the attribute.
*
* @param string|array|Attribute|self $attribute The attribute(s) to add
* @param string|bool|array $value The value of the attribute
*
* @return $this
*
* @throws InvalidArgumentException If the attribute does not yet exist and its name contains special characters
*/
public function add($attribute, $value = null)
{
if ($attribute === null) {
return $this;
}
if ($attribute instanceof self) {
foreach ($attribute as $attr) {
$this->add($attr);
}
return $this;
}
if (is_array($attribute)) {
foreach ($attribute as $name => $value) {
$this->add($name, $value);
}
return $this;
}
if ($attribute instanceof Attribute) {
$this->addAttribute($attribute);
return $this;
}
if (array_key_exists($attribute, $this->setterCallbacks)) {
$callback = $this->setterCallbacks[$attribute];
$callback($value);
return $this;
}
if (! array_key_exists($attribute, $this->attributes)) {
$this->attributes[$attribute] = Attribute::create($attribute, $value);
} else {
$this->attributes[$attribute]->addValue($value);
}
return $this;
}
/**
* Remove the attribute with the given name or remove the given value from the attribute
*
* @param string $name The name of the attribute
* @param null|string|array $value The value to remove if specified
*
* @return Attribute|false
*/
public function remove($name, $value = null)
{
if (! $this->has($name)) {
return false;
}
$attribute = $this->attributes[$name];
if ($value === null) {
unset($this->attributes[$name]);
} else {
$attribute->removeValue($value);
}
return $attribute;
}
/**
* Set the specified attribute
*
* @param Attribute $attribute
*
* @return $this
*/
public function setAttribute(Attribute $attribute)
{
$this->attributes[$attribute->getName()] = $attribute;
return $this;
}
/**
* Add the specified attribute
*
* If an attribute with the same name already exists, the given attribute's value
* will be added to the current value of the attribute.
*
* @param Attribute $attribute
*
* @return $this
*/
public function addAttribute(Attribute $attribute)
{
$name = $attribute->getName();
if ($this->has($name)) {
$this->attributes[$name]->addValue($attribute->getValue());
} else {
$this->attributes[$name] = $attribute;
}
return $this;
}
/**
* Get the attributes name prefix
*
* @return string|null
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Set the attributes name prefix
*
* @param string $prefix
*
* @return $this
*/
public function setPrefix($prefix)
{
$this->prefix = $prefix;
return $this;
}
/**
* Register callback for an attribute
*
* @param string $name Name of the attribute to register the callback for
* @param callable $callback Callback to call when retrieving the attribute
* @param callable $setterCallback Callback to call when setting the attribute
*
* @return $this
*
* @throws InvalidArgumentException If $callback is not callable or if $setterCallback is set and not callable
*/
public function registerAttributeCallback($name, $callback, $setterCallback = null)
{
if ($callback !== null) {
if (! is_callable($callback)) {
throw new InvalidArgumentException(__METHOD__ . ' expects a callable callback');
}
$this->callbacks[$name] = $callback;
}
if ($setterCallback !== null) {
if (! is_callable($setterCallback)) {
throw new InvalidArgumentException(__METHOD__ . ' expects a callable setterCallback');
}
$this->setterCallbacks[$name] = $setterCallback;
}
return $this;
}
/**
* Render attributes to HTML
*
* If the value of an attribute is of type boolean, it will be rendered as
* {@link http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes boolean attribute}.
*
* If the value of an attribute is null, it will be skipped.
*
* HTML-escaping of the attributes' values takes place automatically using {@link Attribute::escapeValue()}.
*
* @return string
*
* @throws InvalidArgumentException If the result of a callback is invalid
*/
public function render()
{
$attributes = $this->attributes;
foreach ($this->callbacks as $name => $callback) {
$attribute = call_user_func($callback);
if ($attribute instanceof Attribute) {
if ($attribute->isEmpty()) {
continue;
}
} elseif ($attribute === null) {
continue;
} elseif (is_scalar($attribute)) {
$attribute = Attribute::create($name, $attribute);
} else {
throw new InvalidArgumentException(sprintf(
'A registered attribute callback must return a scalar, null'
. ' or an Attribute, got a %s',
get_php_type($attribute)
));
}
$name = $attribute->getName();
if (isset($attributes[$name])) {
$attributes[$name] = clone $attributes[$name];
$attributes[$name]->addValue($attribute->getValue());
} else {
$attributes[$name] = $attribute;
}
}
$parts = [];
foreach ($attributes as $attribute) {
if ($attribute->isEmpty()) {
continue;
}
$parts[] = $attribute->render();
}
if (empty($parts)) {
return '';
}
$separator = ' ' . $this->getPrefix();
return $separator . implode($separator, $parts);
}
/**
* Get whether the attribute with the given name exists
*
* @param string $name Name of the attribute
*
* @return bool
*/
public function offsetExists($name): bool
{
return $this->has($name);
}
/**
* Get the attribute with the given name
*
* If the attribute does not yet exist, it is automatically created and registered to this Attributes instance.
*
* @param string $name Name of the attribute
*
* @return Attribute
*
* @throws InvalidArgumentException If the attribute does not yet exist and its name contains special characters
*/
public function offsetGet($name): Attribute
{
return $this->get($name);
}
/**
* Set the given attribute
*
* If the attribute with the given name already exists, it gets overridden.
*
* @param string $name Name of the attribute
* @param mixed $value Value of the attribute
*
* @throws InvalidArgumentException If the attribute name contains special characters
*/
public function offsetSet($name, $value): void
{
$this->set($name, $value);
}
/**
* Remove the attribute with the given name
*
* @param string $name Name of the attribute
*/
public function offsetUnset($name): void
{
$this->remove($name);
}
/**
* Get an iterator for traversing the attributes
*
* @return Attribute[]|ArrayIterator
*/
public function getIterator(): Traversable
{
return new ArrayIterator($this->attributes);
}
}

View File

@ -1,355 +0,0 @@
<?php
namespace ipl\Html;
use RuntimeException;
/**
* Base class for HTML elements
*
* Extend this class in order to provide concrete HTML elements or series of HTML elements, e.g. widgets.
* When extending this class you should provide the element's tag with {@link $tag}. Setting default attributes is
* possible via {@link $defaultAttributes}. And the content of the element is provided in {@link assemble()}.
*
* # Example Usage
* ```
* namespace Acme\Widgets;
*
* use ipl\Html\BaseHtmlElement;
*
* class Dashboard extends BaseHtmlElement
* {
* protected $defaultAttributes = ['class' => 'acme-dashboard'];
*
* protected $tag = 'div';
*
* protected function assemble()
* {
* // ...
* $this->add($content);
* }
* }
* ```
*/
abstract class BaseHtmlElement extends HtmlDocument
{
/**
* List of void elements which must not contain end tags or content
*
* If {@link $isVoid} is null, this property should be used to decide whether the content and end tag has to be
* rendered.
*
* @var array
*
* @see https://www.w3.org/TR/html5/syntax.html#void-elements
*/
protected static $voidElements = [
'area' => 1,
'base' => 1,
'br' => 1,
'col' => 1,
'embed' => 1,
'hr' => 1,
'img' => 1,
'input' => 1,
'link' => 1,
'meta' => 1,
'param' => 1,
'source' => 1,
'track' => 1,
'wbr' => 1
];
/** @var Attributes */
protected $attributes;
/** @var bool Whether possible attribute callbacks have been registered */
protected $attributeCallbacksRegistered = false;
/** @var bool|null Whether the element is void. If null, void check should use {@link $voidElements} */
protected $isVoid;
/** @var array You may want to set default attributes when extending this class */
protected $defaultAttributes;
/** @var string Tag of element. Set this property in order to provide the element's tag when extending this class */
protected $tag;
/**
* Get the attributes of the element
*
* @return Attributes
*/
public function getAttributes()
{
if ($this->attributes === null) {
$default = $this->getDefaultAttributes();
if (empty($default)) {
$this->attributes = new Attributes();
} else {
$this->attributes = Attributes::wantAttributes($default);
}
$this->ensureAttributeCallbacksRegistered();
}
return $this->attributes;
}
/**
* Set the attributes of the element
*
* @param Attributes|array|null $attributes
*
* @return $this
*/
public function setAttributes($attributes)
{
$this->attributes = Attributes::wantAttributes($attributes);
$this->attributeCallbacksRegistered = false;
$this->ensureAttributeCallbacksRegistered();
return $this;
}
/**
* Set the attribute with the given name and value
*
* If the attribute with the given name already exists, it gets overridden.
*
* @param string $name The name of the attribute
* @param string|bool|array $value The value of the attribute
*
* @return $this
*/
public function setAttribute($name, $value)
{
$this->getAttributes()->set($name, $value);
return $this;
}
/**
* Add the given attributes
*
* @param Attributes|array $attributes
*
* @return $this
*/
public function addAttributes($attributes)
{
$this->getAttributes()->add($attributes);
return $this;
}
/**
* Get the default attributes of the element
*
* @return array
*/
public function getDefaultAttributes()
{
return $this->defaultAttributes;
}
/**
* Get the tag of the element
*
* Since HTML Elements must have a tag, this method throws an exception if the element does not have a tag.
*
* @return string
*
* @throws RuntimeException If the element does not have a tag
*/
final public function getTag()
{
$tag = $this->tag();
if (! $tag) {
throw new RuntimeException('Element must have a tag');
}
return $tag;
}
/**
* Set the tag of the element
*
* @param string $tag
*
* @return $this
*/
public function setTag($tag)
{
$this->tag = $tag;
return $this;
}
/**
* Get whether the element is void
*
* The default void detection which checks whether the element's tag is in the list of void elements according to
* https://www.w3.org/TR/html5/syntax.html#void-elements.
*
* If you want to override this behavior, use {@link setVoid()}.
*
* @return bool
*/
public function isVoid()
{
if ($this->isVoid !== null) {
return $this->isVoid;
}
$tag = $this->getTag();
return isset(self::$voidElements[$tag]);
}
/**
* Set whether the element is void
*
* You may use this method to override the default void detection which checks whether the element's tag is in the
* list of void elements according to https://www.w3.org/TR/html5/syntax.html#void-elements.
*
* If you specify null, void detection is reset to its default behavior.
*
* @param bool|null $void
*
* @return $this
*/
public function setVoid($void = true)
{
$this->isVoid = $void === null ?: (bool) $void;
return $this;
}
/**
* Ensure that possible attribute callbacks have been registered
*
* Note that this method is automatically called in {@link getAttributes()} and {@link setAttributes()}.
*
* @return $this
*/
public function ensureAttributeCallbacksRegistered()
{
if (! $this->attributeCallbacksRegistered) {
$this->attributeCallbacksRegistered = true;
$this->registerAttributeCallbacks($this->attributes);
}
return $this;
}
/**
* Render the content of the element to HTML
*
* @return string
*/
public function renderContent()
{
return parent::renderUnwrapped();
}
/**
* Get whether the closing tag should be rendered
*
* @return bool True for void elements, false otherwise
*/
public function wantsClosingTag()
{
// TODO: There is more. SVG and MathML namespaces
return ! $this->isVoid();
}
/**
* Use this element to wrap the given document
*
* @param HtmlDocument $document
*
* @return $this
*/
public function wrap(HtmlDocument $document)
{
$document->addWrapper($this);
return $this;
}
/**
* Internal method for accessing the tag
*
* You may override this method in order to provide the tag dynamically
*
* @return string
*/
protected function tag()
{
return $this->tag;
}
/**
* Register attribute callbacks
*
* Override this method in order to register attribute callbacks in concrete classes.
*/
protected function registerAttributeCallbacks(Attributes $attributes)
{
}
public function addHtml(ValidHtml ...$content)
{
$this->ensureAssembled();
parent::addHtml(...$content);
return $this;
}
/**
* @inheritdoc
*
* @throws RuntimeException If the element does not have a tag or is void but has content
*/
public function renderUnwrapped()
{
$this->ensureAssembled();
$tag = $this->getTag();
$content = $this->renderContent();
$attributes = $this->getAttributes()->render();
if (strlen($this->contentSeparator)) {
$length = strlen($content);
if ($length > 0) {
if ($content[0] === '<') {
$content = $this->contentSeparator . $content;
$length++;
}
if ($content[$length - 1] === '>') {
$content .= $this->contentSeparator;
}
}
}
if (! $this->wantsClosingTag()) {
if (strlen($content)) {
throw new RuntimeException('Void elements must not have content');
}
return sprintf('<%s%s />', $tag, $attributes);
}
return sprintf(
'<%s%s>%s</%s>',
$tag,
$attributes,
$content,
$tag
);
}
}

View File

@ -1,125 +0,0 @@
<?php
namespace ipl\Html\Contract;
use ipl\Html\Attributes;
use ipl\Html\Form;
/**
* Representation of form elements
*/
interface FormElement extends Wrappable
{
/**
* Get the attributes or options of the element
*
* @return Attributes
*/
public function getAttributes();
/**
* Add attributes or options to the form element
*
* @param iterable $attributes
*
* @return $this
*/
public function addAttributes($attributes);
/**
* Get the description for the element, if any
*
* @return string|null
*/
public function getDescription();
/**
* Get the label for the element, if any
*
* @return string|null
*/
public function getLabel();
/**
* Get the validation error messages
*
* @return array
*/
public function getMessages();
/**
* Add a validation error message
*
* @param string $message
*
* @return $this
*/
public function addMessage($message);
/**
* Get the name of the element
*
* @return string
*/
public function getName();
/**
* Get whether the element has a value
*
* @return bool False if the element's value is null, the empty string or the empty array; true otherwise
*/
public function hasValue();
/**
* Get the value of the element
*
* @return mixed
*/
public function getValue();
/**
* Set the value of the element
*
* @param mixed $value
*
* @return $this
*/
public function setValue($value);
/**
* Get whether the element has been validated
*
* @return bool
*/
public function hasBeenValidated();
/**
* Get whether the element is ignored
*
* @return bool
*/
public function isIgnored();
/**
* Get whether the element is required
*
* @return bool
*/
public function isRequired();
/**
* Get whether the element is valid
*
* @return bool
*/
public function isValid();
/**
* Handler which is called after this element has been registered
*
* @param Form $form
*
* @return void
*/
public function onRegistered(Form $form);
}

View File

@ -1,18 +0,0 @@
<?php
namespace ipl\Html\Contract;
use ipl\Html\ValidHtml;
/**
* Representation of form element decorators
*/
interface FormElementDecorator extends ValidHtml
{
/**
* Decorate the given form element
*
* @param FormElement $formElement
*/
public function decorate(FormElement $formElement);
}

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