First commit

This commit is contained in:
Nathan
2026-09-18 20:29:17 -06:00
commit 3b09abe571
2840 changed files with 467153 additions and 0 deletions
@@ -0,0 +1,57 @@
/* Root element */
.json-document {
padding: 1em 2em;
}
/* Syntax highlighting for JSON objects */
ul.json-dict, ol.json-array {
list-style-type: none;
margin: 0 0 0 1px;
border-left: 1px dotted #ccc;
padding-left: 2em;
}
.json-string {
color: #0B7500;
}
.json-literal {
color: #4B31FF;
font-weight: bold;
}
/* Toggle button */
a.json-toggle {
position: relative;
color: inherit;
text-decoration: none;
}
a.json-toggle:focus {
outline: none;
}
a.json-toggle:before {
font-size: 1.1em;
color: #c0c0c0;
content: "\25BC"; /* down arrow */
position: absolute;
display: inline-block;
width: 1em;
text-align: center;
line-height: 1em;
left: -1.2em;
}
a.json-toggle:hover:before {
color: #aaa;
}
a.json-toggle.collapsed:before {
/* Use rotated down arrow, prevents right arrow appearing smaller than down arrow in some browsers */
transform: rotate(-90deg);
}
/* Collapsable placeholder links */
a.json-placeholder {
color: #aaa;
padding: 0 1em;
text-decoration: none;
}
a.json-placeholder:hover {
text-decoration: underline;
}
@@ -0,0 +1,158 @@
/**
* jQuery json-viewer
* @author: Alexandre Bodelot <alexandre.bodelot@gmail.com>
* @link: https://github.com/abodelot/jquery.json-viewer
*/
(function($) {
/**
* Check if arg is either an array with at least 1 element, or a dict with at least 1 key
* @return boolean
*/
function isCollapsable(arg) {
return arg instanceof Object && Object.keys(arg).length > 0;
}
/**
* Check if a string represents a valid url
* @return boolean
*/
function isUrl(string) {
var urlRegexp = /^(https?:\/\/|ftps?:\/\/)?([a-z0-9%-]+\.){1,}([a-z0-9-]+)?(:(\d{1,5}))?(\/([a-z0-9\-._~:/?#[\]@!$&'()*+,;=%]+)?)?$/i;
return urlRegexp.test(string);
}
/**
* Transform a json object into html representation
* @return string
*/
function json2html(json, options) {
var html = '';
if (typeof json === 'string') {
// Escape tags and quotes
json = json
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&apos;')
.replace(/"/g, '&quot;');
if (options.withLinks && isUrl(json)) {
html += '<a href="' + json + '" class="json-string" target="_blank">' + json + '</a>';
} else {
// Escape double quotes in the rendered non-URL string.
json = json.replace(/&quot;/g, '\\&quot;');
html += '<span class="json-string">"' + json + '"</span>';
}
} else if (typeof json === 'number') {
html += '<span class="json-literal">' + json + '</span>';
} else if (typeof json === 'boolean') {
html += '<span class="json-literal">' + json + '</span>';
} else if (json === null) {
html += '<span class="json-literal">null</span>';
} else if (json instanceof Array) {
if (json.length > 0) {
html += '[<ol class="json-array">';
for (var i = 0; i < json.length; ++i) {
html += '<li>';
// Add toggle button if item is collapsable
if (isCollapsable(json[i])) {
html += '<a href class="json-toggle"></a>';
}
html += json2html(json[i], options);
// Add comma if item is not last
if (i < json.length - 1) {
html += ',';
}
html += '</li>';
}
html += '</ol>]';
} else {
html += '[]';
}
} else if (typeof json === 'object') {
var keyCount = Object.keys(json).length;
if (keyCount > 0) {
html += '{<ul class="json-dict">';
for (var key in json) {
if (Object.prototype.hasOwnProperty.call(json, key)) {
html += '<li>';
var keyRepr = options.withQuotes ?
'<span class="json-string">"' + key + '"</span>' : key;
// Add toggle button if item is collapsable
if (isCollapsable(json[key])) {
html += '<a href class="json-toggle">' + keyRepr + '</a>';
} else {
html += keyRepr;
}
html += ': ' + json2html(json[key], options);
// Add comma if item is not last
if (--keyCount > 0) {
html += ',';
}
html += '</li>';
}
}
html += '</ul>}';
} else {
html += '{}';
}
}
return html;
}
/**
* jQuery plugin method
* @param json: a javascript object
* @param options: an optional options hash
*/
$.fn.jsonViewer = function(json, options) {
// Merge user options with default options
options = Object.assign({}, {
collapsed: false,
rootCollapsable: true,
withQuotes: false,
withLinks: true
}, options);
// jQuery chaining
return this.each(function() {
// Transform to HTML
var html = json2html(json, options);
if (options.rootCollapsable && isCollapsable(json)) {
html = '<a href class="json-toggle"></a>' + html;
}
// Insert HTML in target DOM element
$(this).html(html);
$(this).addClass('json-document');
// Bind click on toggle buttons
$(this).off('click');
$(this).on('click', 'a.json-toggle', function() {
var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
target.toggle();
if (target.is(':visible')) {
target.siblings('.json-placeholder').remove();
} else {
var count = target.children('li').length;
var placeholder = count + (count > 1 ? ' items' : ' item');
target.after('<a href class="json-placeholder">' + placeholder + '</a>');
}
return false;
});
// Simulate click on toggle button when placeholder is clicked
$(this).on('click', 'a.json-placeholder', function() {
$(this).siblings('a.json-toggle').click();
return false;
});
if (options.collapsed == true) {
// Trigger click to collapse all nodes
$(this).find('a.json-toggle').click();
}
});
};
})(jQuery);
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 117.19922 125.20118"
xml:space="preserve"
sodipodi:docname="piwigo-logo-minimal.svg"
width="117.19922"
height="125.20118"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
id="metadata950"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs948" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1017"
id="namedview946"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="1.5789474"
inkscape:cx="113.68333"
inkscape:cy="114"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Symbole_24_1"
inkscape:pagecheckerboard="0" />
<style
type="text/css"
id="style935">
.st0{fill:#656565;}
</style>
<g
id="Symbole_24_1"
transform="translate(-590,-460.7992)">
<path
id="Ellipse_68"
style="fill:#ffffff;fill-opacity:1"
d="m 108.69922,14.283203 c -13.600002,0.3 -12.199611,8.201172 -43.599611,8.201172 -31.4,-0.1 -7.00039,0 -7.90039,0 H 44 c -17.1,0 -31,13.9 -31,31 v 55.000005 c 0,17.09999 13.9,31 31,31 h 55.099609 c 17.100001,0 31.000001,-13.90001 31.000001,-31 V 37.283203 c 0.0647,-0.658884 0.0996,-1.325459 0.0996,-2 -0.1,-11.6 -9.9,-21 -21.5,-21 z m 0.5,13.201172 c 4.1,0 7.40039,3.300391 7.40039,7.400391 0,4.1 -3.40039,7.398437 -7.40039,7.398437 -4.1,0 -7.39844,-3.298437 -7.39844,-7.398437 0,-4.1 3.29844,-7.400391 7.39844,-7.400391 z M 71.599609,46.283203 c 19.2,0 34.701171,15.501172 34.701171,34.701172 0,19.100005 -15.501171,34.699215 -34.701171,34.699215 -19.2,0 -34.699218,-15.49921 -34.699218,-34.699215 0,-19.2 15.499218,-34.701172 34.699218,-34.701172 z M 71.328125,56.384766 A 24.6,24.6 0 0 0 47,80.984375 24.6,24.6 0 0 0 71.599609,105.58398 24.6,24.6 0 0 0 96.199219,80.984375 24.6,24.6 0 0 0 71.599609,56.384766 a 24.6,24.6 0 0 0 -0.271484,0 z"
transform="translate(577,446.516)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

+633
View File
@@ -0,0 +1,633 @@
/* BEGIN CSS RESET
http://meyerweb.com/eric/tools/css/reset
v2.0 | 20110126 | License: none (public domain) */
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video
{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;}
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;}
body {line-height:1.1;}
blockquote, q {quotes:none;}
blockquote:before, blockquote:after, q:before, q:after {content:'';content:none;}
table {border-collapse:collapse;border-spacing:0;}
/* END CSS RESET */
#the_body, body {
--color-bg: #E5E5E5;
--color-bg-secondary: #FFFFFF;
--color-text: #434343;
--color-action: #FF7700;
--color-action-text: #FFF;
--color-action-hover: #ee4b00;
--color-action-secondary: #eee;
--color-action-secondary-text: var(--color-text);
--color-action-secondary-hover: #ddd;
--color-bg-nuance:#f7f7f7;
--border-radius: 5px;
--box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25);
--header-heigth: 50px;
--footer-heigth: 20px;
--container-heigth: calc(100vh - var(--header-heigth) - var(--footer-heigth));
background: var(--color-bg);
}
#the_body.dark-mode {
--color-bg: #393939;
--color-bg-secondary: #242424;
--color-text: #fff;
--color-action: #FF7700;
--color-action-text: #FFF;
--color-action-hover: #ee4b00;
--color-action-secondary: #181818;
--color-action-secondary-text: #fff;
--color-action-secondary-hover: #292929;
--color-bg-nuance:#1e1e1e;
--box-shadow: none;
}
li {
list-style: none;
}
html {font-family:"Corbel","Lucida Grande","Verdana",sans-serif;color:#434343;font-size:14px;}
#the_body {
display: flex;
flex-direction: column;
}
#the_container {
display: grid;
grid-template-columns: 250px auto;
}
#the_header, #the_footer {
display: flex;
align-items: center;
z-index: 10;
overflow: hidden;
background: var(--color-bg-secondary);
color: var(--color-text);
}
a {
color:var(--color-action);
text-decoration:none;
}
a:hover {
color:var(--color-action-hover);
border-bottom-width:1px;
}
blockquote {
padding:8px;
}
hr {
margin:10px 30px;
}
ul {
margin-left:25px;
}
p {margin: 8px 0;}
h1 {
font-size:20px;
padding-left:10px;
}
h2 {
font-size:16px;
padding: 10px 10px 5px 10px;
}
h2#errorWrapper {
color:#F42C00;
font-weight:normal;
}
h3 {
display:inline-block;
font-weight:bold;
}
input[type="text"] {
border: 2px solid var(--color-action-secondary);
border-radius: var(--border-radius);
color: var(--color-text);
background: var(--color-bg-secondary);
width: 100%;
padding: 5px;
}
#the_header {
height: var(--header-heigth);
box-shadow: var(--box-shadow);
}
#the_header img {
width: 30px;
opacity: 1;
margin-left: 10px;
}
#the_body:not(.dark-mode) #the_header img {
filter: brightness(80%);;
}
#the_footer {
height: var(--footer-heigth);
justify-content: center;
background: var(--color-bg-secondary);
opacity: 0.7;
}
#the_footer a {
margin-left: 5px;
}
#the_methods, #the_page {
height: var(--container-heigth);
overflow-y: auto;
overflow-x: hidden;
/* ScrollBar customization for firefox */
scrollbar-width: thin;
}
#the_methods {
background-color: var(--color-bg-secondary);
color: var(--color-text);
box-shadow: var(--box-shadow);
z-index: 5;
}
#methodsList, #search {
font-size:1.1em;
margin:5px 10px;
position: relative;
}
#search {
display: flex;
}
#search i {
position:absolute;
top:50%;
left:5px;
transform: translateY(-50%);
}
#search input {
padding-left: 25px;
}
.method-node {
position: relative;
display: flex;
flex-direction: column;
}
.method-node input {
opacity: 0;
position: absolute;
width: 0;
height: 0;
}
.method-node-content {
padding-left: 30px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.method-node label, .method-link {
margin: 5px 0px;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
overflow-y: clip;
}
.method-link {
order: 1;
}
.method-node label {
background: var(--color-action-secondary);
color: var(--color-action-secondary-text);
padding: 6px;
border-radius: var(--border-radius);
font-weight: bold;
}
.onSearch .method-node label {
pointer-events: none;
padding-left: 10px;
}
.onSearch .method-node label i {
display: none;
}
.method-node label i::before {
font-size: 12px;
transform: rotate(-90deg);
transition: 0.2s ease-in-out;
}
.method-node > input:checked ~ label i::before {
transform: rotate(0deg);
}
.method-node label:hover {
background-color: var(--color-action-secondary-hover);
}
#methodsList > .method-node > label {
background: var(--color-action);
color: var(--color-action-text);
}
#methodsList > .method-node > label:hover {
background: var(--color-action-hover);
}
#the_page {
background-color: var(--color-bg);
color: var(--color-text);
}
#the_title {
display: flex;
align-items: baseline;
}
#the_title #onlys .only {
border-radius: var(--border-radius);
background: var(--color-action-secondary);
color: var(--color-text);
padding: 5px;
margin-right: 10px;
}
#the_content {
padding:10px;
padding-top: 0px;
}
#methodWrapper {
display: flex;
flex-direction: column;
}
#methodControl {
display: grid;
grid-template-columns: 66% 34%;
}
#methodDescription blockquote ul {
margin-top: 10px;
}
#methodDescription blockquote ul li {
list-style-type: disc;
}
.card, .card-2 {
margin: 10px;
background-color: var(--color-bg-secondary);
border-radius: var(--border-radius);
position: relative;
}
.card {
padding:10px;
}
.card-2 {
border: 2px solid var(--color-action);
margin-top: 25px;
}
.card .card-title {
font-size: 16px;
}
.card-2 .card-title {
font-size: 14px;
color: var(--color-action);
position: absolute;
top: 0;
transform: translateY(calc(-100% - 5px));
}
.card-2 .card-content {
overflow-y: auto;
/* firefox scrollbar customization */
scrollbar-width: thin;
}
.card .card-title i {
color: var(--color-action);
font-size: 20px;
margin-right: 5px;
}
.card .card-content {
padding: 10px;
position: relative;
}
.header-setting {
margin-bottom: 10px;
}
.header-setting input {
width: 98%;
}
.header-description {
margin: 0;
margin-bottom: 10px;
}
.header-warning {
margin: 0;
color: red;
font-size: 10px;
font-style: italic;
}
.header-label {
margin-bottom: 0;
}
/* #requestResultDisplay {
background: white;
} */
#methodParams table {
width: 100%;
}
#methodParams td .methodParameterSend{
opacity: 0;
position: absolute;
width: 0;
height: 0;
}
#methodParams td .methodParameterSendCheckbox {
padding: 10px;
position: relative;
border: 2px solid var(--color-action);
border-radius: var(--border-radius);
line-height: 0;
box-sizing: border-box;
cursor: pointer;
}
#methodParams td .methodParameterSendCheckbox i {
color: var(--color-action-text);
position:absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
#methodParams td .methodParameterSend:checked ~ .methodParameterSendCheckbox {
background: var(--color-action);
}
#methodParams td .methodParameterSend:not(:checked) ~ .methodParameterSendCheckbox i {
display: none;
transform: translate(-50%,-50%);
}
#methodParams tr {
display: flex;
border-radius: var(--border-radius);
align-items: center;
height: 38px;
}
#methodParams tr td {
display: flex;
flex-wrap: nowrap;
padding: 0px 12px;
}
#methodParams tr .required {
color: var(--color-action);
font-size: 20px;
}
#methodParams tr td:nth-child(1){width: calc(50% - 100px);}
#methodParams tr td:nth-child(2){width: 100px;}
#methodParams tr td:nth-child(3){width: calc(50% - 30px);}
#methodParams tr td:nth-child(4){width: 30px; justify-content: center;}
#methodParams thead tr {
background: var(--color-action);
color: var(--color-action-text);
font-weight: bold;
}
#methodParams tbody tr:nth-child(even) {
background-color: var(--color-bg-nuance);
}
#methodParams .type-badge {
display:flex;
overflow: hidden;
align-items: center;
justify-content: center;
width:20px;
height:20px;
font-size: 20px;
font-weight: bold;
line-height:16px;
border-radius: 100%;
background: var(--color-action);
color: var(--color-action-text);
margin-right: 2px;
}
#methodParams .type-badge::before {
font-size: 12px;
}
#testForm .card-content .select-group {
margin-bottom: 10px;
display: flex;
align-items: baseline;
flex-direction: column;
}
#testForm .testAction {
display:flex;
justify-content: flex-end;
}
#testForm .testAction .button {
margin-left: 10px;
}
#testForm select, #testForm select::before, #testForm select::after {
box-sizing: border-box;
}
select {
appearance: none;
background-color: transparent;
border: none;
padding: 0 1em 0 0;
margin: 0;
width: 100%;
font-family: inherit;
font-size: inherit;
cursor: inherit;
line-height: inherit;
color: var(--color-text);
}
#testForm .select {
width: 100%;
outline: none;
min-width: 15ch;
max-width: 30ch;
border: 2px solid var(--color-action-secondary);
border-radius: var(--border-radius);
padding: 5px;
cursor: pointer;
font-weight: bold;
position: relative;
}
#testForm .select::after {
content: '\e835';
font-family: 'fontello';
font-size: 12px;
color: var(--color-text);
position:absolute;
top:50%;
right: 10px;
transform: translateY(-50%);
pointer-events: none;
}
/* Remove arrow from select */
#testForm select::-ms-expand {
display: none;
}
#introMessage {
font-size:1.1em;
}
#introMessage .card-content {
padding: 0 10px;
}
#urlForm {
margin-bottom:10px;
}
a.button {
padding: 10px;
border-radius: var(--border-radius);
background: var(--color-action);
color: var(--color-action-text);
display: flex;
align-items: center;
}
a.button:hover {
background-color: var(--color-action-hover);
}
#tiptip_content {
font-size:12px;
}
#resultWrapper {
width:100%;
height:300px;
padding: 0;
position:relative;
}
iframe {width:100%;height:100%; background-color: white;}
#iframeAction {
position: absolute;
bottom: 0;
transform: translateY(calc(100% + 5px));
}
#decreaseIframe i::before {
transform: rotate(180deg);
}
div.onlys {padding:.25em .5em;display:table;border-radius:4px;margin-bottom:0.5em;}
.darkModeButton {
position: absolute;
z-index: 11;
top: 0px;
right: 0px;
width: var(--header-heigth);
height: var(--header-heigth);
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
opacity: 0.7;
cursor: pointer;
}
.darkModeButton:hover {
opacity: 1;
}
/* -- Tiptip customization -- */
#tiptip_content {
color: var(--color-action-text) !important;
background: var(--color-action) !important;
text-shadow: none;
}
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
border-bottom-color: var(--color-action) !important;
}
/* -- Chrome ScrollBar customization -- */
::-webkit-scrollbar {
width: 8px;
}
/* Track */
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.11);
}
/* Handle */
::-webkit-scrollbar-thumb {
background: var(--color-action);
border-radius:5px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: var(--color-action);
}
+540
View File
@@ -0,0 +1,540 @@
$(() => {
// global lets
let cachedMethods = new Array;
let ws_url = "http://";
// automatic detection of ws_url
match = document.location.toString().match(/^(https?.*\/)tools\/ws\.html?/);
if (match == null) {
askForUrl();
}
else {
ws_url = match[1] + 'ws.php';
getMethodList();
}
// manual set of ws_url
$("#urlForm").submit(function () {
ws_url = $(this).children("input[name='ws_url']").val();
getMethodList();
return false;
});
// invoke buttons
$("#invokeMethod").click(function () {
invokeMethod($("#methodName").html(), false);
return false;
});
$("#invokeMethodBlank").click(function () {
invokeMethod($("#methodName").html(), true);
return false;
});
// resizable iframe
$("#increaseIframe").click(function () {
$("#resultWrapper").css('height', $("#resultWrapper").height() + 100);
});
$("#decreaseIframe").click(function () {
if ($("#resultWrapper").height() > 200) {
$("#resultWrapper").css('height', $("#resultWrapper").height() - 100);
}
});
// mask all wrappers
function resetDisplay() {
$("#errorWrapper").hide();
$("#methodWrapper").hide();
$("#methodName").hide();
$("#urlForm").hide();
$("#methodDescription blockquote").empty();
$("#methodDescription").hide();
$("#requestURLDisplay").hide();
$("#requestResultDisplay").hide();
$("#invokeFrame").attr('src', '');
}
// display error wrapper
function displayError(error) {
resetDisplay();
$("#errorWrapper").html("<b>Error:</b> " + error).show();
}
// display ws_url form
function askForUrl() {
displayError("can't contact web-services, please give absolute url to 'ws.php'");
if ($("#urlForm input[name='ws_url']").val() == "") {
$("#urlForm input[name='ws_url']").val(ws_url);
}
$("#urlForm").show();
}
// parse Piwigo JSON
function parsePwgJSON(json) {
try {
resp = jQuery.parseJSON(json);
if (resp == null | resp.result == null | resp.stat == null | resp.stat != 'ok') {
throw new Error();
}
}
catch (e) {
displayError("unable to parse JSON string");
resp = { "stat": "ko", "result": "null" };
}
return resp.result;
}
// fetch methods list
function getMethodList() {
resetDisplay();
$.ajax({
type: "GET",
url: ws_url,
data: { format: "json", method: "reflection.getMethodList" }
}).done(function (result) {
// for debug
//console.log(result);
result = parsePwgJSON(result);
if (result != null) {
methods = result.methods;
let methodTree = {};
for (let i = 0; i < methods.length; i++) {
addMethodToNode(methodTree, methods[i].split('.'))
}
$("#methodsList").html(displayMethodNode(methodTree, [])).show();
// trigger method selection
$("#methodsList .method-link").click(function () {
selectMethod($(this).data('method'));
});
if ($.cookie('wse-menu-state')) {
$.cookie('wse-menu-state').split(',').forEach(id => $(`input[id="${id}"]`).attr('checked', true));
}
setStateMenu();
$('.method-node-content').each((i, node) => {
let content = $(node);
let checkbox = content.parent().children('input');
checkbox.on('change', function() {
let id = checkbox.attr('id');
let menustate = $.cookie('wse-menu-state')?.split(',') ?? [];
if (this.checked) {
content.slideDown(200);
menustate.push(id)
} else {
content.slideUp(200);
menustate = menustate.filter(str => str !== id);
}
$.cookie('wse-menu-state', menustate.join(','))
})
})
}
}).error(function (jqXHR, textStatus, errorThrown) {
askForUrl();
});
}
function addMethodToNode(methodNode, methodRoute) {
if (methodRoute.length > 1) {
let node = methodRoute.shift();
if (!methodNode[node])
methodNode[node] = {};
addMethodToNode(methodNode[node], methodRoute);
} else
methodNode[methodRoute[0]] = 1;
}
function displayMethodNode(methodNode, route) {
let html = '';
if (methodNode === 1) {
html = `<a
class="method-link"
data-method="${route.join('.')}"
title="${route[route.length - 1]}"
>
${route[route.length - 1]}
</a>`
} else {
html = route.length === 0 ? '' : `<div class="method-node">
<input type="checkbox" id="method-node-input-${route.join('.')}">
<label for="method-node-input-${route.join('.')}" title="${route[route.length - 1]}">
<i class="icon-down-open"></i>
<span>${route[route.length - 1]}</span>
</label>
<div class="method-node-content">`;
for (const node in methodNode) {
html += displayMethodNode(methodNode[node], [...route, node]);
}
html += route.length === 0 ? '' :'</div></div>';
}
return html;
}
function setStateMenu() {
$('.method-node').each((i, n) => {
let node = $(n);
let content = node.children('.method-node-content')
let checkbox = node.children('input');
if (checkbox.prop('checked')) {
content.show();
} else {
content.hide();
}
})
}
// select method
function selectMethod(methodName) {
$("#introMessage").hide();
$("#tiptip_holder").fadeOut(200);
if (cachedMethods[methodName]) {
fillNewMethod(methodName);
}
else {
$.ajax({
type: "GET",
url: ws_url,
data: { format: "json", method: "reflection.getMethodDetails", methodName: methodName }
}).done(function (result) {
result = parsePwgJSON(result);
if (result != null) {
let onlys = [];
if (result.options.post_only || result.options.admin_only) {
if (result.options.post_only) {
onlys.push('POST only');
}
if (result.options.admin_only) {
onlys.push('Admin only');
}
}
result.onlys = onlys;
cachedMethods[methodName] = result;
fillNewMethod(methodName);
}
}).error(function (jqXHR, textStatus, errorThrown) {
displayError("unknown error");
});
}
}
// display method details
function fillNewMethod(methodName) {
resetDisplay();
method = cachedMethods[methodName];
$("#methodName").html(method.name).show();
$('#onlys').html('');
method.onlys.forEach((text) => {
$('#onlys').append($(`<span class="only">${text}</span>`));
})
if (method.description != "") {
$("#methodDescription blockquote").html(method.description);
$("#methodDescription").show();
}
$("#requestFormat").val(method.options.post_only ? 'post' : 'get');
let methodParams = '';
if (method.params && method.params.length > 0) {
$('.no-params').hide();
$("#methodParams table").show();
for (let i = 0; i < method.params.length; i++) {
let param = method.params[i],
isOptional = param.optional,
acceptArray = param.acceptArray,
defaultValue = param.defaultValue == null ? '' : param.defaultValue,
info = param.info == null ? '' : '<i class="methodInfo icon-info-circled-1" title="' + param.info.replace(/"/g, '&quot;') + '"></i>',
type = '',
subtype = '',
optional = '<span class="required" title = "This parameter is required" >*</span >',
array = '<span class="type-badge icon-clone" title="Can be an array"></span >';
if (param.type.match(/bool/)) type += '<span class="type-badge" title="Boolean">B<span>';
if (param.type.match(/int/)) type += '<span class="type-badge" title="Integer">I</span>';
if (param.type.match(/float/)) type += '<span class="type-badge" title="Float">F</span>';
if (param.type.match(/positive/)) subtype += '<span class="type-badge icon-plus" title="Positive"></span>';
if (param.type.match(/notnull/)) subtype += '<span class="type-badge" title="Not null"><span style="transform:translateY(-3px)">&oslash;</span></span>';
// if an array is direclty printed, the delimiter is a comma where we use a pipe
if (typeof defaultValue == 'object') {
defaultValue = defaultValue.join('|');
}
methodParams += `<tr>
<td>${param.name + (isOptional ? '' : optional ) + info }</td>
<td class="mini">${(acceptArray ? array : '') + type + subtype}</td>
<td class="input"><input type="text" class="methodParameterValue" data-id="${i}" value="${defaultValue}"></td>
<td class="mini">
<input type="checkbox" id="parameter-send-${i}" class="methodParameterSend" data-id="${i}" ${(isOptional ? '' : 'checked="checked"')}>
<label class="methodParameterSendCheckbox" for="parameter-send-${i}"><i class="icon-ok"></i></label>
</td>
</tr>`;
}
$("#methodParams tbody").html(methodParams);
}
else {
$('.no-params').show();
$("#methodParams table").hide();
}
$("#methodWrapper").show();
// trigger field modification
$("input.methodParameterValue").change(function () {
$("input.methodParameterSend[data-id='" + $(this).data('id') + "']").attr('checked', 'checked');
});
// tiptip
$(".methodInfo").tipTip({
maxWidth: "300px",
defaultPosition: "bottom",
delay: 0
});
$(".required, .type-badge").tipTip({
maxWidth: "100px",
defaultPosition: "bottom",
delay: 0
});
}
// invoke method
function invokeMethod(methodName, newWindow) {
$('#json-viewer').jsonViewer({});
$('#requestURLDisplay').show();
$('#requestResultDisplay').show();
let method = cachedMethods[methodName];
let reqUrl = ws_url + "?format=" + $("#responseFormat").val();
const isJson = $("#responseFormat").val() === 'json';
const authorization = $('#apiKey').val();
const useCookie = '' === authorization;
let fetchOption = {};
if (!useCookie) {
fetchOption.credentials = 'omit';
fetchOption.headers = {
"X-PIWIGO-API": authorization
}
}
// GET
if ($("#requestFormat").val() == 'get') {
reqUrl += "&method=" + methodName;
for (let i = 0; i < method.params.length; i++) {
if (!$("input.methodParameterSend[data-id='" + i + "']").is(":checked")) {
continue;
}
let paramValue = $("input.methodParameterValue[data-id='" + i + "']").val();
let paramSplitted = paramValue.split('|');
if (method.params[i].acceptArray && paramSplitted.length > 1) {
$.each(paramSplitted, function (v) {
reqUrl += '&' + method.params[i].name + '[]=' + paramSplitted[v];
});
}
else {
reqUrl += '&' + method.params[i].name + '=' + paramValue;
}
}
if (newWindow) {
window.open(reqUrl);
}
else {
fetch(reqUrl, fetchOption)
.then(data => data.text())
.then(data => {
showResponseData(data);
})
}
$('#requestURLDisplay').find('.url').html(reqUrl).end()
.find('.params').hide();
}
// POST
else {
let params = {};
let form = $("#invokeForm");
form.attr('action', reqUrl);
let t = '<input type="hidden" name="method" value="' + methodName + '">';
for (let i = 0; i < method.params.length; i++) {
if (!$("input.methodParameterSend[data-id='" + i + "']").is(":checked")) {
continue;
}
let paramValue = $("input.methodParameterValue[data-id='" + i + "']").val(),
paramName = method.params[i].name,
paramSplitted = paramValue.split('|');
if (method.params[i].acceptArray && paramSplitted.length > 1) {
params[paramName] = [];
$.each(paramSplitted, function (i, value) {
params[paramName].push(value);
t += '<input type="hidden" name="' + paramName + '[]" value="' + value + '">';
});
}
else {
params[paramName] = paramValue;
t += '<input type="hidden" name="' + paramName + '" value="' + paramValue + '">';
}
}
if (!newWindow) {
$("#invokeFrame").hide();
$('#json-viewer').show();
const formData = new URLSearchParams();
formData.append('method', methodName);
for (const key in params) {
formData.append(key, params[key]);
}
fetchOption.headers ??= {};
fetchOption.headers['Content-Type'] = 'application/x-www-form-urlencoded';
fetch(reqUrl, {
...fetchOption,
method: 'POST',
body: formData
})
.then(data => {
return data.text();
})
.then(data => {
showResponseData(data);
});
} else {
$("#invokeFrame").show();
$('#json-viewer').hide();
form.html(t);
form.attr('target', newWindow ? "_blank" : "invokeFrame");
form.submit();
}
$('#requestURLDisplay').find('.url').html(reqUrl).end()
.find('.params').show().html(JSON.stringify(params, null, 4));
}
return false;
}
$('#search input').val('');
$('#search input').on('input', function () {
if ($(this).val()) {
$('.method-node, .method-link').hide();
if (!$('#methodsList').hasClass('onSearch')) {
$('#methodsList').addClass('onSearch');
$('.method-node-content').show();
}
function showBranch(methodNode) {
methodNode.show();
while (methodNode.parent().parent().hasClass("method-node")) {
methodNode = methodNode.parent().parent();
methodNode.show();
}
}
$('.method-link').each((i, n) => {
if ($(n).data('method').toLowerCase().search($(this).val().toLowerCase())!= -1) {
showBranch($(n));
}
})
} else {
$('.method-node, .method-link').show();
$('#methodsList').removeClass('onSearch');
setStateMenu()
}
})
if ($.cookie('wse-dark-mode')) {
$('#the_body').addClass('dark-mode');
$('.darkModeButton').addClass('icon-sun-inv');
}
$('.darkModeButton').click(() => {
if ($.cookie('wse-dark-mode')) {
$('.darkModeButton').removeClass('icon-sun-inv').addClass('icon-moon-inv');
$.removeCookie('wse-dark-mode');
$('#the_body').removeClass('dark-mode');
} else {
$('.darkModeButton').removeClass('icon-moon-inv').addClass('icon-sun-inv');
$.cookie('wse-dark-mode', true);
$('#the_body').addClass('dark-mode');
}
})
})
function showResponseData(data) {
const isJson = $("#responseFormat").val() === 'json';
if (isJson) {
try {
const json = JSON.parse(data);
$('#json-viewer').jsonViewer(json);
$("#invokeFrame").hide();
$('#json-viewer').show();
} catch (error) {
const iframe = $('#invokeFrame');
const iframeDoc = iframe[0].contentDocument || iframe[0].contentWindow.document;
iframeDoc.open();
iframeDoc.write(`<pre>${data}</pre>`);
iframeDoc.close();
$("#invokeFrame").show();
$('#json-viewer').hide();
}
return;
}
const iframe = $('#invokeFrame');
const iframeDoc = iframe[0].contentDocument || iframe[0].contentWindow.document;
iframeDoc.open();
iframeDoc.write(data);
iframeDoc.close();
$("#invokeFrame").show();
$('#json-viewer').hide();
}