Changeset 18079


Ignore:
Timestamp:
Sep 20, 2012, 6:04:23 PM (12 years ago)
Author:
mistic100
Message:

feature 2751: Redesign web API, webservices explorer

Location:
trunk/tools
Files:
1 deleted
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/ws.htm

    r3282 r18079  
    1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    2 <html>
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
     2   "http://www.w3.org/TR/html4/strict.dtd">
     3<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
    34<head>
    4 <title>PWG web service explorer</title>
    5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    6 <script type="text/javascript" src="prototype.js" ></script>
    7 
    8 <script type="text/javascript">
    9 
    10 function setVisibility(id, vis)
     5  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     6  <title>Piwigo web API (web-services) explorer</title>
     7 
     8  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
     9 
     10  <style type="text/css">
     11  /* BEGIN CSS RESET
     12    http://meyerweb.com/eric/tools/css/reset
     13    v2.0 | 20110126 | License: none (public domain) */
     14  html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code,
     15  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,
     16  fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed,
     17  figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video
     18  {margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;}
     19
     20  article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;}
     21  body {line-height:1.1;}
     22  blockquote, q {quotes:none;}
     23  blockquote:before, blockquote:after, q:before, q:after {content:'';content:none;}
     24  table {border-collapse:collapse;border-spacing:0;}
     25  /* END CSS RESET */
     26
     27  html {font-family:"Corbel","Lucida Grande","Verdana",sans-serif;color:#222;font-size:13px;}
     28
     29  a {color:#247EBF;text-decoration:none;}
     30  a:hover {color:#EB9C39;border-bottom-width:1px;border-style:dotted;
     31    text-shadow:1px 1px 0 #ddd;-moz-text-shadow:1px 1px 0 #ddd;-webkit-text-shadow:1px 1px 0 #ddd;
     32  }
     33  blockquote {border:1px solid #cdcdcd;background:#F9F9F9;padding:8px;}
     34  hr {margin:10px 30px;color:#fff;}
     35  ul {margin-left:25px;}
     36  p {margin:8px 0;}
     37
     38  h1 {color:#fff;font-size:26px;padding:10px 15px;
     39    text-shadow:1px 1px 0 #999;-moz-text-shadow:1px 1px 0 #999;-webkit-text-shadow:1px 1px 0 #999;
     40    background:#45484d;background:-moz-linear-gradient(top, #45484d 0%, #333333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#45484d), color-stop(100%,#333333));background:-webkit-linear-gradient(top, #45484d 0%,#333333 100%);background:-o-linear-gradient(top, #45484d 0%,#333333 100%);background:-ms-linear-gradient(top, #45484d 0%,#333333 100%);background:linear-gradient(to bottom, #45484d 0%,#333333 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#45484d', endColorstr='#333333',GradientType=0 );
     41  }
     42  h2 {color:#fff;font-size:20px;padding:5px 10px;
     43    text-shadow:1px 1px 0 #555;-moz-text-shadow:1px 1px 0 #555;-webkit-text-shadow:1px 1px 0 #555;
     44    background:#f2a841;background:-moz-linear-gradient(top, #f2a841 0%, #ef6b13 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2a841), color-stop(100%,#ef6b13));background:-webkit-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:-o-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:-ms-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:linear-gradient(to bottom, #f2a841 0%,#ef6b13 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2a841', endColorstr='#ef6b13',GradientType=0 );
     45  }
     46  h2#errorWrapper {color:#F42C00;font-weight:normal;
     47    background:#eaeaea;background:-moz-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-webkit-gradient(linear, lefttop, leftbottom, color-stop(0%,#eaeaea), color-stop(100%,#afafaf));background:-webkit-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-o-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-ms-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:linear-gradient(tobottom, #eaeaea 0%, #afafaf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eaeaea', endColorstr='#afafaf', GradientType=0);
     48  }
     49  h3 {display:inline-block;padding:5px 10px;color:#555;font-weight:bold;text-align:center;
     50    border-radius:8px 8px 0 0;-moz-border-radius:8px 8px 0 0;-webkit-border-radius:8px 8px 0 0;
     51    text-shadow:1px 1px 0 #bbb;-moz-text-shadow:1px 1px 0 #bbb;-webkit-text-shadow:1px 1px 0 #bbb;
     52    background:#f2f2f2;background:-moz-linear-gradient(top, #f2f2f2 0%, #cecece 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f2f2), color-stop(100%,#cecece));background:-webkit-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:-o-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:-ms-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:linear-gradient(to bottom, #f2f2f2 0%,#cecece 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f2f2', endColorstr='#cecece',GradientType=0 );
     53  }
     54
     55  #the_header {border-bottom:1px solid #cdcdcd;margin-bottom:1px;}
     56  #the_footer {background:#EAEAEA;border-top:1px solid #cdcdcd;padding:10px;clear:both;}
     57
     58  #the_methods {width:250px;float:left;border-style:solid;border-color:#cdcdcd;border-width:1px 1px 0 0;
     59    background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAH0lEQVQImSXHMQEAMAwCMOrfK0jIjuVL2gLBzyHJtgd7wBdU3Vt/7AAAAABJRU5ErkJggg==);
     60  }
     61  #the_methods ul {font-size:1.1em;margin:5px 0 10px 10px;list-style:none;}
     62  #the_methods li:before {content:"\203A\00A0";font-weight:bold;color:#EB9C39;font-size:1.1em;}
     63  #the_methods li:hover:before {content:"\00A0\203A";}
     64
     65  #the_page {margin-left:252px;border-style:solid;border-color:#cdcdcd;border-width:1px 0 0 1px;}
     66  #the_content {padding:10px;}
     67
     68  #methodParams {display:inline-block;}
     69  #methodParams thead td {background:#DEE3E9;font-weight:bold;padding:2px 5px;}
     70  #methodParams td {padding:2px;border:1px solid #cdcdcd;vertical-align:middle;}
     71  #methodParams tbody tr:nth-child(even) {background:#f7f7f7;}
     72  #methodParams tbody tr td:first-child {font-family:monospace;font-size:0.95em;}
     73  #methodParams td.mini {width:0px;text-align:center;}
     74  #methodParams tfoot {font-size:0.95em;}
     75  #methodParams td.input {text-align:center;}
     76  #methodParams td.input input[type="text"] {width:97%;font-size:0.9em;background:#f7f7f7;border:1px solid #ccc;
     77    border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;
     78  }
     79  #methodParams td.input input[type="text"]:hover, #methodParams td.input input[type="text"]:focus {border-color:#C7E2F1;border-top-color:#96BCD7;background:#fff;}
     80
     81  #testForm {display:inline-block;margin-left:15px;}
     82  #testForm td {padding:2px 0;}
     83  #testForm tr:last-child td {padding:8px 0 5px 0;}
     84  #testForm blockquote {width:200px;}
     85 
     86  #introMessage {font-size:1.1em;}
     87  #urlForm {margin-bottom:10px;}
     88
     89  a.button {color:#fff;padding:3px 8px;border:1px solid #91bb5c;font-size:0.9em;margin-right:3px;display:inline-block;
     90    border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;
     91    text-shadow:1px 1px 0 #666;-moz-text-shadow:1px 1px 0 #666;-webkit-text-shadow:1px 1px 0 #666;
     92    background:#84bb3c;background:-moz-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-webkit-gradient(linear, lefttop, leftbottom, color-stop(0%,#84bb3c), color-stop(100%,#3f5a1d));background:-webkit-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-o-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-ms-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:linear-gradient(tobottom, #84bb3c 0%, #3f5a1d 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#84bb3c', endColorstr='#3f5a1d', GradientType=0);
     93  }
     94  a.button:hover {color:#E5FF00;}
     95 
     96  #iframeWrapper {width:100%;height:300px;padding:3px 3px 20px 3px;background:#F9F9F9;border:1px solid #cdcdcd;overflow:hidden;position:relative;}
     97  iframe {width:100%;height:100%;background:#fff;}
     98  </style>
     99 
     100</head>
     101
     102<body>
     103
     104<div id="the_header">
     105  <h1>Piwigo web API (web-services) explorer</h1>
     106</div> <!-- the_header -->
     107
     108<div id="the_methods">
     109  <h2>Available methods</h2>
     110 
     111  <ul id="methodsList">
     112  </ul>
     113</div> <!-- the_methods -->
     114
     115<div id="the_page">
     116  <h2 id="methodName" style="display:none;"></h2>
     117  <h2 id="errorWrapper" style="display:none;"></h2>
     118 
     119  <div id="the_content">
     120    <form id="urlForm" style="display:none;">
     121      <input type="text" name="ws_url" size="60">
     122      <input type="submit" value="Go!">
     123    </form>
     124   
     125    <blockquote id="introMessage">
     126      <p>
     127        <b>API = Application Programming Interface.</b><br>
     128        This is the way other applications can communicate with Piwigo. This feature is also know as Web Services.
     129      </p>
     130
     131      <p>Examples:</p>
     132      <ul>
     133        <li>Wordpress (web blog software) can display random photos from a Piwigo gallery in its sidebar</li>
     134        <li>Lightroom (photo management software for desktop) can create albums and upload photos to Piwigo</li>
     135      </ul>
     136
     137      <p>
     138        This page lists all API methods available on your Piwigo installation, part of the Piwigo core or added by third-party plugins.
     139        For each method you can consult required and optional parameters, and even test them in direct live!
     140      </p>
     141
     142      <p>
     143        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>.
     144      </p>
     145    </blockquote> <!-- introMessage -->
     146
     147
     148    <form id="methodWrapper" style="display:none;">
     149      <div id="methodDescription" style="display:none;">
     150        <h3>Description</h3>
     151        <blockquote>
     152        </blockquote>
     153       
     154        <hr>
     155      </div> <!-- methodDescription -->
     156     
     157      <div id="methodParams">
     158        <h3>Method parameters</h3>
     159        <table>
     160          <thead>
     161            <tr>
     162              <td style="width:150px;">Name</td>
     163              <td class="mini">Extra</td>
     164              <td style="width:300px;">Value</td>
     165              <td class="mini">Send</td>
     166            </tr>
     167          </thead>
     168         
     169          <tbody>
     170          </tbody>
     171         
     172          <tfoot>
     173            <tr>
     174              <td colspan="4"><b>*</b>: required parameter, <b>?</b>: optional parameter, <b>[]</b>: parameter can be an array (use a pipe | to split values)</td>
     175            </tr>
     176          </tfoot>
     177        </table>
     178      </div> <!-- methodParams -->
     179     
     180      <div id="testForm">
     181        <h3>Test</h3>
     182        <blockquote>
     183          <table>
     184            <tr>
     185              <td>Request format :</td>
     186              <td>
     187                <select id="requestFormat">
     188                  <option value="get" selected="selected">GET</option>
     189                  <option value="post">POST</option>
     190                </select>
     191              </td>
     192            </tr>
     193            <tr>
     194              <td>Response format :</td>
     195              <td>
     196                <select id="responseFormat">
     197                  <option value="rest" selected="selected">REST (xml)</option>
     198                  <option value="json">JSON</option>
     199                  <option value="php">PHP serial</option>
     200                  <option value="xmlrpc">XML RPC</option>
     201                </select>
     202              </td>
     203            </tr>
     204            <tr>
     205              <td colspan="2">
     206                <a href="#" class="button" id="invokeMethod">INVOKE</a>
     207                <a href="#" class="button" id="invokeMethodBlank">INVOKE (new window)</a>
     208              </td>
     209            </tr>
     210          </table>
     211        </blockquote>
     212      </div> <!-- testForm -->
     213     
     214      <hr>
     215     
     216      <h3>Result</h3>
     217      <div id="iframeWrapper">
     218        <iframe src="" id="invokeFrame" name="invokeFrame"></iframe>
     219        <a href="#bottom" id="increaseIframe"><b>&darr;</b> increase height</a> &#8226; <a href="#bottom" id="decreaseIframe"><b>&uarr;</b> decrease height</a>
     220        <a name="bottom"></a>
     221      </div>
     222    </form> <!-- iframeWrapper -->
     223   
     224    <!-- hidden form for POST submition -->
     225    <form method="post" action="" target="" id="invokeForm" style="display:none;"></form>
     226   
     227  </div> <!-- the_content -->
     228
     229</div> <!-- the_page -->
     230
     231<div id="the_footer">
     232  Copyright © 2002-2012 <a href="http://piwigo.org">Piwigo Team</a>
     233</div> <!-- the_footer -->
     234
     235
     236<script type="text/javascript"> 
     237// global vars
     238var cachedMethods = new Array;
     239var ws_url = "http://";
     240
     241// automatic detection of ws_url
     242match = document.location.toString().match(/^(https?.*\/)tools\/ws\.html?/);
     243if (match==null) {
     244  askForUrl();
     245}
     246else {
     247  ws_url = match[1]+'ws.php';
     248  getMethodList();
     249}
     250
     251// manual set of ws_url
     252$("#urlForm").submit(function() {
     253  ws_url = $(this).children("input[name='ws_url']").val();
     254  getMethodList();
     255  return false;
     256});
     257
     258// invoke buttons
     259$("#invokeMethod").click(function() {
     260  invokeMethod($("#methodName").html(), false);
     261  return false;
     262});
     263$("#invokeMethodBlank").click(function() {
     264  invokeMethod($("#methodName").html(), true);
     265  return false;
     266});
     267
     268// resizable iframe
     269$("#increaseIframe").click(function() {
     270  $("#iframeWrapper").css('height', $("#iframeWrapper").height()+100);
     271  adaptHeight();
     272});
     273$("#decreaseIframe").click(function() {
     274  if ($("#iframeWrapper").height() > 200) {
     275    $("#iframeWrapper").css('height', $("#iframeWrapper").height()-100);
     276    adaptHeight();
     277  }
     278});
     279
     280// mask all wrappers
     281function resetDisplay() {
     282  $("#errorWrapper").hide();
     283  $("#methodWrapper").hide();
     284  $("#methodName").hide();
     285  $("#urlForm").hide();
     286  $("#methodDescription").hide();
     287  $("#invokeFrame").attr('src','');
     288}
     289
     290// give the same size to methods list and main page
     291function adaptHeight()
    11292{
    12   $(id).style.visibility = vis;
    13 }
    14 
    15 function dumpError(err)
    16 {
    17         var s= 'Error ';
    18         if ('string' === typeof err )
    19          s += err;
    20         else
    21         {
    22     s += err.name+'<br/>';
    23          s += err.message;
    24          if (err.stack!=null)
    25          {//mozilla only
    26                 s += '<br/><small><pre>'+ err.stack + '</pre></small>';
    27          }
    28         }
    29   $("error").update(s);
    30 }
    31 
    32 var gServiceUrl;
    33 var gCachedMethods;
    34 
    35 Ajax.Responders.register({
    36 
    37 onException: function(req, err) {
    38         try {
    39                 document.pwgError = err;
    40                 dumpError(err);
    41         }
    42         catch (e)
    43         {
    44                 alert (err);
    45                 alert (err.message);
    46         }
    47 },
    48 
    49 onComplete: function(req, transport) {
    50         if (!req.responseIsSuccess())
    51         {
    52                 var s = 'Completion failure\n' + transport.status + ' ' + transport.statusText;
    53                 if (transport.status>=300)
    54                 {
    55                         s += '\n';
    56                         s += transport.responseText.substr(0,1000);
    57                 }
    58                 dumpError(s);
    59         }
    60  }
    61 }
    62 );
    63 
    64 
    65 function pwgGetJsonResult(transport)
    66 {
    67   var resp;
     293  $("#the_page").css('height', 'auto');
     294  $("#the_methods").css('height', 'auto');
     295 
     296  min_h = $(window).height()-$("#the_header").outerHeight()-$("#the_footer").outerHeight()-3;
     297  h = Math.max(min_h, Math.max($("#the_methods").height(), $("#the_page").height()));
     298 
     299  $("#the_page").css('height', h);
     300  $("#the_methods").css('height', h);
     301}
     302
     303// display error wrapper
     304function displayError(error) {
     305  resetDisplay();
     306  $("#errorWrapper").html("<b>Error:</b> "+ error).show();
     307  adaptHeight();
     308}
     309
     310// display ws_url form
     311function askForUrl() {
     312  if ($("#urlForm input[name='ws_url']").val() == "") {
     313    $("#urlForm input[name='ws_url']").val(ws_url);
     314  }
     315  $("#urlForm").show();
     316  displayError("can't contact web-services, please give absolute url to 'ws.php'");
     317}
     318
     319// parse Piwigo JSON
     320function parsePwgJSON(json) {
    68321  try {
    69                 eval('resp = ' + transport.responseText);
    70         }
    71         catch (e)
    72         {
    73                 var s = e.message;
    74                 s += '\n' + transport.responseText.substr(0,1000).escapeHTML();
    75                 throw new Error( s );
    76         }
    77   if (resp==null || resp.result==null || resp.stat==null || resp.stat!='ok')
    78   {
    79     var s = 'JSON evaluation error';
    80     if (resp)
    81     {
    82                         if (resp.stat!=null) s+= '\n'+resp.stat;
    83       if (resp.message!=null) s+= '\n'+ resp.message;
    84     }
    85     throw new Error(s);
    86   }
     322    resp = jQuery.parseJSON(json);
     323    if (resp==null | resp.result==null | resp.stat==null | resp.stat!='ok') {
     324      throw new Error();
     325    }
     326  }
     327  catch(e) {
     328    displayError("unable to parse JSON string");
     329    resp = {"stat": "ko", "result": "null"};
     330  }
     331 
    87332  return resp.result;
    88333}
    89334
    90 function pwgChangeUrl()
    91 {
    92   $("error").update("");
    93   setVisibility("methodListWrapper", "hidden");
    94   $("methodList").update("");
    95   setVisibility("methodWrapper", "hidden");
    96   setVisibility("methodDetailWrapper", "hidden");
    97 
    98   gServiceUrl = $F('ws_url');
    99   gCachedMethods = new Hash();
    100 
    101   try {
    102                 var ajaxReq = new Ajax.Request(
    103                                 gServiceUrl,
    104                                 {method:'get', parameters:'format=json&method=reflection.getMethodList',
    105                                  onSuccess: function (r) { onSuccess_getMethodList(r); }
    106                                 }
    107                         )
    108   }catch (e)
    109   {
    110     dumpError(e);
    111   }
     335// fetch methods list
     336function getMethodList() {
     337  resetDisplay();
     338 
     339  $.ajax({
     340    type: "GET",
     341    url: ws_url,
     342    data: { format: "json", method: "reflection.getMethodList" }
     343  }).done(function(result) {
     344    result = parsePwgJSON(result);
     345   
     346    if (result!=null) {
     347      methods = result.methods;
     348     
     349      var ml = '';
     350      for (var i=0; i<methods.length; i++)
     351      {
     352        ml += '<li><a href="#">'+ methods[i]+'</a></li>';
     353      }
     354      $("#methodsList").html(ml).show();
     355     
     356      adaptHeight();
     357     
     358      // trigger method selection
     359      $("#methodsList li a").click(function() {
     360        selectMethod($(this).html());
     361        return false;
     362      });
     363    }
     364  }).error(function(jqXHR, textStatus, errorThrown) {
     365    askForUrl();
     366  });
     367}
     368
     369// select method
     370function selectMethod(methodName) {
     371  $("#introMessage").hide();
     372 
     373  if (cachedMethods[ methodName ]) {
     374    fillNewMethod(methodName);
     375  }
     376  else {
     377    $.ajax({
     378      type: "GET",
     379      url: ws_url,
     380      data: { format: "json", method: "reflection.getMethodDetails", methodName: methodName }
     381    }).done(function(result) {
     382      result = parsePwgJSON(result);
     383   
     384      if (result!=null) {
     385        cachedMethods[ methodName ] = result;
     386        fillNewMethod(methodName);
     387      }
     388    }).error(function(jqXHR, textStatus, errorThrown) {
     389      displayError("unknown error");
     390    });
     391  }
     392}
     393
     394// display method details
     395function fillNewMethod(methodName) {
     396  resetDisplay();
     397 
     398  method = cachedMethods[ methodName ];
     399 
     400  $("#methodName").html(method.name).show();
     401 
     402  if (method.description != "") {
     403    $("#methodDescription blockquote").html(method.description);
     404    $("#methodDescription").show();
     405  }
     406 
     407  var methodParams = '';
     408  if (method.params && method.params.length>0) {
     409    for (var i=0; i<method.params.length; i++) {
     410      var isOptional = method.params[i].optional;
     411      var acceptArray = method.params[i].acceptArray;
     412      var defaultValue = method.params[i].defaultValue == null ? '' : method.params[i].defaultValue;
     413     
     414      // if an array is direclty printed, the delimiter is a comma where we use a pipe
     415      if (typeof defaultValue == 'object') {
     416        defaultValue = defaultValue.join('|');
     417      }
     418
     419      methodParams+= '<tr>'+
     420        '<td>'+ method.params[i].name +'</td>'+
     421        '<td class="mini">'+ (isOptional ? '?':'*') + (acceptArray ? ' []':'') +'</td>'+
     422        '<td class="input"><input type="text" class="methodParameterValue" data-id="'+ i +'" value="'+ defaultValue +'"></td>'+
     423        '<td class="mini"><input type="checkbox" class="methodParameterSend" data-id="'+ i +'" '+ (isOptional ? '':'checked="checked"') +'></td>'+
     424      '</tr>';
     425    }
     426        }
     427  else {
     428    methodParams = '<tr><td colspan="4">This method takes no parameters</td></tr>';
     429  }
     430 
     431  $("#methodParams tbody").html(methodParams);
     432  $("#methodWrapper").show();
     433 
     434  adaptHeight();
     435 
     436  // trigger field modification
     437  $("input.methodParameterValue").change(function() {
     438    $("input.methodParameterSend[data-id='"+ $(this).data('id') +"']").attr('checked', 'checked');
     439  });
     440}
     441
     442// invoke method
     443function invokeMethod(methodName, newWindow) {
     444        var method = cachedMethods[ methodName ];
     445
     446  var reqUrl = ws_url +"?format="+ $("#responseFormat").val();
     447 
     448  // GET
     449  if ($("#requestFormat").val() == 'get') {
     450    reqUrl+= "&method="+ methodName;
     451   
     452    for (var i=0; i<method.params.length; i++) {
     453      if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
     454        continue;
     455      }
     456
     457      var paramValue = $("input.methodParameterValue[data-id='"+ i +"']").val();
     458     
     459      var paramSplitted = paramValue.split('|');
     460      if (method.params[i].acceptArray &&  paramSplitted.length > 1) {
     461        $.each(paramSplitted, function(v) {
     462          reqUrl+= '&'+ method.params[i].name +'[]='+ paramSplitted[v];
     463        });
     464      }
     465      else {
     466        reqUrl+= '&'+ method.params[i].name +'='+ paramValue;
     467      }
     468    }
     469   
     470    if (newWindow) {
     471      window.open(reqUrl);
     472    }
     473    else {
     474      $("#invokeFrame").attr('src', reqUrl);
     475    }
     476  }
     477  // POST
     478  else {
     479    var form = $("#invokeForm");
     480    form.attr('action', reqUrl);
     481   
     482    var t = '<input type="hidden" name="method" value="'+ methodName +'">';
     483   
     484    for (var i=0; i<method.params.length; i++) {
     485      if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
     486        continue;
     487      }
     488
     489      var paramValue = $("input.methodParameterValue[data-id='"+ i +"']").val();
     490
     491      var paramSplitted = paramValue.split('|');
     492      if (method.params[i].acceptArray &&  paramSplitted.length > 1) {
     493        $.each(paramSplitted, function(v) {
     494          t+= '<input type="hidden" name="'+ method.params[i].name +'[]" value="'+ paramSplitted[v] +'">';
     495        });
     496      }
     497      else {
     498        t+= '<input type="hidden" name="'+ method.params[i].name +'" value="'+ paramValue +'">';
     499      }
     500    }
     501   
     502    form.html(t);
     503    form.attr('target', newWindow ? "_blank" : "invokeFrame");
     504    form.submit();
     505  }
     506 
    112507  return false;
    113508}
    114 
    115 function onSuccess_getMethodList(transport)
    116 {
    117         var result = pwgGetJsonResult(transport);
    118         var ml = '';
    119         for (var i=0; i<result.methods.length; i++)
    120         {
    121                 ml += '<li><a href="#" onclick="return pwgSelectMethod(this.innerHTML)">'+ result.methods[i]+'</a></li>';
    122         }
    123         $("methodList").update(ml);
    124         setVisibility("methodListWrapper", "visible");
    125 }
    126 
    127 function pwgSelectMethod(methodName)
    128 {
    129   $("error").update("");
    130   $("methodName").update(methodName);
    131   setVisibility("methodDetailWrapper", "hidden");
    132   setVisibility("methodWrapper", "visible");
    133 
    134   if ( gCachedMethods[methodName] )
    135     fillNewMethod( gCachedMethods[methodName] );
    136   else
    137   {
    138     try {
    139                 var ajaxReq = new Ajax.Request(
    140                                 gServiceUrl,
    141                                 {method:'get', parameters:'format=json&method=reflection.getMethodDetails&methodName='+methodName,
    142                                  onSuccess: function (r) { onSuccess_getMethodDetails(r); }
    143                                 }
    144                         )
    145     }catch (e)
    146     {
    147       dumpError( e );
    148     }
    149   }
    150   return false;
    151 }
    152 
    153 function onSuccess_getMethodDetails(transport)
    154 {
    155         var result = pwgGetJsonResult(transport);
    156   fillNewMethod( gCachedMethods[result.name] = result );
    157 }
    158 
    159 function fillNewMethod(method)
    160 {
    161         var methodParamsElt = $("methodParams");
    162         while (methodParamsElt.tBodies[0].rows.length)
    163                 methodParamsElt.tBodies[0].deleteRow(methodParamsElt.tBodies[0].rows.length-1);
    164 
    165         if (method.params && method.params.length>0)
    166         {
    167                 for (var i=0; i<method.params.length; i++)
    168                 {
    169                         var row = methodParamsElt.tBodies[0].insertRow(-1);
    170                         var isOptional = method.params[i].optional;
    171                         var acceptArray = method.params[i].acceptArray;
    172                         var defaultValue = method.params[i].defaultValue == null ? '' : method.params[i].defaultValue;
    173 
    174                         row.insertCell(0).innerHTML = method.params[i].name;
    175                         row.insertCell(1).innerHTML = '<span title="parameter is '+(isOptional ? 'optional':'required') +'">'+(isOptional ? '?':'*')+'</span>'
    176           + (method.params[i].acceptArray ? ' <span title="parameter can be an array; use | (pipe) character to split values">[ ]</span>':'');
    177                         row.insertCell(2).innerHTML = '<input id="methodParameterSend_'+i+'" type="checkbox" '+(isOptional ? '':'checked="checked"')+'/>';
    178                         row.insertCell(3).innerHTML = '<input id="methodParameterValue_'+i+'"" value="'+defaultValue+'" style="width:99%" onchange="$(\'methodParameterSend_'+i+'\').checked=true;"/>';
    179                 }
    180         }
    181         $("methodDescription").update(method.description);
    182         setVisibility("methodDetailWrapper", "visible");
    183 }
    184 
    185 function pwgInvokeMethod( newWindow )
    186 {
    187         var methodName = $('methodName').innerHTML;
    188         var method = gCachedMethods[methodName];
    189 
    190   var reqUrl = gServiceUrl;
    191   reqUrl += "?format="+$F('responseFormat');
    192 
    193   if ($('requestFormat').value == 'get')
    194   {
    195     reqUrl += "&method="+methodName;
    196     for ( var i=0; i<method.params.length; i++)
    197     {
    198       if (! $('methodParameterSend_'+i).checked)
    199         continue;
    200 
    201       if ( method.params[i].acceptArray &&  $F('methodParameterValue_'+i).split('|').length > 1 )
    202       {
    203         $F('methodParameterValue_'+i).split('|').each(
    204             function(v) {
    205               reqUrl += '&'+method.params[i].name+'[]='+v;
    206             }
    207           );
    208       }
    209       else
    210         reqUrl += '&'+method.params[i].name+'='+$F('methodParameterValue_'+i);
    211     }
    212     if ( !newWindow )
    213       $("invokeFrame").src = reqUrl;
    214     else
    215       window.open(reqUrl);
    216   }
    217   else
    218   {
    219     var form = $("invokeForm");
    220     form.action = reqUrl;
    221     var t = '<input type="hidden" name="'+'method'+'" value="'+methodName+'"/>';
    222     for ( var i=0; i<method.params.length; i++)
    223     {
    224       if (! $('methodParameterSend_'+i).checked)
    225         continue;
    226 
    227       if ( method.params[i].acceptArray &&  $F('methodParameterValue_'+i).split('|').length > 1 )
    228       {
    229         $F('methodParameterValue_'+i).split('|').each(
    230             function(v) {
    231               t += '<input type="hidden" name="'+method.params[i].name+'[]" value="'+v+'"/>';
    232             }
    233           );
    234       }
    235       else
    236         t += '<input type="hidden" name="'+method.params[i].name+'" value="'+$F('methodParameterValue_'+i)+'"/>';
    237     }
    238     form.innerHTML = t;
    239     form.target = newWindow ? "_blank" : "invokeFrame";
    240     form.submit();
    241   }
    242   return false;
    243 }
    244509</script>
    245 
    246 
    247 <style>
    248 #methodListWrapper {
    249   width: 13em;
    250   float: left;
    251   display: inline;
    252   visibility: hidden;
    253 }
    254 
    255 #methodList {
    256   padding-left: 10px;
    257   margin-left: 15px;
    258 }
    259 
    260 #methodWrapper {
    261   margin-left: 14em;
    262   visibility: hidden;
    263 }
    264 
    265 #methodName {
    266   margin-top: 0;
    267   margin-bottom: 3px;
    268 }
    269 
    270 
    271 #error {
    272   height: 90px;
    273   overflow: scroll;
    274   color: red;
    275 }
    276 
    277 #methodParams {
    278   border-collapse: collapse;
    279   font-size: small;
    280 }
    281 
    282 #methodParams input {
    283   font-size: 90%;
    284   border: 1px solid black;
    285   text-indent: 2px;
    286 }
    287 
    288 
    289 a {
    290   color: #02f;
    291   background-color: white;
    292   text-decoration: underline;
    293 }
    294 
    295 a:hover {
    296   color: white;
    297   background-color: #02f;
    298   text-decoration: none;
    299   cursor:pointer;
    300 }
    301 
    302 </style>
    303 
    304 </head>
    305 
    306 
    307 <body>
    308 
    309 <div>
    310  <label>PWG Web service url
    311   <input name="ws_url" id="ws_url" size="64"/>
    312 <script type="text/javascript">
    313   var match = document.location.toString().match(/^(https?.*\/)tools\/ws\.html?$/);
    314   if (match!=null) $('ws_url').value = match[1]+'ws.php';
    315 </script>
    316  </label>
    317  <a href="#" onclick="return pwgChangeUrl();">Go!</a>
    318 </div>
    319 
    320 <div id="error">
    321 </div>
    322 
    323 <div>
    324 
    325 <div id="methodListWrapper"><h2>Methods</h2>
    326   <ul id="methodList">
    327     <li><a href="#" onclick="return pwgSelectMethod(this.innerHTML)">getVersion</a></li>
    328   </ul>
    329 </div>
    330 
    331 <div id="methodWrapper">
    332   <h2 id="methodName"></h2>
    333   <div id="methodDetailWrapper">
    334 
    335     <table>
    336     <tr style="vertical-align:top">
    337 
    338     <td>
    339       <div id="methodDescription"></div>
    340       <table>
    341         <tr>
    342           <td>Request format:</td>
    343           <td>
    344             <select id="requestFormat">
    345               <option value="get" selected="selected">GET</option>
    346               <option value="post">POST</option>
    347             </select>
    348           </td>
    349         </tr>
    350 
    351         <tr>
    352           <td>Response format:</td>
    353           <td>
    354             <select id="responseFormat">
    355               <option value="rest" selected="selected">REST (xml)</option>
    356               <option value="json">JSON</option>
    357               <option value="php">PHP serial</option>
    358               <option value="xmlrpc">XML RPC</option>
    359             </select>
    360           </td>
    361         </tr>
    362       </table>
    363       <p>
    364         <a href="#" onclick="return pwgInvokeMethod(false)">Invoke</a>
    365         <a href="#" onclick="return pwgInvokeMethod(true)">Invoke (new Window)</a>
    366       </p>
    367     </td>
    368 
    369 
    370     <td>
    371       <table id="methodParams"  border="1" cellspacing="0" cellpadding="2px">
    372         <thead>
    373           <tr>
    374             <td style="width:150px">Parameter</td>
    375             <td>Extra</td>
    376             <td>Send</td>
    377             <td style="width:160px">Value</td>
    378           </tr>
    379         </thead>
    380         <tbody>
    381         </tbody>
    382       </table>
    383     </td>
    384 
    385     </tr>
    386     </table>
    387 
    388                 <div style="display:none;">
    389                         <!-- hiddenForm for POST -->
    390                         <form method="post" action="" target="invokeFrame" id="invokeForm">
    391                                 <input type="submit" value="submit"/>
    392                         </form>
    393                 </div>
    394 
    395     <iframe width="100%" height="400px" id="invokeFrame" name="invokeFrame" style="clear:both"></iframe>
    396   </div> <!-- methodDetailWrapper -->
    397 </div> <!-- methodWrapper -->
    398 
    399 </div>
    400510
    401511</body>
Note: See TracChangeset for help on using the changeset viewer.