mirror of
https://github.com/Piwigo/Piwigo.git
synced 2025-04-26 11:19:55 +03:00
Web Service Explorer Redesign
* General visual redesign * Method list in method tree * Json is now beautifully displayed
This commit is contained in:
parent
8c8c19e3e6
commit
a06bc75959
6 changed files with 1548 additions and 553 deletions
727
tools/ws.htm
727
tools/ws.htm
|
@ -5,570 +5,191 @@
|
|||
<title>Piwigo web API (web-services) explorer</title>
|
||||
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/tiptip/1.3/tipTip.css">
|
||||
<link rel="stylesheet" href="../admin/themes/default/fontello/css/fontello.css">
|
||||
|
||||
<style>
|
||||
/* 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 */
|
||||
|
||||
html {font-family:"Corbel","Lucida Grande","Verdana",sans-serif;color:#222;font-size:13px;}
|
||||
|
||||
a {color:#247EBF;text-decoration:none;}
|
||||
a:hover {color:#EB9C39;border-bottom-width:1px;border-style:dotted;text-shadow:1px 1px 0 #ddd;}
|
||||
|
||||
blockquote {border:1px solid #cdcdcd;background:#F9F9F9;padding:8px;}
|
||||
hr {margin:10px 30px;color:#fff;}
|
||||
ul {margin-left:25px;}
|
||||
p {margin:8px 0;}
|
||||
|
||||
h1 {color:#fff;font-size:26px;padding:10px 15px;text-shadow:1px 1px 0 #999;
|
||||
background:#45484d;background:linear-gradient(to bottom, #45484d 0%,#333333 100%);
|
||||
}
|
||||
h2 {color:#fff;font-size:20px;padding:5px 10px;text-shadow:1px 1px 0 #555;
|
||||
background:#f2a841;background:linear-gradient(to bottom, #f2a841 0%,#ef6b13 100%);
|
||||
}
|
||||
h2#errorWrapper {color:#F42C00;font-weight:normal;
|
||||
background:#eaeaea;background:linear-gradient(to bottom, #eaeaea 0%, #afafaf 100%);
|
||||
}
|
||||
h3 {display:inline-block;padding:5px 10px;color:#555;font-weight:bold;text-align:center;
|
||||
border-radius:8px 8px 0 0;text-shadow:1px 1px 0 #bbb;
|
||||
background:#f2f2f2;background:linear-gradient(to bottom, #f2f2f2 0%,#cecece 100%);
|
||||
}
|
||||
|
||||
#the_header {border-bottom:1px solid #cdcdcd;margin-bottom:1px;}
|
||||
#the_footer {background:#EAEAEA;border-top:1px solid #cdcdcd;padding:10px;clear:both;}
|
||||
|
||||
#the_methods {width:250px;float:left;border-style:solid;border-color:#cdcdcd;border-width:1px 1px 0 0;
|
||||
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAH0lEQVQImSXHMQEAMAwCMOrfK0jIjuVL2gLBzyHJtgd7wBdU3Vt/7AAAAABJRU5ErkJggg==);
|
||||
}
|
||||
#methodsList {font-size:1.1em;margin:5px 0 10px 10px;list-style:none;}
|
||||
#methodsList li:before {content:"\203A\00A0";font-weight:bold;color:#EB9C39;font-size:1.1em;}
|
||||
#methodsList li:hover:before {content:"\00A0\203A";}
|
||||
|
||||
#the_page {margin-left:252px;border-style:solid;border-color:#cdcdcd;border-width:1px 0 0 1px;}
|
||||
#the_content {padding:10px;}
|
||||
|
||||
#methodParams {margin-right:230px;}
|
||||
#methodParams thead td {background:#DEE3E9;font-weight:bold;padding:2px 5px;}
|
||||
#methodParams td {padding:2px;border:1px solid #cdcdcd;vertical-align:middle;}
|
||||
#methodParams tbody tr:nth-child(even) {background:#f7f7f7;}
|
||||
#methodParams tbody tr td:first-child {font-family:monospace;font-size:0.95em;}
|
||||
#methodParams td.mini {width:0px;text-align:center;}
|
||||
#methodParams tfoot {font-size:0.95em;}
|
||||
#methodParams td.input {text-align:center;}
|
||||
#methodParams td.input input[type="text"] {width:97%;font-size:0.9em;background:#f7f7f7;border:1px solid #ccc;border-radius:2px;}
|
||||
#methodParams td.input input[type="text"]:hover, #methodParams td.input input[type="text"]:focus {border-color:#C7E2F1;border-top-color:#96BCD7;background:#fff;}
|
||||
#methodParams .type {display:inline-block;width:16px;height:16px;font-size:12px;line-height:16px;background:#ddd;border-radius:8px;font-weight:bold;text-align:center;color:#222;}
|
||||
#methodParams .subtype {vertical-align:super;}
|
||||
|
||||
#testForm {float:right;}
|
||||
#testForm td {padding:2px 0;}
|
||||
#testForm tr:last-child td {padding:8px 0 5px 0;}
|
||||
#testForm blockquote {width:200px;}
|
||||
|
||||
#introMessage {font-size:1.1em;}
|
||||
#urlForm {margin-bottom:10px;}
|
||||
|
||||
a.button {color:#fff;padding:3px 8px;border:1px solid #91bb5c;font-size:0.9em;margin-right:3px;display:inline-block;
|
||||
border-radius:5px;text-shadow:1px 1px 0 #666;
|
||||
background:#84bb3c;background:linear-gradient(to bottom, #84bb3c 0%, #3f5a1d 100%);
|
||||
}
|
||||
a.button:hover {color:#E5FF00;}
|
||||
|
||||
.methodInfo {float:right;display:inline-block;width:16px;height:16px;font-size:12px;line-height:16px;background:#555;border-radius:8px;font-family:"Times New Roman",sans-serif;font-style:italic;font-weight:bold;text-align:center;color:#fff;}
|
||||
.methodInfo:hover {border:none;text-shadow:none;background:#888;cursor:pointer;color:#fff;}
|
||||
#tiptip_content { font-size:12px; }
|
||||
|
||||
#iframeWrapper {width:100%;height:300px;padding:3px 3px 20px 3px;background:#F9F9F9;border:1px solid #cdcdcd;overflow:hidden;position:relative;}
|
||||
iframe {width:100%;height:100%;background:#fff;}
|
||||
|
||||
div.onlys {background:#faa;color:#fff;border:1px solid #f22;padding:.25em .5em;display:table;border-radius:4px;margin-bottom:0.5em;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="ws/ws.css">
|
||||
<link rel="stylesheet" href="ws/jquery.json-viewer.css">
|
||||
|
||||
<script src="../themes/default/js/jquery.min.js"></script>
|
||||
<script src="../themes/default/js/jquery.cookie.js"></script>
|
||||
<script src="../themes/default/js/plugins/jquery.tipTip.minified.js"></script>
|
||||
<script src="ws/jquery.json-viewer.js"></script>
|
||||
<script src="ws/ws.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a name="top"></a>
|
||||
|
||||
<div id="the_header">
|
||||
<h1>Piwigo web API (web-services) explorer</h1>
|
||||
</div> <!-- the_header -->
|
||||
<div id="the_body">
|
||||
<a name="top"></a>
|
||||
|
||||
<i class="darkModeButton icon-moon-inv" title="Toogle Dark Mode"></i>
|
||||
|
||||
<div id="the_methods">
|
||||
<h2>Available methods</h2>
|
||||
<div id="the_header">
|
||||
<a title="Go to admin page" href="../admin.php"><img src="ws/piwigo-logo-minimal.svg"></a>
|
||||
<h1>Piwigo web API (web-services) explorer</h1>
|
||||
</div> <!-- the_header -->
|
||||
|
||||
<div id="the_container">
|
||||
|
||||
<div id="the_methods">
|
||||
<h2>Available methods</h2>
|
||||
|
||||
<ul id="methodsList">
|
||||
</ul>
|
||||
</div> <!-- the_methods -->
|
||||
|
||||
<div id="the_page">
|
||||
<h2 id="methodName" style="display:none;"></h2>
|
||||
<h2 id="errorWrapper" style="display:none;"></h2>
|
||||
|
||||
<div id="the_content">
|
||||
<form id="urlForm" style="display:none;">
|
||||
<input type="text" name="ws_url" size="60">
|
||||
<input type="submit" value="Go!">
|
||||
</form>
|
||||
|
||||
<blockquote id="introMessage">
|
||||
<p>
|
||||
<b>API = Application Programming Interface.</b><br>
|
||||
This is the way other applications can communicate with Piwigo. This feature is also know as Web Services.
|
||||
</p>
|
||||
|
||||
<p>Examples:</p>
|
||||
<ul>
|
||||
<li>Wordpress (web blog software) can display random photos from a Piwigo gallery in its sidebar</li>
|
||||
<li>Lightroom (photo management software for desktop) can create albums and upload photos to Piwigo</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This page lists all API methods available on your Piwigo installation, part of the Piwigo core or added by third-party plugins.
|
||||
For each method you can consult required and optional parameters, and even test them in direct live!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information you can consult our Wiki <a href="http://piwigo.org/doc/doku.php?id=dev:webapi:start" target="_blank">Piwigo Web API</a> and <a href="http://piwigo.org/forum" target="_blank">our forums</a>.
|
||||
</p>
|
||||
</blockquote> <!-- introMessage -->
|
||||
|
||||
|
||||
<form id="methodWrapper" style="display:none;">
|
||||
<div id="methodDescription" style="display:none;">
|
||||
<h3>Description</h3>
|
||||
<blockquote>
|
||||
</blockquote>
|
||||
<br>
|
||||
</div> <!-- methodDescription -->
|
||||
|
||||
<div id="testForm">
|
||||
<h3>Test</h3>
|
||||
<blockquote>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Request format :</td>
|
||||
<td>
|
||||
<select id="requestFormat">
|
||||
<option value="get" selected>GET</option>
|
||||
<option value="post">POST</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Response format :</td>
|
||||
<td>
|
||||
<select id="responseFormat">
|
||||
<option value="rest" selected>REST (xml)</option>
|
||||
<option value="json">JSON</option>
|
||||
<option value="php">PHP serial</option>
|
||||
<option value="xmlrpc">XML RPC</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<a href="#" class="button" id="invokeMethod">INVOKE</a>
|
||||
<a href="#" class="button" id="invokeMethodBlank">INVOKE (new window)</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div> <!-- testForm -->
|
||||
|
||||
<div id="methodParams">
|
||||
<h3>Method parameters</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width:150px;">Name</td>
|
||||
<td class="mini">Extra</td>
|
||||
<td class="mini">Type</td>
|
||||
<td style="width:300px;">Value</td>
|
||||
<td class="mini">Send</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<b>*</b>: required, <b>?</b>: optional, <b>[]</b>: can be an array (use a pipe | to split values)<br>
|
||||
<b>B</b>: boolean, <b>I</b>: integer, <b>F</b>: float, <b>+</b>: positive, <b>ø</b>: not null
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div> <!-- methodParams -->
|
||||
|
||||
<div id="requestDisplay" style="display:none;">
|
||||
<br>
|
||||
<h3>Request</h3>
|
||||
<blockquote>
|
||||
<pre class="url"></pre>
|
||||
<pre class="params"></pre>
|
||||
</blockquote>
|
||||
</div> <!-- requestDisplay -->
|
||||
|
||||
<br>
|
||||
<h3>Result</h3>
|
||||
<div id="iframeWrapper">
|
||||
<iframe src="" id="invokeFrame" name="invokeFrame"></iframe>
|
||||
<a href="#iframe-bottom" id="increaseIframe"><b>↓</b> increase height</a> •
|
||||
<a href="#iframe-bottom" id="decreaseIframe"><b>↑</b> decrease height</a>
|
||||
<a name="iframe-bottom"></a>
|
||||
<div id="search">
|
||||
<i class="icon-search"></i>
|
||||
<input type="text" placeholder="Search">
|
||||
</div>
|
||||
</form> <!-- iframeWrapper -->
|
||||
|
||||
<!-- hidden form for POST submition -->
|
||||
<form method="post" action="" target="" id="invokeForm" style="display:none;"></form>
|
||||
|
||||
</div> <!-- the_content -->
|
||||
|
||||
</div> <!-- the_page -->
|
||||
|
||||
<div id="the_footer">
|
||||
Copyright © 2002-2019 <a href="http://piwigo.org">Piwigo Team</a>
|
||||
</div> <!-- the_footer -->
|
||||
|
||||
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/tiptip/1.3/jquery.tipTip.minified.js"></script>
|
||||
|
||||
<script>
|
||||
// global vars
|
||||
var cachedMethods = new Array;
|
||||
var 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() {
|
||||
$("#iframeWrapper").css('height', $("#iframeWrapper").height()+100);
|
||||
adaptHeight();
|
||||
});
|
||||
$("#decreaseIframe").click(function() {
|
||||
if ($("#iframeWrapper").height() > 200) {
|
||||
$("#iframeWrapper").css('height', $("#iframeWrapper").height()-100);
|
||||
adaptHeight();
|
||||
}
|
||||
});
|
||||
|
||||
// mask all wrappers
|
||||
function resetDisplay() {
|
||||
$("#errorWrapper").hide();
|
||||
$("#methodWrapper").hide();
|
||||
$("#methodName").hide();
|
||||
$("#urlForm").hide();
|
||||
$("#methodDescription blockquote").empty();
|
||||
$("#methodDescription").hide();
|
||||
$("#requestDisplay").hide();
|
||||
$("#invokeFrame").attr('src','');
|
||||
}
|
||||
|
||||
// give the same size to methods list and main page
|
||||
function adaptHeight() {
|
||||
$("#the_page").css('height', 'auto');
|
||||
$("#the_methods").css('height', 'auto');
|
||||
|
||||
min_h = $(window).height()-$("#the_header").outerHeight()-$("#the_footer").outerHeight()-3;
|
||||
h = Math.max(min_h, Math.max($("#the_methods").height(), $("#the_page").height()));
|
||||
|
||||
$("#the_page").css('height', h);
|
||||
$("#the_methods").css('height', h);
|
||||
}
|
||||
|
||||
// display error wrapper
|
||||
function displayError(error) {
|
||||
resetDisplay();
|
||||
$("#errorWrapper").html("<b>Error:</b> "+ error).show();
|
||||
adaptHeight();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
result = parsePwgJSON(result);
|
||||
|
||||
if (result!=null) {
|
||||
methods = result.methods;
|
||||
|
||||
var ml = '';
|
||||
for (var i=0; i<methods.length; i++)
|
||||
{
|
||||
ml += '<li><a href="#top">'+ methods[i]+'</a></li>';
|
||||
}
|
||||
$("#methodsList").html(ml).show();
|
||||
|
||||
adaptHeight();
|
||||
|
||||
// trigger method selection
|
||||
$("#methodsList li a").click(function() {
|
||||
selectMethod($(this).html());
|
||||
});
|
||||
}
|
||||
}).error(function(jqXHR, textStatus, errorThrown) {
|
||||
askForUrl();
|
||||
});
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (result.options.post_only || result.options.admin_only) {
|
||||
var onlys = '<div class="onlys">';
|
||||
if (result.options.post_only) {
|
||||
onlys+= 'POST only. ';
|
||||
}
|
||||
if (result.options.admin_only) {
|
||||
onlys+= 'Admin only. ';
|
||||
}
|
||||
onlys+= '</div>';
|
||||
|
||||
result.description = onlys + result.description;
|
||||
}
|
||||
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();
|
||||
|
||||
if (method.description != "") {
|
||||
$("#methodDescription blockquote").html(method.description);
|
||||
$("#methodDescription").show();
|
||||
}
|
||||
|
||||
$("#requestFormat").val(method.options.post_only ? 'post' : 'get');
|
||||
|
||||
var methodParams = '';
|
||||
if (method.params && method.params.length>0) {
|
||||
for (var i=0; i<method.params.length; i++) {
|
||||
var param = method.params[i],
|
||||
isOptional = param.optional,
|
||||
acceptArray = param.acceptArray,
|
||||
defaultValue = param.defaultValue == null ? '' : param.defaultValue,
|
||||
info = param.info == null ? '' : '<a class="methodInfo" title="'+ param.info.replace(/"/g, '"') + '">i</a>',
|
||||
type = '';
|
||||
|
||||
if (param.type.match(/bool/)) type+= '<span class=type>B</span>';
|
||||
if (param.type.match(/int/)) type+= '<span class=type>I</span>';
|
||||
if (param.type.match(/float/)) type+= '<span class=type>F</span>';
|
||||
if (param.type.match(/positive/)) type+= '<span class=subtype>+</span>';
|
||||
if (param.type.match(/notnull/)) type+= '<span class=subtype>ø</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 + info +'</td>'+
|
||||
'<td class="mini">'+ (isOptional ? '?':'*') + (acceptArray ? ' []':'') +'</td>'+
|
||||
'<td class="mini">'+ type +'</td>'+
|
||||
'<td class="input"><input type="text" class="methodParameterValue" data-id="'+ i +'" value="'+ defaultValue +'"></td>'+
|
||||
'<td class="mini"><input type="checkbox" class="methodParameterSend" data-id="'+ i +'" '+ (isOptional ? '':'checked="checked"') +'></td>'+
|
||||
'</tr>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
methodParams = '<tr><td colspan="4">This method takes no parameters</td></tr>';
|
||||
}
|
||||
|
||||
$("#methodParams tbody").html(methodParams);
|
||||
$("#methodWrapper").show();
|
||||
|
||||
adaptHeight();
|
||||
|
||||
// trigger field modification
|
||||
$("input.methodParameterValue").change(function() {
|
||||
$("input.methodParameterSend[data-id='"+ $(this).data('id') +"']").attr('checked', 'checked');
|
||||
});
|
||||
|
||||
// tiptip
|
||||
$(".methodInfo").tipTip({
|
||||
maxWidth:"300px",
|
||||
defaultPosition:"right",
|
||||
delay:0
|
||||
});
|
||||
}
|
||||
|
||||
// invoke method
|
||||
function invokeMethod(methodName, newWindow) {
|
||||
var method = cachedMethods[ methodName ];
|
||||
|
||||
var reqUrl = ws_url +"?format="+ $("#responseFormat").val();
|
||||
|
||||
// GET
|
||||
if ($("#requestFormat").val() == 'get') {
|
||||
reqUrl+= "&method="+ methodName;
|
||||
|
||||
for (var i=0; i<method.params.length; i++) {
|
||||
if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var paramValue = $("input.methodParameterValue[data-id='"+ i +"']").val();
|
||||
|
||||
var 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 {
|
||||
$("#invokeFrame").attr('src', reqUrl);
|
||||
}
|
||||
|
||||
$('#requestDisplay').show()
|
||||
.find('.url').html(reqUrl).end()
|
||||
.find('.params').hide();
|
||||
}
|
||||
// POST
|
||||
else {
|
||||
var params = {};
|
||||
|
||||
var form = $("#invokeForm");
|
||||
form.attr('action', reqUrl);
|
||||
|
||||
var t = '<input type="hidden" name="method" value="'+ methodName +'">';
|
||||
|
||||
for (var i=0; i<method.params.length; i++) {
|
||||
if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var 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] = [];
|
||||
|
||||
<div id="methodsList">
|
||||
|
||||
$.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 +'">';
|
||||
}
|
||||
}
|
||||
|
||||
form.html(t);
|
||||
form.attr('target', newWindow ? "_blank" : "invokeFrame");
|
||||
form.submit();
|
||||
</div>
|
||||
</div> <!-- the_methods -->
|
||||
|
||||
<div id="the_page">
|
||||
<div id="the_title">
|
||||
<h2 id="methodName" style="display:none;"></h2>
|
||||
<span id="onlys"></span>
|
||||
</div>
|
||||
<h2 id="errorWrapper" style="display:none;"></h2>
|
||||
|
||||
<div id="the_content">
|
||||
<form id="urlForm" style="display:none;">
|
||||
<input type="text" name="ws_url" size="60">
|
||||
<input type="submit" value="Go!">
|
||||
</form>
|
||||
|
||||
<div class="card" id="introMessage">
|
||||
<h3 class="card-title"><i class="icon-info-circled-1"></i>What is this page ?</h3>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
<b>API = Application Programming Interface.</b><br>
|
||||
This is the way other applications can communicate with Piwigo. This feature is also know as Web Services.
|
||||
</p>
|
||||
|
||||
$('#requestDisplay').show()
|
||||
.find('.url').html(reqUrl).end()
|
||||
.find('.params').show().html(JSON.stringify(params, null, 4));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
<p>Examples:</p>
|
||||
<ul>
|
||||
<li>Wordpress (web blog software) can display random photos from a Piwigo gallery in its sidebar</li>
|
||||
<li>Lightroom (photo management software for desktop) can create albums and upload photos to Piwigo</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This page lists all API methods available on your Piwigo installation, part of the Piwigo core or added by third-party plugins.
|
||||
For each method you can consult required and optional parameters, and even test them in direct live!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information you can consult our Wiki <a href="http://piwigo.org/doc/doku.php?id=dev:webapi:start" target="_blank">Piwigo Web API</a> and <a href="http://piwigo.org/forum" target="_blank">our forums</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div> <!-- introMessage -->
|
||||
|
||||
|
||||
<form id="methodWrapper" style="display:none;">
|
||||
<div class="card" id="methodDescription" style="display:none;">
|
||||
<h3 class="card-title"><i class="icon-book"></i>Description</h3>
|
||||
<blockquote>
|
||||
</blockquote>
|
||||
</div> <!-- methodDescription -->
|
||||
|
||||
<div id="methodControl">
|
||||
|
||||
<div class="methodControlContainer">
|
||||
<div class="card" id="methodParams">
|
||||
<h3 class="card-title"><i class="icon-equalizer"></i>Method parameters</h3>
|
||||
<div class="card-content">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td class="mini">Type</td>
|
||||
<td>Value</td>
|
||||
<td class="mini">Send</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<span class="no-params" style="display: none;">This method takes no parameters</span>
|
||||
</div>
|
||||
</div> <!-- methodParams -->
|
||||
</div> <!-- methodControlContainer -->
|
||||
|
||||
<div class="methodControlContainer">
|
||||
<div class="card" id="testForm">
|
||||
<h3 class="card-title"><i class="icon-wrench"></i>Test</h3>
|
||||
<div class="card-content">
|
||||
|
||||
<div class="select-group">
|
||||
<label for='requestFormat'>Request format</label>
|
||||
<div class="select">
|
||||
<select id="requestFormat">
|
||||
<option value="get" selected>GET</option>
|
||||
<option value="post">POST</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='select-group'>
|
||||
<label for='responseFormat'>Response format</label>
|
||||
<div class="select">
|
||||
<select id="responseFormat">
|
||||
<option value="json" selected>JSON</option>
|
||||
<option value="rest" selected>REST (xml)</option>
|
||||
<option value="php">PHP serial</option>
|
||||
<option value="xmlrpc">XML RPC</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testAction">
|
||||
<a href="#iframe-bottom" class="button" id="invokeMethod">INVOKE</a>
|
||||
<a href="#" class="button" id="invokeMethodBlank">INVOKE (new window)</a>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- testForm -->
|
||||
</div> <!-- methodControlContainer -->
|
||||
|
||||
</div> <!-- methodControl -->
|
||||
|
||||
<div class="card-2" id="requestURLDisplay" style="display:none;">
|
||||
<h3 class="card-title"><i class="icon-network"></i>Request</h3>
|
||||
<div class="card-content">
|
||||
<blockquote>
|
||||
<pre class="url"></pre>
|
||||
<pre class="params"></pre>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div> <!-- requestDisplay -->
|
||||
|
||||
<div class="card-2" id="requestResultDisplay" style="display:none;">
|
||||
<h3 class="card-title"><i class="icon-code"></i>Result</h3>
|
||||
<div class="card-content">
|
||||
<div id="resultWrapper">
|
||||
<iframe src="" id="invokeFrame" name="invokeFrame"></iframe>
|
||||
<pre id="json-viewer"></pre>
|
||||
</div>
|
||||
<div id="iframeAction">
|
||||
<a href="#iframe-bottom" id="increaseIframe"><i class="icon-down-open"></i> increase height</a>
|
||||
<a href="#iframe-bottom" id="decreaseIframe"><i class="icon-down-open"></i> decrease height</a>
|
||||
<span id="iframe-bottom"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form> <!-- resultWrapper -->
|
||||
|
||||
<!-- hidden form for POST submition -->
|
||||
<form method="post" action="" target="" id="invokeForm" style="display:none;"></form>
|
||||
|
||||
</div> <!-- the_content -->
|
||||
|
||||
</div> <!-- the_page -->
|
||||
|
||||
</div> <!-- the_container -->
|
||||
|
||||
<div id="the_footer">
|
||||
Copyright © 2002-2021 <a href="http://piwigo.org">Piwigo Team</a>
|
||||
</div> <!-- the_footer -->
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
57
tools/ws/jquery.json-viewer.css
Normal file
57
tools/ws/jquery.json-viewer.css
Normal file
|
@ -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;
|
||||
}
|
158
tools/ws/jquery.json-viewer.js
Normal file
158
tools/ws/jquery.json-viewer.js
Normal file
|
@ -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, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/"/g, '"');
|
||||
|
||||
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(/"/g, '\\"');
|
||||
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);
|
66
tools/ws/piwigo-logo-minimal.svg
Normal file
66
tools/ws/piwigo-logo-minimal.svg
Normal file
|
@ -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 |
601
tools/ws/ws.css
Normal file
601
tools/ws/ws.css
Normal file
|
@ -0,0 +1,601 @@
|
|||
|
||||
/* 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%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
/* #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);
|
||||
}
|
492
tools/ws/ws.js
Normal file
492
tools/ws/ws.js
Normal file
|
@ -0,0 +1,492 @@
|
|||
$(() => {
|
||||
// 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) {
|
||||
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, '"') + '"></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)">ø</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) {
|
||||
|
||||
$('#requestURLDisplay').show();
|
||||
$('#requestResultDisplay').show();
|
||||
|
||||
let method = cachedMethods[methodName];
|
||||
|
||||
let reqUrl = ws_url + "?format=" + $("#responseFormat").val();
|
||||
|
||||
// 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 {
|
||||
if ($("#responseFormat").val() === 'json') {
|
||||
$("#invokeFrame").hide();
|
||||
$('#json-viewer').show();
|
||||
fetch(reqUrl)
|
||||
.then(data => data.json())
|
||||
.then(json => {
|
||||
$('#json-viewer').jsonViewer(json);
|
||||
})
|
||||
} else {
|
||||
$("#invokeFrame").show();
|
||||
$('#json-viewer').hide();
|
||||
$("#invokeFrame").attr('src', reqUrl);
|
||||
}
|
||||
}
|
||||
|
||||
$('#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 && $("#responseFormat").val() === 'json') {
|
||||
$("#invokeFrame").hide();
|
||||
$('#json-viewer').show();
|
||||
jQuery.ajax({
|
||||
url: reqUrl,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
"method": methodName,
|
||||
...params
|
||||
},
|
||||
success : function(data) {
|
||||
$('#json-viewer').jsonViewer(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');
|
||||
}
|
||||
})
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue