packages feed

yesod-static-angular 0.1.7 → 0.1.8

raw patch · 7 files changed

+124/−112 lines, 7 filesdep ~language-javascript

Dependency ranges changed: language-javascript

Files

Yesod/EmbeddedStatic/AngularJavascript.hs view
@@ -59,12 +59,11 @@   , hamletTestTemplate ) where -import Control.Applicative import Control.Monad (forM, unless) import Data.Aeson (encode, decode, toJSON, Value) import Data.Default (def) import Data.List (isPrefixOf, sort)-import Data.Monoid ((<>), mconcat)+import Data.Monoid ((<>)) import Language.Haskell.TH import Network.Mime (MimeType) import System.Directory (getDirectoryContents, doesDirectoryExist, doesFileExist)
Yesod/EmbeddedStatic/AngularJsMangle.hs view
@@ -6,9 +6,10 @@ ) where  import Blaze.ByteString.Builder (toLazyByteString)-import Control.Applicative+import Data.List (intersperse) import Data.Maybe (catMaybes) import Language.JavaScript.Parser+import Language.JavaScript.Parser.AST import System.Directory (doesFileExist) import System.FilePath @@ -23,67 +24,76 @@ cleanupDIFile :: FilePath -> IO BL.ByteString cleanupDIFile f = toLazyByteString . renderJS . cleanupDI <$> parseFile f -cleanupDI :: JSNode -> JSNode-cleanupDI (NN (JSSourceElementsTop exprs)) = NN $ JSSourceElementsTop $ map diTopExpr exprs+cleanupDI :: JSAST -> JSAST+cleanupDI (JSAstProgram exprs _) = JSAstProgram (map diTopExpr exprs) JSNoAnnot cleanupDI x = x -diTopExpr :: JSNode -> JSNode-diTopExpr (NN (JSExpression-                [ call@(NN (JSMemberDot-                            [NT (JSIdentifier "module") _ _]-                            _ -- Literal .-                            (NT (JSIdentifier func) _ _))) -- function like controller/directive/etc.-                , NN (JSArguments open args close)-                ])) = NN $ JSExpression [call, NN $ JSArguments open (map (diFuncExpr directive) args) close]-    where directive = func == "directive"+diTopExpr :: JSStatement -> JSStatement+diTopExpr (JSMethodCall+            call@(JSMemberDot+                (JSIdentifier _ "module")+                _+                (JSIdentifier _ func))+            _+            argsCommaList+            _+            semi)+    = JSMethodCall call JSNoAnnot (diCommaList (func == "directive") argsCommaList) JSNoAnnot semi diTopExpr x = x +diCommaList :: Bool -> JSCommaList JSExpression -> JSCommaList JSExpression+diCommaList _ JSLNil = JSLNil+diCommaList isDir (JSLOne x) = JSLOne $ diFuncExpr isDir x+diCommaList isDir (JSLCons h _ x) = JSLCons (diCommaList isDir h) JSNoAnnot (diFuncExpr isDir x)+ -- | DI a single argument which is a function expression-diFuncExpr :: Bool -> JSNode -> JSNode-diFuncExpr isDir (NN (JSFunctionExpression a b c params d body)) =+diFuncExpr :: Bool -> JSExpression -> JSExpression+diFuncExpr isDir (JSFunctionExpression _ ident _ params _ body) =         case params of-            [] -> func-            _  -> NN $ JSArrayLiteral aopen elems aclose+            JSLNil -> func+            _  -> JSArrayLiteral JSNoAnnot elems JSNoAnnot     where-        aopen = NT (JSLiteral "[") tokenPosnEmpty [NoComment]-        aclose = NT (JSLiteral "]") tokenPosnEmpty [NoComment]-        comma = NN (JSElision (NT (JSLiteral ",") tokenPosnEmpty [NoComment]))-         body' = if isDir then diBody body else body-        func = NN $ JSFunctionExpression a b c params d body'+        func = JSFunctionExpression JSNoAnnot ident JSNoAnnot params JSNoAnnot body' -        elems = map diParam params ++ [comma, func]+        elems :: [JSArrayElement]+        elems = intersperse (JSArrayComma JSNoAnnot) $ map diParam (jsToList params) ++ [JSArrayElement func] diFuncExpr _ x = x --- | Convert a function parameter to a string literal and convert comma to elision-diParam :: JSNode -> JSNode-diParam (NT (JSIdentifier name) _ _) = NT (JSStringLiteral '"' name) tokenPosnEmpty [NoComment]-diParam (NT (JSLiteral ",") _ _) = NN $ JSElision $ NT (JSLiteral ",") tokenPosnEmpty [NoComment]-diParam x = x+-- | Convert a function parameter to a string literal+diParam :: JSIdent -> JSArrayElement+diParam (JSIdentName _ name) = JSArrayElement $ JSStringLiteral JSNoAnnot ("\"" ++ name ++ "\"")+diParam JSIdentNone = JSArrayElement (JSDecimal JSNoAnnot "0")  -- | Check a directive body to see if we need to DI cleanup a controller.-diBody :: JSNode -> JSNode-diBody (NN (JSBlock begin statements end)) = NN $ JSBlock begin (map diReturn statements) end-diBody x = x+diBody :: JSBlock -> JSBlock+diBody (JSBlock _ statements _) = JSBlock JSNoAnnot (map diReturn statements) JSNoAnnot  -- | Check if a statement is a return of an object literal-diReturn :: JSNode -> JSNode-diReturn (NN (JSReturn ret [NN (JSExpression [NN (JSObjectLiteral begin props end)])] colon))-    = NN $ JSReturn ret [NN (JSExpression [NN (JSObjectLiteral begin (map diProperty props) end)])] colon+diReturn :: JSStatement -> JSStatement+diReturn (JSReturn _ (Just (JSObjectLiteral _ props _)) semi)+    = JSReturn JSNoAnnot (Just (JSObjectLiteral JSNoAnnot (diPropertyList props) JSNoAnnot)) semi diReturn x = x -testPropName :: String -> JSNode -> Bool-testPropName n (NT (JSIdentifier n') _ _) = n == n'-testPropName n (NT (JSStringLiteral _ n') _ _) = n == n'+diPropertyList :: JSObjectPropertyList -> JSObjectPropertyList+diPropertyList (JSCTLComma x _) = JSCTLNone $ diPropertyList' x+diPropertyList (JSCTLNone x) = JSCTLNone $ diPropertyList' x++diPropertyList' :: JSCommaList JSObjectProperty -> JSCommaList JSObjectProperty+diPropertyList' (JSLCons h _ x) = JSLCons (diPropertyList' h) JSNoAnnot (diProperty x)+diPropertyList' (JSLOne x) = JSLOne $ diProperty x+diPropertyList' JSLNil = JSLNil++testPropName :: String -> JSPropertyName -> Bool+testPropName n (JSPropertyIdent _ n') = n == n'+testPropName n (JSPropertyString _ n') = "'" ++ n ++ "'" == n' || "\"" ++ n ++ "\"" == n' testPropName _ _ = False  -- | Check a property of an object for controller-diProperty :: JSNode -> JSNode-diProperty (NN (JSPropertyNameandValue prop _ args)) -        | testPropName "controller" prop = NN $ JSPropertyNameandValue ctrl colon args'+diProperty :: JSObjectProperty -> JSObjectProperty+diProperty (JSPropertyNameandValue prop _ args)+        | testPropName "controller" prop = JSPropertyNameandValue prop JSNoAnnot args'     where-        ctrl = NT (JSStringLiteral '"' "controller") tokenPosnEmpty [NoComment]-        colon = NT (JSLiteral ":") tokenPosnEmpty [NoComment]         args' = map (diFuncExpr False) args diProperty x = x @@ -116,34 +126,46 @@ firstJust (Nothing:xs) = firstJust xs  -- | Search for the directive ID -parseDirId :: JSNode -> Maybe String-parseDirId (NN (JSSourceElementsTop es)) = firstJust $ map parseDirectiveCall es+parseDirId :: JSAST -> Maybe String+parseDirId (JSAstProgram es _) = firstJust $ map parseDirectiveCall es parseDirId _ = Nothing +jsToList :: JSCommaList a -> [a]+jsToList JSLNil = []+jsToList (JSLOne x) = [x]+jsToList (JSLCons h _ x) = jsToList h ++ [x]+ -- | Parse module.directive(... function(..) {-parseDirectiveCall :: JSNode -> Maybe String-parseDirectiveCall (NN (JSExpression-                         [NN (JSMemberDot-                                [NT (JSIdentifier "module") _ _]-                                _ -- Literal .-                                (NT (JSIdentifier "directive") _ _)),-                          NN (JSArguments _ args _)])) = firstJust $ map parseDirArg args+parseDirectiveCall :: JSStatement -> Maybe String+parseDirectiveCall (JSMethodCall+                        (JSMemberDot+                            (JSIdentifier _ "module")+                            _+                            (JSIdentifier _ "directive"))+                        _ -- annotation+                        argsCommalist+                        _ --annotation+                        _) -- semi colon+    = firstJust $ map parseDirArg $ jsToList argsCommalist parseDirectiveCall _ = Nothing  -- | check the function argument to the directive call-parseDirArg :: JSNode -> Maybe String-parseDirArg (NN (JSFunctionExpression _ _ _ _ _ (NN (JSBlock _ statements _))))-    = firstJust $ map parseDirSt statements+parseDirArg :: JSExpression -> Maybe String+parseDirArg (JSFunctionExpression _ _ _ _ _ (JSBlock _ statements _)) = firstJust $ map parseDirSt statements parseDirArg _ = Nothing  -- | Check a statement inside the factory function for  return { .. };-parseDirSt :: JSNode -> Maybe String-parseDirSt (NN (JSReturn _ [NN (JSExpression [NN (JSObjectLiteral _ props _)])] _))-    = firstJust $ map parseDirTUrl props+parseDirSt :: JSStatement -> Maybe String+parseDirSt (JSReturn _ (Just (JSObjectLiteral _ props _)) _) = result+    where+        propsLst = case props of+                    (JSCTLComma x _) -> jsToList x+                    (JSCTLNone x) -> jsToList x+        result = firstJust $ map parseDirTUrl propsLst parseDirSt _ = Nothing  -- | Check a property in the object literal-parseDirTUrl :: JSNode -> Maybe String-parseDirTUrl (NN (JSPropertyNameandValue prop _ [NT (JSStringLiteral _ tUrl) _ _])) -    | testPropName "templateUrl" prop = Just tUrl+parseDirTUrl :: JSObjectProperty -> Maybe String+parseDirTUrl (JSPropertyNameandValue prop _ [JSStringLiteral _ tUrl])+    | testPropName "templateUrl" prop = Just (drop 1 $ take (length tUrl - 1) tUrl) -- the string literal has quotes around it parseDirTUrl _ = Nothing
test/RunGenerator.hs view
@@ -5,7 +5,7 @@ import Data.List (sortBy) import Data.Ord (comparing) import Language.Haskell.TH-import Test.HUnit+import Test.HUnit hiding (Location) import Yesod.EmbeddedStatic import Yesod.EmbeddedStatic.Types @@ -36,8 +36,9 @@  testEntry :: Entry -> (Location, B.ByteString, FilePath) -> ExpQ testEntry e (loc, mime, f) = do-    eCt <- runIO $ BL.readFile f     gCt <- runIO $ ebProductionContent e+    --runIO $ BL.writeFile f gCt+    eCt <- runIO $ BL.readFile f     case (loc == ebLocation e, mime == ebMimeType e, eCt == gCt, ebDevelExtraFiles e) of         (False,_,_,_) -> [| GeneratorTestResult (Just $ "Locations don't match for " ++ $(litE $ stringL loc))                                                 undefined undefined |]
test/angular/mod1-and-templ.js.expected view
@@ -1,19 +1,16 @@-(function(module) {module.controller("myctrl",["$scope", function($scope) {+(function(module) {module.controller("myctrl",["$scope",function($scope) {     console.log("A");     $scope.A = "A";-}]);-module.factory("thefactory",["$http","xyz", function($http, xyz) {+}]);module.factory("thefactory",["$http","xyz",function($http, xyz) {     console.log("B");-}]);-module.directive("my-directive", function() {-    return { template: "<h1>Hello World</h1>" };-});-module.directive("myPane", function() {-    return {+}]);module.directive("my-directive",function(){return{+             template: "<h1>Hello World</h1>"} ;})+  ;module.directive("myPane",function(){return{+                     require: '^myTabs',         restrict: 'E',-        transclude: true,"controller":["$scope","ttt",-                    function($scope, ttt) {+        transclude: true,+        controller:["$scope","ttt",function($scope, ttt) {             console.log("hah");         }],         scope: {@@ -22,14 +19,14 @@         link: function(scope, element, attrs, tabsCtrl) {             tabsCtrl.addPane(scope);         },-        templateUrl: 'paneid',-    };-});module.directive("myTabs", function() {-    return {+        templateUrl: 'paneid'}+     ;})+  ;module.directive("myTabs",function(){return{+                     restrict: "E",         transclude: true,-        scope: {},"controller":["$scope",-                      function($scope) {+        scope: {},+        "controller":["$scope",function($scope) {             var panes = $scope.panes = [];              $scope.select = function(pane) {@@ -46,10 +43,9 @@                 panes.push(pane);             };         }],-        "templateUrl": 'tabstemplateurl',-    };-});-module.run(['$templateCache', function($templateCache) {+        "templateUrl": 'tabstemplateurl'}+     ;})+  ;module.run(['$templateCache', function($templateCache) { $templateCache.put("paneid","<div class=\"tab-pane\" ng-show=\"selected\" ng-transclude></div>\n<br>\n"); $templateCache.put("tabstemplateurl","<div class=\"tabbable\"><ul class=\"nav nav-tabs\"><br>\n<li ng-repeat=\"pane in panes\" ng-class=\"{active:pane.selected}\"><a href=\"\" ng-click=\"select(pane)\">{{pane.title}}</a>\n</li>\n</ul>\n<div class=\"tab-content\" ng-transclude></div>\n</div>\n"); }]);
test/angular/mod1.js.expected view
@@ -1,19 +1,16 @@-(function(module) {module.controller("myctrl",["$scope", function($scope) {+(function(module) {module.controller("myctrl",["$scope",function($scope) {     console.log("A");     $scope.A = "A";-}]);-module.factory("thefactory",["$http","xyz", function($http, xyz) {+}]);module.factory("thefactory",["$http","xyz",function($http, xyz) {     console.log("B");-}]);-module.directive("my-directive", function() {-    return { template: "<h1>Hello World</h1>" };-});-module.directive("myPane", function() {-    return {+}]);module.directive("my-directive",function(){return{+             template: "<h1>Hello World</h1>"} ;})+  ;module.directive("myPane",function(){return{+                     require: '^myTabs',         restrict: 'E',-        transclude: true,"controller":["$scope","ttt",-                    function($scope, ttt) {+        transclude: true,+        controller:["$scope","ttt",function($scope, ttt) {             console.log("hah");         }],         scope: {@@ -22,14 +19,14 @@         link: function(scope, element, attrs, tabsCtrl) {             tabsCtrl.addPane(scope);         },-        templateUrl: 'paneid',-    };-});module.directive("myTabs", function() {-    return {+        templateUrl: 'paneid'}+     ;})+  ;module.directive("myTabs",function(){return{+                     restrict: "E",         transclude: true,-        scope: {},"controller":["$scope",-                      function($scope) {+        scope: {},+        "controller":["$scope",function($scope) {             var panes = $scope.panes = [];              $scope.select = function(pane) {@@ -46,8 +43,7 @@                 panes.push(pane);             };         }],-        "templateUrl": 'tabstemplateurl',-    };-});-})(angular.module("mod1",[]));+        "templateUrl": 'tabstemplateurl'}+     ;})+  ;})(angular.module("mod1",[])); Added by mini
test/angular/mod2.js.expected view
@@ -1,9 +1,7 @@-(function(module) {module.controller("thectrl", function() {+(function(module) {module.controller("thectrl",function()  {     console.log("ABC");-});-module.factory("a factory", function() {+});module.factory("a factory",function()  {     console.log("Factory!");     return {};-});-})(angular.module("mod2",["mod1"]));+});})(angular.module("mod2",["mod1"])); Added by mini
yesod-static-angular.cabal view
@@ -1,5 +1,5 @@ name:              yesod-static-angular-version:           0.1.7+version:           0.1.8 cabal-version:     >= 1.8 build-type:        Simple synopsis:          Yesod generators for embedding AngularJs code into yesod-static at compile time@@ -69,7 +69,7 @@                  , directory            >= 1.2                  , filepath             >= 1.3                  , hamlet               >= 1.1-                 , language-javascript  >= 0.5+                 , language-javascript  >= 0.6 && < 0.7                  , mime-types           >= 0.1                  , shakespeare          >= 1.2                  , template-haskell