web staff : xul integration experiment collab/berick/web-staff-proto-xul-integration
authorBill Erickson <berick@esilibrary.com>
Mon, 17 Mar 2014 19:58:57 +0000 (15:58 -0400)
committerBill Erickson <berick@esilibrary.com>
Mon, 17 Mar 2014 19:58:57 +0000 (15:58 -0400)
Trying to see if it's possible to run these UIs from within XUL,
potentially easing integration and testing.

Notes:

 * cookies / localStorage need XUL pass-thru's
 * to use websockets, a global (xul-level) websocket connection would be
   required (to avoid per-tab connections).
 * we'd probably want to trim out the nav bar along the top
 * debugging is a pain in the butt.  For some reason, not all errors
   bubble up to the console.  and console.log() no workee.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/t_base.tt2
Open-ILS/src/templates/staff/t_base_js.tt2
Open-ILS/web/js/ui/default/staff/cat/bucket/record/app.js
Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
Open-ILS/web/js/ui/default/staff/circ/patron/app.js
Open-ILS/web/js/ui/default/staff/services/auth.js
Open-ILS/web/js/ui/default/staff/services/xul.js [new file with mode: 0644]

index 6009417..ae96b4e 100644 (file)
@@ -8,7 +8,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <!-- TODO: remote hosted CSS should be hosted locally instead -->
-    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css" />
+    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css" />
     <link rel="stylesheet" href="[% ctx.base_path %]/staff/css/style.css" />
   </head>
   <body>
index 4686bdb..51ca7fd 100644 (file)
@@ -7,22 +7,22 @@
 %]
 
 <!-- hosted angular libs -->
-<script src="//ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular.min.js"></script>
-<script src="//ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular-route.min.js"></script>
-<script src="//ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular-cookies.min.js"></script>
-<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/[% ANGULAR_BOOTSTRAP_VERSION %]/ui-bootstrap-tpls.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular-route.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular-cookies.min.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/[% ANGULAR_BOOTSTRAP_VERSION %]/ui-bootstrap-tpls.min.js"></script>
 
 <!-- IDL / opensrf (network) -->
 <script src="/IDL2js"></script>
 <script src="[% ctx.media_prefix %]/js/dojo/opensrf/JSON_v1.js"></script>
 <script src="[% ctx.media_prefix %]/js/dojo/opensrf/opensrf.js"></script>
-<!--
+
+<!-- needed for XUL, pending global websockets connection -->
 <script src="[% ctx.media_prefix %]/js/dojo/opensrf/opensrf_xhr.js"></script>
--->
 <script>
   // pending api_level thunking in C
   // OpenSRF.api_level = 2;
-  OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS_SHARED
+  // OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS_SHARED;
 </script>
 
 <!-- angular-driven shared services -->
