liftweb-uirouter

angularjs ui-router module for scala liftweb framework

git clone https://9o.is/git/liftweb-uirouter.git

UiJs.scala

(5559B)


      1 package net.liftmodules.uirouter
      2 package snippet
      3 
      4 import net.liftweb._
      5 import http._
      6 import js._
      7 import common._
      8 import util._
      9 import Helpers._
     10 import net.liftmodules.uirouter.UiRouter._
     11 
     12 /**
     13  * Just a bunch of javascript to append in html.
     14  */
     15 trait UiJs extends SnippetHelper {
     16   
     17   /**
     18    * Snippet to configure AngularJs module with all routes.
     19    * 
     20    * Required attributes:
     21    * - ngApp: Name of AngularJs module. 
     22    * 
     23    * Example:
     24    * if script is 'var myapp = angular.module(....'
     25    * then add the following to the end of your html file,
     26    * 
     27    * <script data-lift="UiRouter.js?ngApp=myapp"></script>
     28    */
     29   def js: CssSel = 
     30     for{
     31       app <- S.attr("ngApp") ?~ "ngApp name is missing"
     32     } yield "* *" #> {      
     33       s"""// <![CDATA[
     34       ${init + app + config + 
     35         onViewContentLoaded(ifStateNotVisited(updateLiftWatch, evalRenderedJS, restartComet)) + 
     36         onStateChangeSuccess(pageTitle.vend)};
     37       $cometScript
     38       //]]>"""
     39     }
     40 
     41   /**
     42    * Provides default route in js
     43    */
     44   def routerOtherwise =
     45     defaultRoute.vend map {
     46       "$urlRouterProvider.otherwise('" + S.contextPath + _.loc.calcDefaultHref + "');"
     47     } openOr ""
     48    
     49   /**
     50    * Provides main configurations in js
     51    */
     52   def config = 
     53       """
     54       .config(function($stateProvider, $urlRouterProvider,$locationProvider) {
     55         $locationProvider.html5Mode("""+html5mode.vend.toString+""");
     56         """+routerOtherwise+"""
     57         $stateProvider"""+{
     58           routes.vend.map { menu =>
     59             val templateUrl = S.contextPath+menu.loc.calcDefaultHref
     60             val state: String = menu.loc.name.replaceAll(" ","_")
     61             
     62             ".state('"+state+"', {"+
     63               "url:'"+templateUrl+"',"+
     64               "templateUrl:'"+templateUrl+".html?ajax'"+
     65             "})"
     66           }.mkString
     67         }+"""
     68       ;})
     69       """
     70        
     71   /**
     72    * Initializing 
     73    */
     74   def init = 
     75     "var statesVisited = [];"+
     76     " var lift_toWatch = {};"
     77     
     78   /**
     79    * Updates all new comet entries 
     80    */
     81   def updateLiftWatch = 
     82     """var el = angular.element(document.querySelectorAll(".ui-liftwatch"));"""+
     83     """for (var i=0;i<el.length;++i) { window.lift_toWatch[el[i].getAttribute("id")] = el[i].getAttribute("when") };"""  
     84   
     85   /**
     86    * Evaluates the javascript that was placed in the ajax-uploaded html page.
     87    */
     88   def evalRenderedJS = 
     89     """var promises = angular.element(document.querySelectorAll(".ui-liftjs"));"""+
     90     """for (var i=0;i<promises.length;++i) { eval(promises[i].innerHTML) };"""
     91   
     92   /**
     93    * Restarts comet
     94    */
     95   def restartComet = """window.liftComet.lift_cometRestart();"""
     96     
     97   /**
     98    * The current page's name.
     99    */
    100   def pageName = "toState.name.replace(/_/g, ' ')"
    101 
    102   /**
    103    *  Run commands when UI-Router's $viewContentLoaded event is fired.
    104    */
    105   def onViewContentLoaded(cmds: String*): String =
    106     """.run(['$rootScope', '$state', function($rootScope, $state) {$rootScope.$on('$viewContentLoaded', function() {""" +
    107       cmds.mkString + """}); }])"""
    108 
    109   /**
    110    *  Run commands when UI-Router's $stateChangeSuccess event is fired.
    111    */
    112   def onStateChangeSuccess(cmds: String*): String =
    113     """.run(['$rootScope', function($rootScope) {$rootScope.$on('$stateChangeSuccess', function(e, toState) {""" +
    114       cmds.mkString + """}); }])"""
    115 
    116   /**
    117    * Run commands if state wasn't visited during the current page load.
    118    */
    119   def ifStateNotVisited(cmds: String*): String = """
    120         var visited = false;
    121         angular.forEach(statesVisited, function(state){
    122           if(state === $state.current.name) {visited = true;}
    123         });
    124         if(!visited){
    125           statesVisited.push($state.current.name);
    126           """ + cmds.mkString + """
    127         }
    128         """
    129 
    130   /**
    131    * Hides (or scopes) js code.
    132    */
    133   protected def func(body: String): String = "(function() {"+body+"});"
    134   
    135   /**
    136    * Renders the default JS comet script
    137    */
    138   private def cometScript: String = """
    139   (function() {
    140     var currentCometRequest = null;
    141     window.liftComet = {
    142       lift_handlerSuccessFunc: function() {
    143         setTimeout("liftComet.lift_cometEntry();",100);
    144       },
    145 
    146       lift_unlistWatch : function(watchId) {
    147         var ret = [];
    148         for (item in lift_toWatch) {
    149           if (item !== watchId) {
    150             ret.push(item);
    151           }
    152         }
    153         lift_toWatch = ret;
    154       },
    155 
    156       lift_handlerFailureFunc: function() {
    157         setTimeout("liftComet.lift_cometEntry();",""" + LiftRules.cometFailureRetryTimeout + """);
    158       },
    159 
    160 
    161       lift_cometError: function(e) {
    162         if (console && typeof console.error == 'function')
    163           console.error(e.stack || e);
    164         throw e;
    165       },
    166 
    167       lift_sessionLost: function() { window.location = '/' },
    168         
    169       lift_cometRestart: function() {
    170         if (currentCometRequest) {
    171           currentCometRequest.abort();
    172         }
    173         
    174         liftComet.lift_handlerSuccessFunc();
    175       },
    176 
    177       lift_cometEntry: function() {
    178         var isEmpty = function(){for (var i in lift_toWatch) {return false} return true}();
    179         if (!isEmpty) {
    180           liftAjax.lift_uriSuffix = undefined;
    181         currentCometRequest = """ +
    182           LiftRules.jsArtifacts.comet(AjaxInfo(JE.JsRaw("lift_toWatch"),
    183             "GET",
    184             LiftRules.cometGetTimeout,
    185             false,
    186             "script",
    187             Full("liftComet.lift_handlerSuccessFunc"),
    188             Full("liftComet.lift_handlerFailureFunc"))) +
    189           """
    190               }
    191             }
    192        
    193           }})();
    194           """
    195             
    196   
    197 }