Files
xen-orchestra/app/node_modules/xo-directives/index.coffee
2015-05-22 15:16:02 +02:00

125 lines
3.6 KiB
CoffeeScript

angular = require 'angular'
# TODO: split into multiple modules.
module.exports = angular.module 'xoWebApp.directives', []
# This attribute stops the ascendant propagation of a given event.
#
# The value of this attribute should be the name of the event to
# stop.
.directive 'stopEvent', ->
(_, $element, attrs) ->
$element.on attrs.stopEvent, ($event) ->
$event.stopPropagation()
# This attribute works similarly to `ng-click` but do not handle the
# event if the clicked element:
# - is an `input`;
# - has a `ng-click` attribute;
# - has a `xo-click` attribute;
# - has a `xo-sref` attribute;
# - is a link (`a`) and has a `href` attribute.
.directive 'xoClick', ($parse) ->
($scope, $element, attrs) ->
fn = $parse attrs.xoClick
current = $element[0]
current.addEventListener(
'click'
(event) ->
# Browse all parent elements of the element the event
# happened to and abort if one of them should handle the
# event itself.
el = event.target
while el isnt current
{attributes: attrs, tagName: tag} = el
return if (
tag is 'INPUT' or
attrs['ng-click']? or
attrs['xo-click']? or
attrs['xo-sref']? or
(tag is 'A') and attrs.href?
)
el = el.parentNode
# Stop the propagation.
event.stopPropagation()
# Apply the `xo-click` attribute.
$scope.$applyAsync ->
fn $scope, {$event: event}
true
)
# TODO: create a directive which allows a link on any element.
# TODO: Mutualize code with `xoClick`.
.directive 'xoSref', ($state, $window) ->
($scope, $element, attrs) ->
current = $element[0]
current.addEventListener(
'mouseup'
(event) ->
{which: button} = event
return unless button is 1 or button is 2
# Browse all parent elements of the element the event
# happened to and abort if one of them should handle the
# event itself.
el = event.target
while el isnt current
{attributes: attrs_, tagName: tag} = el
return if (
tag is 'INPUT' or
attrs_['ng-click']? or
attrs_['xo-click']? or
attrs_['xo-sref']? or
(tag is 'A') and attrs_.href?
)
el = el.parentNode
# Stop the propagation.
event.stopPropagation()
# Extracts the state and its parameters for the `xo-sref`
# attribute.
match = attrs.xoSref.match /^([^(]+)\s*(?:\((.*)\))?$/
throw new Error 'invalid SREF' unless match
state = match[1]
params = if match[2] then $scope.$eval match[2] else {}
# Ctrl modifier or middle-button.
if event.ctrlKey or button is 2
url = $state.href state, params
$window.open url
else
$state.go state, params
true
)
.directive 'fixAutofill', ($timeout) ->
restrict: 'A'
require: 'ngModel'
link: ($scope, $elem, attrs, ngModel) ->
previous = $elem.val()
updateValue = ->
current = $elem.val()
if ngModel.$pristine and current isnt previous
previous = current
ngModel.$setViewValue current
# Attempt to update the value.
$timeout updateValue, 5e2
# A refresh can be asked via the fixAutofill event.
$scope.$on 'fixAutofill', updateValue
# A module exports its name.
.name