@@ -36,6 +36,7 @@
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/org.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/startup.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/xul.js"></script>
 
 <!-- navbar driver -->
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/navbar.js"></script>
index eedd805..de8c434 100644 (file)
@@ -15,8 +15,9 @@
 angular.module('egCatRecordBuckets', 
     ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egListMod'])
 
-.config(function($routeProvider, $locationProvider) {
+.config(function($routeProvider, $locationProvider, $compileProvider) {
     $locationProvider.html5Mode(true);
+    $compileProvider.aHrefSanitizationWhitelist(/^\s*(chrome|oils):/); 
 
     var resolver = {delay : function(egStartup) {return egStartup.go()}};
 
index 6d9c926..d9670b2 100644 (file)
@@ -1,8 +1,11 @@
 angular.module('egCheckinApp', ['ngRoute', 'ui.bootstrap', 
     'egCoreMod', 'egUiMod', 'egListMod', 'egUserMod'])
 
-.config(function($routeProvider, $locationProvider) {
+.config(function($routeProvider, $locationProvider, $compileProvider) {
     $locationProvider.html5Mode(true);
+
+    $compileProvider.aHrefSanitizationWhitelist(/^\s*(chrome|oils):/); 
+    
     // no routes needed 
 })
 
index 0d8c02b..b09f34a 100644 (file)
 angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap', 
     'egCoreMod', 'egUiMod', 'egListMod', 'egUserMod'])
 
-.config(function($routeProvider, $locationProvider) {
+.config(function($routeProvider, $locationProvider, $compileProvider) {
     $locationProvider.html5Mode(true);
 
+    $compileProvider.aHrefSanitizationWhitelist(/^\s*(chrome|oils):/); 
+
     // data loaded at startup which only requires an authtoken goes
     // here. this allows the requests to be run in parallel instead of
     // waiting until startup has completed.
@@ -245,9 +247,14 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egEnv,
     $scope.profiles = egEnv.pgt.list.map(
         function(grp) {return {name : grp.name(), id : grp.id() }})
 
+
     $scope.org_units = egEnv.aou.list.map(
         function(org) {return {shortname : org.shortname(), id : org.id() }})
 
+
+    $scope.tips = { dismissed : function() {return true} };
+    /* localStorage would need xul tie-in
+
     // TODO: experiment
     // if this is useful, it should be moved into a service.
     $scope.tips = {
@@ -259,18 +266,23 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egEnv,
         }
         // TODO: function to reset all tips
     };
+    */
+
 
     // TODO:
     // another experiment -- user prefs in localStorage -- this should
     // be a service, which can also check (certain) user/org settings
     $scope.applyShowExtras = function($event, bool) {
         $scope.showExtras = bool;
-        $window.localStorage.setItem('eg.prefs.circ.patron.search.showExtras', bool);
+        //$window.localStorage.setItem('eg.prefs.circ.patron.search.showExtras', bool);
         $event.preventDefault();
     }
     // localStorage stores strings; parse the values as JSON bools
+    /*
     $scope.showExtras = JSON.parse($window.localStorage.getItem(
         'eg.prefs.circ.patron.search.showExtras')) || false;
+    */
+
 
     // map form arguments into search params
     function compileSearch(args) {
index 3c4ad88..44053fd 100644 (file)
@@ -12,8 +12,8 @@ angular.module('egCoreMod')
 .constant('EG_AUTH_COOKIE', 'ses')
 
 .factory('egAuth', 
-       ['$q','$cookies','egNet','EG_AUTH_COOKIE',
-function($q,  $cookies,  egNet,  EG_AUTH_COOKIE) {
+       ['$q','$cookies', '$timeout','egNet','EG_AUTH_COOKIE','egXUL',
+function($q,  $cookies,  $timeout,   egNet,  EG_AUTH_COOKIE , egXUL) {
 
     var service = {
         // expose user and token via function, since we will eventually
@@ -23,7 +23,7 @@ function($q,  $cookies,  egNet,  EG_AUTH_COOKIE) {
             return this._user;
         },
         token : function() {
-            return $cookies[EG_AUTH_COOKIE];
+            return this._token || $cookies[EG_AUTH_COOKIE];
         }
     };
 
@@ -33,6 +33,16 @@ function($q,  $cookies,  egNet,  EG_AUTH_COOKIE) {
         var deferred = $q.defer();
         var token = service.token();
 
+        if (egXUL.isXUL()) {
+            var authstuff = egXUL.getAuthInfo();
+            service._user = authstuff.user;
+            service._token = authstuff.token;
+            // race condition from multiple callers of egStartup.go()
+            // which relies on the testAuthToken to resolve asynchronously
+            $timeout(function() { deferred.resolve()}, 1);
+            return deferred.promise;  
+        }
+
         if (token) {
             egNet.request(
                 'open-ils.auth',
diff --git a/Open-ILS/web/js/ui/default/staff/services/xul.js b/Open-ILS/web/js/ui/default/staff/services/xul.js
new file mode 100644 (file)
index 0000000..f4cda88
--- /dev/null
@@ -0,0 +1,42 @@
+angular.module('egCoreMod')
+
+.factory('egXUL', [function() {
+
+    var service = {};
+
+    service.isXUL = function() {
+        if(location.protocol == 'chrome:' || location.protocol == 'oils:') 
+            return true;
+        return Boolean(window.IAMXUL);
+    }
+
+    service.getStash = function() {                                            
+        try {                                                                  
+            var CacheClass = Components.classes[
+                "@open-ils.org/openils_data_cache;1"].getService();
+            return CacheClass.wrappedJSObject.data;                            
+        } catch(e) {                                                           
+            console.log("Error loading XUL stash: " + e);                      
+            return {error : e};                                            
+        }                                                                      
+    } 
+
+    service.getAuthInfo = function() {
+        var stash = service.getStash();
+        return {
+            user : stash.list.au[0],
+            token : stash.session.key
+        };
+    }
+
+    service.initXUL = function($compileProvider) {
+        // treat these URLs schemes as safe
+        if (service.isXUL()) 
+            $compileProvider.aHrefSanitizationWhitelist(/^\s*(chrome|oils):/); 
+    }
+
+    return service;
+}]);
+
+
+