source: main/trunk/greenstone3/web/interfaces/default/transform/pages/webswing-phind.xsl@ 38983

Last change on this file since 38983 was 38983, checked in by anupama, 4 weeks ago

I think these are all the changes needed for tthe new GS3 ext/DEACTIVATE.sh (and ext/ACTIVATE.sh) to (de)activate the webswing extension.

File size: 18.5 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:java="http://xml.apache.org/xslt/java"
5 xmlns:util="xalan://org.greenstone.gsdl3.util.XSLTUtil"
6 xmlns:gslib="http://www.greenstone.org/skinning"
7 xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat"
8 extension-element-prefixes="java util"
9 exclude-result-prefixes="java util">
10
11 <!-- This page, structurally speaking, is a hybrid of home.xsl and about.xsl -->
12 <!-- Produces a general embedded Phind browser, given the library and collection -->
13
14 <!-- use the 'main' layout -->
15 <xsl:import href="layouts/main.xsl"/>
16
17 <!-- what is this used for??? Can it be deleted? -->
18 <xsl:variable name="groupPath"><xsl:value-of select="/page/pageRequest/paramList/param[@name='group']/@value"/></xsl:variable>
19
20 <!-- set page title -->
21
22 <xsl:template name="pageTitle">WebSwing Phind<!--<gslib:collectionName/><xsl:value-of select="/page/pageResponse/service/applet"/>--></xsl:template>
23
24 <!-- set page breadcrumbs -->
25 <xsl:template name="breadcrumbs">
26 <xsl:choose>
27 <xsl:when test="/page/pageRequest/paramList/param[@name='c']/@value != ''">
28 <gslib:siteLink/>
29 <gslib:rightArrow/>
30 <xsl:if test="$groupPath != ''">
31 <gslib:groupLinks/>
32 <gslib:rightArrow/>
33 </xsl:if>
34 <a href="{$library_name}/collection/{$collName}/page/about">
35 <gslib:collectionName/>
36 </a>
37 </xsl:when>
38 <xsl:otherwise>
39 <xsl:choose>
40 <xsl:when test="$groupPath != ''">
41 <a>
42 <xsl:attribute name="href"><gslib:groupHref path="{$groupPath}"/></xsl:attribute>
43 <xsl:attribute name="title"><gslib:groupName path="{$groupPath}"/></xsl:attribute>
44 <gslib:groupName path="{$groupPath}"/>
45 </a>
46 </xsl:when>
47 <xsl:otherwise>
48 <gslib:siteLink/>
49 </xsl:otherwise>
50 </xsl:choose>
51
52 </xsl:otherwise>
53 </xsl:choose>
54 </xsl:template>
55
56
57 <!-- the page content -->
58 <xsl:template match="/page">
59
60 <xsl:choose>
61 <xsl:when test="$this-element/displayItemList/displayItem[@name='icon']">
62 <img border="0">
63 <xsl:attribute name="src"><xsl:value-of select="$this-element/metadataList/metadata[@name='httpPath']"/>/images/<xsl:value-of select="$this-element/displayItemList/displayItem[@name='icon']"/></xsl:attribute>
64 <xsl:attribute name="alt">
65 <xsl:value-of select="$this-element/displayItemList/displayItem[@name='name']"/>
66 </xsl:attribute>
67 <xsl:attribute name="title">
68 <xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 'webswing_phindpage')"/>
69 </xsl:attribute>
70 </img>
71 </xsl:when>
72 </xsl:choose>
73
74 <!-- Inactive applet element that is used as a shim by our webswing JavaScript
75 code to read alll param values from and configure the webswing JPhind with.
76 The applet needs to appear on the page before the JavaScript code that
77 tries to locate it, for its parameters to be used to configure the webswing
78 instance. If there applet appears later or there is no applet, the
79 JavaScript will fallback to obtaining the webswing config settings from
80 XSLT/pageResponse.
81 -->
82 <xsl:call-template name="phind-applet-shim"/>
83 <!-- the webswing instance and JavaScript code -->
84 <xsl:call-template name="webswing-embed-phind"/>
85 </xsl:template>
86
87 <!-- Although applets are defunct, we use the phind and collage applets as shims:
88 JavaScript reads parameters set on the phind/collage applet and instantiates
89 the webswing application with those settings.
90 The JavaScript code has been written to work even with the applet element on
91 the page, but the applet element may be easier to customise for users than
92 the JavaScript code or the webswing arguments or webswing config file, so it
93 may be preferrable.
94 -->
95 <xsl:template name="phind-applet-shim">
96 <applet
97 style="display: none"
98 id="phind-applet-element"
99 archive="phind.jar, xercesImpl.jar, xml-apis.jar, webswing-api.jar"
100 code="org.greenstone.applet.phind.JPhind.class"
101 height="500"
102 width="500">
103 <xsl:attribute name="codebase">/<xsl:value-of select="$servlet_context"/>/applet</xsl:attribute>
104
105 <param name="library" value="library" />
106 <param name="phindcgi" value="?a=a&amp;rt=r&amp;s=PhindApplet&amp;o=xml&amp;ro=1" />
107 <param name="collection" value="tudor" />
108 <param name="classifier" value="1" />
109 <param name="orientation" value="vertical" />
110 <param name="depth" value="2" />
111 <param name="resultorder" value="L,l,E,e,D,d" />
112 <param name="backdrop" value="interfaces/default/images/phindbg1.jpg" />
113 <param name="fontsize" value="10" />
114 <param name="blocksize" value="10" />
115 The Phind java applet
116 </applet>
117 </xsl:template>
118
119 <xsl:template name="webswing-embed-phind">
120 <link rel="stylesheet" href="/webswing-server/css/style.css" />
121
122 <div id="webswing-phind" class="webswing-element" data-webswing-instance="webswingInstance0" style="width: 500px; height: 500px;">
123 <div id="loading" class="ws-modal-container">
124 <div class="ws-login">
125 <div class="ws-login-content">
126 <div class="ws-spinner">
127 <div class="ws-spinner-dot-1"><xsl:comment>filler</xsl:comment></div>
128 <div class="ws-spinner-dot-2"><xsl:comment>filler</xsl:comment></div>
129 </div>
130 </div>
131 </div>
132 </div>
133 </div>
134
135 <gsf:script>
136 // https://www.webswing.org/docs/23.2/configure/applet.html
137 // https://www.webswing.org/docs/23.2/configure/swing.html
138 // https://www.webswing.org/docs/23.2/integrate/javascript-api?_h=customArgs%2Cargs#usage-with-customization-and-options
139 // https://www.webswing.org/docs/23.2/integrate/embed.html
140 // https://www.webswing.org/docs/20.1/integrate/urlparams.html
141 // https://www.webswing.org/docs/23.2/integrate/urlparams.html
142 // https://www.webswing.org/docs/20.1/integrate/customize.html
143 // https://www.webswing.org/docs/2.7/integrate/embed.html
144
145 var webswingInstance0 = {
146 options: {
147 autoStart: true,
148 //appletParams: getParam('appletParams'),
149 //appletParams: {"collection":"tudor", "library":"library"},
150 connectionUrl:'/webswing-server/phind',
151
152 customization: function(injector) {
153 injector.services.base.handleActionEvent = function(actionName, data, binaryData) {
154 //console.log("WebSwing actionEvent callback handler: called with actionName = " + actionName);
155
156 if (actionName === "openURL") {
157 var url = data;
158 // check if a target tab/window name has been specified
159 // TODO: Any better way of passing > 1 string between Java and JavaScript?
160 var index = url.indexOf(" - ");
161 if (index !== -1) {
162 var target = url.substring(index+3); // skip past " - " to get target name
163 url = url.substring(0, index);
164 window.open(url, target);
165 } else {
166 window.open(url, '_blank');
167 }
168 } else if (actionName == "javaToWebswingJSConsoleLog") {
169 console.log("Got message from java:\n" + data);
170 }
171
172 }
173 }
174
175
176 }
177 };
178
179
180 // The applet jar files can just remain in web/applet where they are compiled up
181 if(!webswingInstance0.options.args) {
182 webswingInstance0.options.args="";
183 }
184
185 var verbosity = 3;
186 var appletEl = document.querySelector("applet");
187
188 // Set to false if running the webswing instance as a webswing application. This has
189 // nothing to do with if the applet element exists on the page: it can be on the page
190 // and you can still decide to run JPhind as a webswing application. If switching
191 // between running as application and applet, remember to adjust webswing.config.in
192 // If we do push the deprecated applet element onto the page, we can use it as a shim:
193 // use JavaScript to read its params and pass them to webswing as configuration args.
194 //
195 var isWebswingRunAsApplet = true;
196
197 // Fill up webswingParams JSON record with non-dynamic values and other vals
198 // that may perhaps not be set on the applet element, to use as fallback
199 var webswingParams = {
200 //"webswing":1, // set in webswing.config.in to discourage editing
201 "verbosity": verbosity,
202 "phindcgi": "?a=a&amp;rt=r&amp;s=PhindApplet&amp;o=xml&amp;ro=1",
203 "classifier": 1, // true or false
204 "backdrop": "interfaces/default/images/phindbg1.jpg",
205 "orientation": "vertical",
206 "depth": 2,
207 "resultorder": "L,l,E,e,D,d",
208 "fontsize": 10,
209 "blocksize": 10
210 }
211
212 // When passed into webswing if run as an application, the mostly static args will look like
213 //--verbosity 3 --phindcgi \"?a=a&amp;rt=r&amp;s=PhindApplet&amp;o=xml&amp;ro=1\" --classifier 1 --backdrop interfaces/default/images/phindbg1.jpg --orientation vertical --depth 2 --resultorder \"L,l,E,e,D,d\" --fontsize 10 --blocksize 10
214 // More will get prefixed and suffixed
215
216 if(!appletEl &amp;&amp; verbosity >= 4) {
217 console.log("No applet element on page. Reading in from pageResponse/XSLT.");
218 }
219
220 // The entirely javascript way of setting our webswing app parameters
221 // (does not read the parameters set on the applet element)
222 // dynamic phind arguments
223 webswingParams["collection"] = gs.cgiParams.c;
224 webswingParams["library"] = gs.xsltParams.library_name;
225
226 // If run as webswing application, we need an extra cmdline arg at the *start*: the baseURL
227 // It is not of key-value form, just the baseURL by itself.
228 if(!isWebswingRunAsApplet) {
229 //https://stackoverflow.com/questions/25203124/how-to-get-base-url-with-jquery-or-javascript
230 var baseURL = window.location.origin+window.location.pathname;
231 // webswingInstance0.options.args += "\"" + baseURL+ "?a=a&amp;rt=d&amp;s=PhindApplet&amp;c="+gs.cgiParams.c + "\"";
232 webswingInstance0.options.args += "\"" + baseURL + "\" ";
233 }
234
235 if(appletEl) { // get all available webswing config settings from applet element
236 if(verbosity >= 4) {
237 console.log("Found an applet HTML element on page, using its params where available.");
238 }
239 // If using the inactive/deprecated applet element as shim, instead of javascript
240 // working out the webswing config params from the pageRequest or XSLT variables:
241 // Get the webswing configuration arguments from the lingering applet html element,
242 // as a GS3 library designer may know to how to customize applet parameters
243 // better than they know javascript or how to construct webswing parameters.
244
245 // Now get the param subelements of the applet element
246 for (var webswingParam of Object.keys(webswingParams)) {
247 var querySelectorStr = "param[name='"+webswingParam+"']";
248 var appletParam = appletEl.querySelector(querySelectorStr);
249 if(appletParam) { // if this parameter was set on the applet
250 webswingParams[webswingParam] = appletParam.value;
251 } else {
252 if(verbosity>=3) {
253 console.log("Applet element does not supply param: " + webswingParam + ". Using fallback: " + webswingParams[webswingParam]);
254 }
255 }
256 }
257
258 }
259 verbosity = webswingParams["verbosity"]; // so JavaScript logging obeys any user-supplied verbosity
260
261 // Special case: width and height are attributes of the applet tag not subelements
262 // and may need parsing.
263 // Control the width and height of the Java application launched with webswing by
264 // passing the width and height params set on the webswing element, unless an applet
265 // element is available. In that case try to get the dimensions from the applet tag.
266 // https://stackoverflow.com/questions/21851633/get-height-from-style-attribute
267 var w = appletEl ? appletEl.getAttribute("width") : document.getElementById("webswing-phind").style.width;
268 var h = appletEl ? appletEl.getAttribute("height") : document.getElementById("webswing-phind").style.height;
269 webswingParams["width"] = stripUnitOffAttribute("px", w);
270 webswingParams["height"] = stripUnitOffAttribute("px", h);
271
272 // Webswing only uses the width and height set on the webswing-collage element
273 // Override this with any dimensions set on any applet element, as that is user-controlled
274 // from GLI. style.setProperty failed without the 'important' parameter to force the setting.
275 // https://stackoverflow.com/questions/5191478/changing-element-style-attribute-dynamically-using-javascript
276 document.getElementById("webswing-phind").style.setProperty("width", webswingParams["width"] + "px", "important");
277 document.getElementById("webswing-phind").style.setProperty("height", webswingParams["height"] + "px", "important");
278
279 if(verbosity >= 4) {
280 console.log("@@@ Final verbosity: " + webswingParams["verbosity"]
281 + ", width: " + webswingParams["width"] + ", height: " + webswingParams["height"]);
282 }
283
284 // Having collected all the webswingParams, we can finally build up the single webswing customArgs string
285 var _args = "";
286 for (var webswingParam of Object.keys(webswingParams)) {
287 _args += "--" + webswingParam + " \"" + webswingParams[webswingParam] + "\" "; // space at end to precede next arg
288 }
289 webswingInstance0.options.args += _args.substring(0, _args.length-1); // remove extra space at end
290
291 // When run as webswing applet (instead of as webswing application), the webswing var
292 // customargs becomes assigned as the value of key "xtraParams" in webswing.config.in
293 // and is a string of key-value pairs. And our Java code is able to successfully
294 // receive these key-valye pairs in the form k1::v1;;k2::v2;; (URL form of key-value
295 // pairs is not easy to pass in from JavaScript through webswing into Java).
296
297 if(isWebswingRunAsApplet) {
298 var xtraParams = webswingInstance0.options.args;
299 var hyphens_index = xtraParams.indexOf("--");
300 var spaceAfterKey = -1;
301 while(hyphens_index >= 0) {
302 // Locate start of value in each key-value pair
303 spaceAfterKey = xtraParams.indexOf(" ", hyphens_index);
304 if(spaceAfterKey >= 0) {
305 // insert (splice in) the key-value internal separator,creating "key::value"
306 xtraParams = [xtraParams.slice(0, spaceAfterKey), "::", xtraParams.slice(spaceAfterKey+1)].join('');
307 }
308 hyphens_index = xtraParams.indexOf("--", hyphens_index+2);
309 }
310 // now add separator *between* each key-value pairs with ;;
311 xtraParams = xtraParams.replaceAll(" --", ";;");
312 webswingInstance0.options.args = xtraParams.substring(2);
313 }
314
315 if(verbosity >= 4) {
316 console.log("custom args: " + webswingInstance0.options.args);
317 }
318
319
320 function getParam(name) {
321 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
322 var results = new RegExp("[\\?&amp;]" + name + "=([^&amp;#]*)").exec(location.href);
323 return results == null ? null : decodeURIComponent(results[1]);
324 }
325
326 function stripUnitOffAttribute(unit, attr) {
327 // common code, regardless of whether we use the applet element as a shim or not
328 var suffixIndex = 0;
329 if(attr) {
330 suffixIndex = attr.indexOf(unit);
331 if(suffixIndex>0) {
332 attr = attr.substring(0, suffixIndex);
333 }
334 }
335 return attr;
336 }
337 </gsf:script>
338
339
340 <script data-webswing-global-var="webswing">
341 <xsl:text disable-output-escaping="yes">
342 var unloaded = false;
343 (function (window, document) {
344 var loader = function () {
345 var baseUrl = '/webswing-server/phind';
346 baseUrl = baseUrl.indexOf("/", baseUrl.length - 1) !== -1 ? baseUrl : (baseUrl + "/");
347 var xmlhttp = new XMLHttpRequest();
348 xmlhttp.onreadystatechange = function () {
349 if (xmlhttp.readyState == XMLHttpRequest.DONE) {
350 var version = xmlhttp.status == 200 ? xmlhttp.responseText : "undefined";
351 var script = document.createElement("script"),
352 tag = document.getElementsByTagName("script")[0];
353 script.src = baseUrl + "javascript/webswing-embed.js?version=" + version;
354 tag.parentNode.insertBefore(script, tag);
355
356 if (xmlhttp.status != 200) { // possibly no webswing-server
357 document.getElementById("webswing-phind").style.setProperty("display", "none", "important");
358 appletEl.style.setProperty("display", "block", "important");
359 appletEl.textContent += " This applet cannot be displayed as the webswing extension it requires has possibly been deactivated.";
360 }
361 }
362 };
363 xmlhttp.open("GET", baseUrl + "rest/version", true);
364 xmlhttp.send();
365 };
366
367 var navigatingAway = function () {
368 if(verbosity >= 4) {
369 console.log("*** navigatingAway called");
370 }
371
372 if(!unloaded) {
373
374 if(typeof webswingInstance0.kill === 'function') { // it should exist
375 if(verbosity >= 3) {
376 console.log("@@@ Telling webswing to stop the collage application/applet");
377 }
378 webswingInstance0.kill();
379 unloaded = true; // do not unload again, if multiple listeners call navigatingAway() callback function
380 if(verbosity >= 4) {
381 console.log("@@@@ unloaded");
382 }
383 } // else cannot call method that does not exist
384 } else {
385 if(verbosity >= 4) {
386 console.log("@@@@ already unloaded.");
387 }
388 }
389
390 };
391
392 window.addEventListener ? window.addEventListener("load", loader, false) : window.attachEvent("onload", loader);
393
394
395 // When the user navigates away from this page or reloads it, we want to shutdown
396 // the webswing Java application/applet. For more info, see layouts/webswing-collage.xsl
397
398 window.addEventListener ? window.addEventListener("beforeunload", navigatingAway, false) : window.attachEvent("onbeforeunload", navigatingAway);
399 window.addEventListener ? window.addEventListener("pagehide", navigatingAway, false) : window.attachEvent("onpagehide", navigatingAway);
400 // Not visibilitychange: it's triggered even if the user minimises the browser window
401 // don't want to kill Phind if the user only changed focus to another application.
402 //window.addEventListener ? window.addEventListener("visibilitychange", navigatingAway, false) : window.attachEvent("onvisibilitychange", navigatingAway);
403
404 })(window, document);
405 </xsl:text>
406 </script>
407
408
409
410 </xsl:template>
411
412</xsl:stylesheet>
413
Note: See TracBrowser for help on using the repository browser.