Changeset 18079


Ignore:
Timestamp:
09/20/12 18:04:23 (7 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.