summaryrefslogtreecommitdiffstats
path: root/afb-client/bower_components/foundation-apps/js/angular/vendor/svgDirs.js
blob: c07c883d6acaa614f049281bdd126a3a23f77eba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict';

(function(){
  var svgDirectives = {};

  angular.forEach([
      'clipPath',
      'colorProfile',
      'src',
      'cursor',
      'fill',
      'filter',
      'marker',
      'markerStart',
      'markerMid',
      'markerEnd',
      'mask',
      'stroke'
    ],
    function(attr) {
      svgDirectives[attr] = [
          '$rootScope',
          '$location',
          '$interpolate',
          '$sniffer',
          'urlResolve',
          'computeSVGAttrValue',
          'svgAttrExpressions',
          function(
              $rootScope,
              $location,
              $interpolate,
              $sniffer,
              urlResolve,
              computeSVGAttrValue,
              svgAttrExpressions) {
            return {
              restrict: 'A',
              link: function(scope, element, attrs) {
                var initialUrl;

                //Only apply to svg elements to avoid unnecessary observing
                //Check that is in html5Mode and that history is supported
                if ((!svgAttrExpressions.SVG_ELEMENT.test(element[0] &&
                    element[0].toString())) ||
                  !$location.$$html5 ||
                  !$sniffer.history) return;

                //Assumes no expressions, since svg is unforgiving of xml violations
                initialUrl = attrs[attr];
                attrs.$observe(attr, updateValue);
                $rootScope.$on('$locationChangeSuccess', updateValue);

                function updateValue () {
                  var newVal = computeSVGAttrValue(initialUrl);
                  //Prevent recursive updating
                  if (newVal && attrs[attr] !== newVal) attrs.$set(attr, newVal);
                }
              }
            };
          }];
  });

  angular.module('ngSVGAttributes', []).
    factory('urlResolve', [function() {
      //Duplicate of urlResolve & urlParsingNode in angular core
      var urlParsingNode = document.createElement('a');
      return function urlResolve(url) {
        urlParsingNode.setAttribute('href', url);
        return urlParsingNode;
      };
    }]).
    value('svgAttrExpressions', {
      FUNC_URI: /^url\((.*)\)$/,
      SVG_ELEMENT: /SVG[a-zA-Z]*Element/,
      HASH_PART: /#.*/
    }).
    factory('computeSVGAttrValue', [
                '$location', '$sniffer', 'svgAttrExpressions', 'urlResolve',
        function($location,   $sniffer,   svgAttrExpressions,   urlResolve) {
          return function computeSVGAttrValue(url) {
            var match, fullUrl;
            if (match = svgAttrExpressions.FUNC_URI.exec(url)) {
              //hash in html5Mode, forces to be relative to current url instead of base
              if (match[1].indexOf('#') === 0) {
                fullUrl = $location.absUrl().
                  replace(svgAttrExpressions.HASH_PART, '') +
                  match[1];
              }
              //Presumably links to external SVG document
              else {
                fullUrl = urlResolve(match[1]);
              }
            }
            return fullUrl ? 'url(' + fullUrl + ')' : null;
          };
        }
      ]
    ).
    directive(svgDirectives);
}());