Commit d1923af5 authored by Xavier Guimard's avatar Xavier Guimard

Switch javascript to coffeescript

parent 1500a1b8
......@@ -190,6 +190,10 @@ JSSRCFILES:=$(shell find $(SRCMANAGERDIR)/site/static/js $(SRCPORTALDIR)/example
$(SRCMANAGERDIR)/site/static/bwr/file-saver.js/FileSaver.js
CSSSRCFILES:=$(shell find $(SRCMANAGERDIR)/site/static/css $(SRCPORTALDIR)/example -type f -name '*.css' ! -name '*.min.css')
# Coffee files
COFFEESRCFILES:=$(shell find $(SRCMANAGERDIR)/site/coffee/ -type f)
COFFEEDSTFILES:=$(subst coffee/,static/js/,$(COFFEESRCFILES:.coffee=.js))
# Minified files
JSDSTFILES=$(JSSRCFILES:.js=.min.js)
CSSDSTFILES=$(CSSSRCFILES:.css=.min.css)
......@@ -258,6 +262,12 @@ configure: json common_conf handler_conf portal_conf manager_conf
minify: $(JSDSTFILES) $(CSSDSTFILES)
$(SRCMANAGERDIR)/site/static/js/%.js: $(SRCMANAGERDIR)/site/coffee/%.coffee
@if which coffee >/dev/null; then \
echo "Compiling $(SRCMANAGERDIR)/site/coffee/$*.coffee"; \
coffee -c -o $(SRCMANAGERDIR)/site/static/js/ $(SRCMANAGERDIR)/site/coffee/$*.coffee; \
fi
%.min.css: %.css
@echo "Compressing $*.css"
@yui-compressor $*.css > $*.min.css
......@@ -272,7 +282,7 @@ fastcgi-server/man/llng-fastcgi-server.1p: fastcgi-server/sbin/llng-fastcgi-serv
# Perl libraries configuration
json: $(MANAGERJSONDST) fastcgi-server/man/llng-fastcgi-server.1p
@if which yui-compressor; then $(MAKE) minify; fi
@if which yui-compressor >/dev/null; then $(MAKE) minify; fi
$(MANAGERJSONDST): $(MANAGERJSONSRC)
./scripts/jsongenerator.pl
......@@ -1010,7 +1020,7 @@ tidy: clean
$(MAKE) json
tidy-js: clean
@find $(SRCMANAGERDIR)/site/static/js/ e2e-tests/ $(SRCPORTALDIR)/example \
@find e2e-tests/ $(SRCPORTALDIR)/example \
-type f \
-name '*.js' \
! -name 'jq*' \
......
###
LemonLDAP::NG base app module
This file contains:
- 3 AngularJS directives (HTML attributes):
* `on-read-file` to get file content
* `resizer` to resize HTML div
* `trspan` to set translated message in HTML content
- a AngularJS factory to handle 401 Ajax responses
###
llapp = angular.module 'llApp', []
# TRANSLATION SYSTEM
#
# It provides:
# - 3 functions to translate:
# * translate(word)
# * translateP(paragraph): only __words__ are translated
# * translateField(object, property)
# - an HTML attribute called 'trspan'. Exemple: <h3 trspan="portal"/>
# $translator provider
llapp.provider '$translator', ->
res = {}
# Language detection
if navigator
langs = []
langs2 = []
nlangs = [ navigator.language ]
if navigator.languages
nlangs = navigator.languages
for nl in nlangs
for al in window.availableLanguages
if al == nl
langs.push al
else if al.substring(0, 1) == nl.substring(0, 1)
langs2.push al
res.lang = if langs[0] then langs[0] else if langs2[0] then langs2[0] else 'en';
else
res.lang = 'en'
# Internal properties
res.deferredTr = []
res.translationFields = {}
# Translation methods
# 1. word translation
res.translate = (s) ->
if res.translationFields[s]
s = res.translationFields[s]
return s
# 2. node field translation
res.translateField = (node, field) ->
res.translate node[field]
# 3. paragraph translation (verify that json is available
res.translateP = (s) ->
if s and res.translationFields.portal
s = s.replace /__(\w+)__/g, (match,w) ->
res.translate w
s
# Initialization
this.$get = [ '$q', '$http', ($q, $http) ->
res.last = ''
res.init = (lang) ->
lang = res.lang unless lang
d = $q.defer()
if res.last != lang
res.last = lang
$http.get("#{window.staticPrefix}languages/#{lang}.json").then (response) ->
res.translationFields = response.data
for h in res.deferredTr
h.e[h.f] res.translationFields[h.m]
res.deferredTr = []
d.resolve "Translation files loaded"
, (response) ->
d.reject ''
else
d.resolve "No change"
d.promise
res
]
this
# Translation directive (HTML trspan tag)
llapp.directive 'trspan', [ '$translator', ($translator) ->
restrict: 'A'
replace: false
transclude: true
scope:
trspan: "@"
link: (scope, elem, attr) ->
if $translator.translationFields.portal
attr.trspan = $translator.translate(attr.trspan)
# Deferred translations will be done after JSON download
else
$translator.deferredTr.push
e: elem
f: 'text'
m: attr.trspan
elem.text attr.trspan
template: ''
]
# Form menu management
#
# Two parts:
# - $htmlParams: used to store values inserted as <script type="text/menu">.
# It provides menu() method to get them
# - HTML "script" element handler
llapp.provider '$htmlParams', ->
this.$get = ->
params = {}
set: (key, obj) ->
params[key] = obj
menu: ->
params.menu
# To be used later
params: ->
params.params
this
llapp.directive 'script', ['$htmlParams', ($htmlParams) ->
restrict: 'E'
terminal: true
compile: (element, attr) ->
if t = attr.type.match /text\/(menu|parameters)/
$htmlParams.set t[1], eval element[0].text
]
# Modal controller used to display messages
llapp.controller 'ModalInstanceCtrl', ['$scope', '$uibModalInstance', 'elem', 'set', 'init', ($scope, $uibModalInstance, elem, set, init) ->
oldvalue = null
$scope.elem = elem
$scope.set = set
$scope.result = init
$scope.staticPrefix = window.staticPrefix
currentNode = elem 'currentNode'
$scope.translateP = elem 'translateP'
if currentNode
oldValue = currentNode.data
$scope.currentNode = currentNode
$scope.ok = ->
set('result', $scope.result)
$uibModalInstance.close(true)
$scope.cancel = ->
if currentNode then $scope.currentNode.data = oldValue
$uibModalInstance.dismiss('cancel')
# test if value is in select
$scope.inSelect = (value) ->
for i in $scope.currentNode.select
if i.k == value then return true
return false
]
# File reader directive
#
# Add "onReadFile" HTML attribute to be used in a "file" input
# The content off attribute will be launched.
#
# Example:
# <input type="file" on-read-file="replaceContent($fileContent)"/>
llapp.directive 'onReadFile', [ '$parse', ($parse) ->
restrict: 'A'
scope: false
link: (scope, element, attrs) ->
fn = $parse attrs.onReadFile
element.on 'change', (onChangeEvent) ->
reader = new FileReader()
reader.onload = (onLoadEvent) ->
scope.$apply () ->
fn scope,
$fileContent: onLoadEvent.target.result
reader.readAsText ((onChangeEvent.srcElement || onChangeEvent.target).files[0])
]
# Resize system
#
# Add a "resizer" HTML attribute
llapp.directive 'resizer', ['$document', ($document) ->
hsize = null
rsize = null
($scope, $element, $attrs) ->
$element.on 'mousedown', (event) ->
if $attrs.resizer == 'vertical'
rsize = $($attrs.resizerRight).width() + $($attrs.resizerLeft).width()
else
hsize = $($attrs.resizerTop).height() + $($attrs.resizerBottom).height()
event.preventDefault()
$document.on 'mousemove', mousemove
$document.on 'mouseup', mouseup
mousemove = (event) ->
# Handle vertical resizer
if $attrs.resizer == 'vertical'
x = event.pageX
if $attrs.resizerMax and x > $attrs.resizerMax
x = parseInt $attrs.resizerMax
$($attrs.resizerLeft).css
width: "#{x}px"
$($attrs.resizerRight).css
width: "#{rsize-x}px"
# Handle horizontal resizer
else
y = event.pageY - $('#navbar').height()
$($attrs.resizerTop).css
height: "#{y}px"
$($attrs.resizerBottom).css
height: "#{hsize-y}px"
mouseup = () ->
$document.unbind 'mousemove', mousemove
$document.unbind 'mouseup', mouseup
]
###
# Authentication system
#
# If a 401 code is returned and if "Authorization" header contains an url,
# user is redirected to this url (but target is replaced by location.href
###
llapp.factory '$lmhttp', ['$q', '$location', ($q, $location) ->
responseError: (rejection) ->
if rejection.status == 401 and window.portal
window.location = "#{window.portal}?url=" + window.btoa(window.location).replace(/\//, '_')
]
llapp.config [ '$httpProvider', ($httpProvider) ->
$httpProvider.interceptors.push '$lmhttp'
]
This diff is collapsed.
(function(){var llapp=angular.module("llApp",[]);llapp.provider("$translator",$Translator);function $Translator(){var res={};if(navigator){var nlangs=[navigator.language];if(navigator.languages){nlangs=navigator.languages}var langs=[],langs2=[];nlangs.forEach(function(nl){availableLanguages.forEach(function(al){if(al==nl){langs.push(al)}else{if(al.substring(0,1)==nl.substring(0,1)){langs2.push(al)}}})});res.lang=langs[0]?langs[0]:langs2[0]?langs2[0]:"en"}else{res.lang="en"}res.deferredTr=[];res.translationFields={};res.translate=function(s){if(res.translationFields[s]){s=res.translationFields[s]}return s};res.translateField=function(node,field){return res.translate(node[field])};res.translateP=function(s){if(s&&res.translationFields.portal){s=s.replace(/__(\w+)__/g,function(match,w){return res.translate(w)})}return s};this.$get=["$q","$http",function($q,$http){res.last="";res.init=function(lang){if(!lang){lang=res.lang}var d=$q.defer();if(res.last!=lang){res.last=lang;$http.get(staticPrefix+"languages/"+lang+".json").then(function(response){res.translationFields=response.data;res.deferredTr.forEach(function(h){h.e[h.f](res.translationFields[h.m])});res.deferredTr=[];d.resolve("Translation files loaded")},function(resp){d.reject("")})}else{d.resolve("No change")}return d.promise};return res}]}llapp.directive("trspan",["$translator",function($translator){return{restrict:"A",replace:false,transclude:true,scope:{trspan:"@"},link:function(scope,elem,attr){if($translator.translationFields.portal){attr.trspan=$translator.translate(attr.trspan)}else{$translator.deferredTr.push({e:elem,f:"text",m:attr.trspan})}elem.text(attr.trspan)},template:""}}]);llapp.provider("$htmlParams",$HtmlParamsProvider);function $HtmlParamsProvider(){this.$get=function(){var params={};return{set:function(key,obj){params[key]=obj},menu:function(){return params.menu},params:function(){return params.params}}}}llapp.directive("script",["$htmlParams",function($htmlParams){return{restrict:"E",terminal:true,compile:function(element,attr){var t;if(t=attr.type.match(/text\/(menu|parameters)/)){$htmlParams.set(t[1],eval(element[0].text))}}}}]);llapp.controller("ModalInstanceCtrl",["$scope","$uibModalInstance","elem","set","init",function($scope,$uibModalInstance,elem,set,init){var oldValue;$scope.elem=elem;$scope.set=set;$scope.result=init;$scope.staticPrefix=staticPrefix;var currentNode=elem("currentNode");$scope.translateP=elem("translateP");if(currentNode){oldValue=currentNode.data;$scope.currentNode=currentNode}$scope.ok=function(){set("result",$scope.result);$uibModalInstance.close(true)};$scope.cancel=function(){if(currentNode){$scope.currentNode.data=oldValue}$uibModalInstance.dismiss("cancel")};$scope.inSelect=function(value){for(var i=0;i<$scope.currentNode.select.length;i++){if($scope.currentNode.select[i].k==value){return true}}return false}}]);llapp.directive("onReadFile",["$parse",function($parse){return{restrict:"A",scope:false,link:function(scope,element,attrs){var fn=$parse(attrs.onReadFile);element.on("change",function(onChangeEvent){var reader=new FileReader();reader.onload=function(onLoadEvent){scope.$apply(function(){fn(scope,{$fileContent:onLoadEvent.target.result})})};reader.readAsText((onChangeEvent.srcElement||onChangeEvent.target).files[0])})}}}]);llapp.directive("resizer",["$document",function($document){var rsize,hsize;return function($scope,$element,$attrs){$element.on("mousedown",function(event){if($attrs.resizer=="vertical"){rsize=$($attrs.resizerRight).width()+$($attrs.resizerLeft).width()}else{hsize=$($attrs.resizerTop).height()+$($attrs.resizerBottom).height()}event.preventDefault();$document.on("mousemove",mousemove);$document.on("mouseup",mouseup)});function mousemove(event){if($attrs.resizer=="vertical"){var x=event.pageX;if($attrs.resizerMax&&x>$attrs.resizerMax){x=parseInt($attrs.resizerMax)}$($attrs.resizerLeft).css({width:x+"px"});$($attrs.resizerRight).css({width:(rsize-x)+"px"})}else{var y=event.pageY-$("#navbar").height();$($attrs.resizerTop).css({height:y+"px"});$($attrs.resizerBottom).css({height:(hsize-y)+"px"})}}function mouseup(){$document.unbind("mousemove",mousemove);$document.unbind("mouseup",mouseup)}}}]);llapp.factory("$lmhttp",["$q","$location",function($q,$location){return{responseError:function(rejection){if(rejection.status==401&&window.portal){window.location=window.portal+"?url="+window.btoa(window.location).replace(/\//,"_")}}}}]);llapp.config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push("$lmhttp")}])})();
\ No newline at end of file
(function(){var llapp;llapp=angular.module("llApp",[]);llapp.provider("$translator",function(){var al,j,k,langs,langs2,len,len1,nl,nlangs,ref,res;res={};if(navigator){langs=[];langs2=[];nlangs=[navigator.language];if(navigator.languages){nlangs=navigator.languages}for(j=0,len=nlangs.length;j<len;j++){nl=nlangs[j];ref=window.availableLanguages;for(k=0,len1=ref.length;k<len1;k++){al=ref[k];if(al===nl){langs.push(al)}else{if(al.substring(0,1)===nl.substring(0,1)){langs2.push(al)}}}}res.lang=langs[0]?langs[0]:langs2[0]?langs2[0]:"en"}else{res.lang="en"}res.deferredTr=[];res.translationFields={};res.translate=function(s){if(res.translationFields[s]){s=res.translationFields[s]}return s};res.translateField=function(node,field){return res.translate(node[field])};res.translateP=function(s){if(s&&res.translationFields.portal){s=s.replace(/__(\w+)__/g,function(match,w){return res.translate(w)})}return s};this.$get=["$q","$http",function($q,$http){res.last="";res.init=function(lang){var d;if(!lang){lang=res.lang}d=$q.defer();if(res.last!==lang){res.last=lang;$http.get(window.staticPrefix+"languages/"+lang+".json").then(function(response){var h,l,len2,ref1;res.translationFields=response.data;ref1=res.deferredTr;for(l=0,len2=ref1.length;l<len2;l++){h=ref1[l];h.e[h.f](res.translationFields[h.m])}res.deferredTr=[];return d.resolve("Translation files loaded")},function(response){return d.reject("")})}else{d.resolve("No change")}return d.promise};return res}];return this});llapp.directive("trspan",["$translator",function($translator){return{restrict:"A",replace:false,transclude:true,scope:{trspan:"@"},link:function(scope,elem,attr){if($translator.translationFields.portal){attr.trspan=$translator.translate(attr.trspan)}else{$translator.deferredTr.push({e:elem,f:"text",m:attr.trspan})}return elem.text(attr.trspan)},template:""}}]);llapp.provider("$htmlParams",function(){this.$get=function(){var params;params={};return{set:function(key,obj){return params[key]=obj},menu:function(){return params.menu},params:function(){return params.params}}};return this});llapp.directive("script",["$htmlParams",function($htmlParams){return{restrict:"E",terminal:true,compile:function(element,attr){var t;if(t=attr.type.match(/text\/(menu|parameters)/)){return $htmlParams.set(t[1],eval(element[0].text))}}}}]);llapp.controller("ModalInstanceCtrl",["$scope","$uibModalInstance","elem","set","init",function($scope,$uibModalInstance,elem,set,init){var currentNode,oldValue,oldvalue;oldvalue=null;$scope.elem=elem;$scope.set=set;$scope.result=init;$scope.staticPrefix=window.staticPrefix;currentNode=elem("currentNode");$scope.translateP=elem("translateP");if(currentNode){oldValue=currentNode.data;$scope.currentNode=currentNode}$scope.ok=function(){set("result",$scope.result);return $uibModalInstance.close(true)};$scope.cancel=function(){if(currentNode){$scope.currentNode.data=oldValue}return $uibModalInstance.dismiss("cancel")};return $scope.inSelect=function(value){var i,j,len,ref;ref=$scope.currentNode.select;for(j=0,len=ref.length;j<len;j++){i=ref[j];if(i.k===value){return true}}return false}}]);llapp.directive("onReadFile",["$parse",function($parse){return{restrict:"A",scope:false,link:function(scope,element,attrs){var fn;fn=$parse(attrs.onReadFile);return element.on("change",function(onChangeEvent){var reader;reader=new FileReader();reader.onload=function(onLoadEvent){return scope.$apply(function(){return fn(scope,{$fileContent:onLoadEvent.target.result})})};return reader.readAsText((onChangeEvent.srcElement||onChangeEvent.target).files[0])})}}}]);llapp.directive("resizer",["$document",function($document){var hsize,rsize;hsize=null;rsize=null;return function($scope,$element,$attrs){var mousemove,mouseup;$element.on("mousedown",function(event){if($attrs.resizer==="vertical"){rsize=$($attrs.resizerRight).width()+$($attrs.resizerLeft).width()}else{hsize=$($attrs.resizerTop).height()+$($attrs.resizerBottom).height()}event.preventDefault();$document.on("mousemove",mousemove);return $document.on("mouseup",mouseup)});mousemove=function(event){var x,y;if($attrs.resizer==="vertical"){x=event.pageX;if($attrs.resizerMax&&x>$attrs.resizerMax){x=parseInt($attrs.resizerMax)}$($attrs.resizerLeft).css({width:x+"px"});return $($attrs.resizerRight).css({width:(rsize-x)+"px"})}else{y=event.pageY-$("#navbar").height();$($attrs.resizerTop).css({height:y+"px"});return $($attrs.resizerBottom).css({height:(hsize-y)+"px"})}};return mouseup=function(){$document.unbind("mousemove",mousemove);return $document.unbind("mouseup",mouseup)}}}]);llapp.factory("$lmhttp",["$q","$location",function($q,$location){return{responseError:function(rejection){if(rejection.status===401&&window.portal){return window.location=(window.portal+"?url=")+window.btoa(window.location).replace(/\//,"_")}}}}]);llapp.config(["$httpProvider",function($httpProvider){return $httpProvider.interceptors.push("$lmhttp")}])}).call(this);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment