Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • feature/migrate-cordova-13
  • feat/improve-network-scan
  • feat/force-migration-check
  • develop
  • feature/encrypted_comment
  • feature/android_api_19
  • gitlab_migration_1
  • rml8
  • v1.7.14
  • v1.7.13
  • v1.7.12
  • v1.7.11
  • v1.7.10
  • v1.7.9
  • v1.7.8
  • v1.7.7
  • v1.7.6
  • v1.7.5
  • v1.7.4
  • v1.7.3
  • v1.7.2
  • v1.7.1
  • v1.7.0
  • v1.7.0-rc2
  • v1.7.0-rc1
  • v1.6.12
  • v1.6.11
  • v1.6.10
29 results

directives.js

Blame
  • directives.js 15.93 KiB
    angular.module('cesium.directives', [])
    
      // Add new compare-to directive (need for form validation)
      .directive("compareTo", function() {
          return {
              require: "?ngModel",
              link: function(scope, element, attributes, ngModel) {
                if (ngModel && attributes.compareTo) {
                  ngModel.$validators.compareTo = function(modelValue) {
                      return modelValue == scope.$eval(attributes.compareTo);
                  };
    
                  scope.$watch(attributes.compareTo, function() {
                      ngModel.$validate();
                  });
                }
              }
          };
      })
    
      // Add new different-to directive (need for form validation)
      .directive("differentTo", function() {
        return {
          require: "?ngModel",
          link: function(scope, element, attributes, ngModel) {
            if (ngModel && attributes.differentTo) {
              ngModel.$validators.differentTo = function(modelValue) {
                return modelValue != scope.$eval(attributes.differentTo);
              };
    
              scope.$watch(attributes.differentTo, function() {
                ngModel.$validate();
              });
            }
          }
        };
      })
    
      .directive('numberFloat', function() {
        var NUMBER_REGEXP = new RegExp('^[0-9]+([.,][0-9]+)?$');
    
        return {
          require: '?ngModel',
          link: function(scope, element, attributes, ngModel) {
            if (ngModel) {
              ngModel.$validators.numberFloat = function(value) {
                return ngModel.$isEmpty(value) || NUMBER_REGEXP.test(value);
              };
            }
          }
        };
      })
    
      .directive('numberInt', function() {
        var INT_REGEXP = new RegExp('^[0-9]+$');
        return {
          require: 'ngModel',
          link: function(scope, element, attrs, ngModel) {
            if (ngModel) {
              ngModel.$validators.numberInt = function (value) {
                return ngModel.$isEmpty(value) || INT_REGEXP.test(value);
              };
            }
          }
        };
      })
    
      .directive('email', function() {
        var EMAIL_REGEXP = new RegExp('^[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$');
        return {
          require: 'ngModel',
          link: function(scope, element, attrs, ngModel) {
            if (ngModel) {
              ngModel.$validators.email = function (value) {
                return ngModel.$isEmpty(value) || EMAIL_REGEXP.test(value);
              };
            }
          }
        };
      })
    
      .directive('requiredIf', function() {
        return {
          require: '?ngModel',
          link: function(scope, element, attributes, ngModel) {
            if (ngModel && attributes.requiredIf) {
              ngModel.$validators.required = function(value) {
                return !(scope.$eval(attributes.requiredIf)) || !ngModel.$isEmpty(value);
              };
    
              scope.$watch(attributes.requiredIf, function() {
                ngModel.$validate();
              });
            }
          }
        };
      })
    
      .directive('geoPoint', function() {
        return {
          require: '?ngModel',
          link: function(scope, element, attributes, ngModel) {
            if (ngModel) {
              ngModel.$validators.geoPoint = function(value) {
                return ngModel.$isEmpty(value) ||
                  // twice are defined
                  (angular.isDefined(value.lat) && angular.isDefined(value.lon)) ||
                  // or twice are NOT defined (=empty object - can be useful to override data in ES node)
                  (angular.isUndefined(value.lat) && angular.isUndefined(value.lon));
              };
            }
          }
        };
      })
    
      // Add a copy-on-click directive
      .directive('copyOnClick', function ($window, Device, UIUtils) {
        'ngInject';
        return {
          restrict: 'A',
          link: function (scope, element, attrs) {
            var showCopyPopover = function (event) {
              var value = attrs.copyOnClick;
              if (value === undefined || value === null) return; // Skip if no value
              if (Device.clipboard.enable) {
                // copy to clipboard, using cordova
                Device.clipboard.copy(value)
                  .then(function(){
                     UIUtils.toast.show('INFO.COPY_TO_CLIPBOARD_DONE');
                  })
                  .catch(UIUtils.onError('ERROR.COPY_CLIPBOARD'));
              }
              else {
    
                var rows = value && value.indexOf('\n') >= 0 ? value.split('\n').length : 1;
                UIUtils.popover.show(event, {
                  scope: scope,
                  templateUrl: 'templates/common/popover_copy.html',
                  bindings: {
                    value: attrs.copyOnClick,
                    rows: rows,
                    copied: false
                  },
                  autoselect: '.popover-copy ' + (rows <= 1 ? 'input' : 'textarea'),
    
                  // After popover, try to copy the selection
                  afterShow: document.execCommand ? function(popover) {
                    try {
                      document.execCommand("copy");
                      UIUtils.toast.show('INFO.COPY_TO_CLIPBOARD_DONE', 1000);
                    } catch (err) {
                      console.error("[copy-on-click] Failed to copy using document.execCommand('copy')", err);
                    }
                  } : undefined
                });
              }
    
            };
            element.bind('click', showCopyPopover);
            element.bind('hold', showCopyPopover);
          }
        };
      })
    
      // Add a select-on-click directive
      .directive('selectOnClick', function ($window) {
        'ngInject';
          return {
              restrict: 'A',
              link: function (scope, element, attrs) {
                  element.bind('click', function () {
                    if ($window.getSelection && !$window.getSelection().toString() && this.value) {
                      this.setSelectionRange(0, this.value.length);
                    }
                  });
              }
          };
      })
    
      .directive('activeLink', function ($location) {
        'ngInject';
        return {
          restrict: 'A',
          link: function(scope, element, attrs, controller) {
            var clazz = attrs.activeLink;
            var path;
            if (attrs.activeLinkPathPrefix) {
              path = attrs.activeLinkPathPrefix.substring(1); //hack because path does not return including hashbang
              scope.location = $location;
              scope.$watch('location.path()', function (newPath) {
                if (newPath && newPath.indexOf(path) === 0) {
                  element.addClass(clazz);
                } else {
                  element.removeClass(clazz);
                }
              });
            }
            else if (attrs.href) {
              path = attrs.href.substring(1); //hack because path does not return including hashbang
              scope.location = $location;
              scope.$watch('location.path()', function (newPath) {
                if (newPath && newPath == path) {
                  element.addClass(clazz);
                } else {
                  element.removeClass(clazz);
                }
              });
            }
          }
        };
      })
    
      // All this does is allow the message
      // to be sent when you tap return
      .directive('input', function($timeout) {
        'ngInject';
        return {
          restrict: 'E',
          scope: {
            'returnClose': '=',
            'onReturn': '&',
            'onFocus': '&',
            'onBlur': '&'
          },
          link: function(scope, element, attr) {
            element.bind('focus', function(e) {
              if (scope.onFocus) {
                $timeout(function() {
                  scope.onFocus();
                });
              }
            });
            element.bind('blur', function(e) {
              if (scope.onBlur) {
                $timeout(function() {
                  scope.onBlur();
                });
              }
            });
            element.bind('keydown', function(e) {
              if (e.which == 13) {
                if (scope.returnClose) element[0].blur();
                if (scope.onReturn) {
                  $timeout(function() {
                    scope.onReturn();
                  });
                }
              }
            });
          }
        };
      })
    
      .directive('trustAsHtml', function($sce, $compile, $parse){
        'ngInject';
        return {
          restrict: 'A',
          compile: function (tElement, tAttrs) {
            var ngBindHtmlGetter = $parse(tAttrs.trustAsHtml);
            var ngBindHtmlWatch = $parse(tAttrs.trustAsHtml, function getStringValue(value) {
              return (value || '').toString();
            });
            $compile.$$addBindingClass(tElement);
    
            return function ngBindHtmlLink(scope, element, attr) {
              $compile.$$addBindingInfo(element, attr.trustAsHtml);
    
              scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
                // we re-evaluate the expr because we want a TrustedValueHolderType
                // for $sce, not a string
                element.html($sce.getTrustedHtml($sce.trustAsHtml(ngBindHtmlGetter(scope))) || '');
                $compile(element.contents())(scope);
              });
            };
          }
        };
      })
    
      /**
      * Close the current modal
      */
      .directive('modalClose', function($ionicHistory, $timeout) {
        'ngInject';
    
        return {
          restrict: 'AC',
          link: function($scope, $element) {
            $element.bind('click', function() {
              if ($scope.closeModal) {
                $ionicHistory.nextViewOptions({
                  historyRoot: true,
                  disableAnimate: true,
                  expire: 300
                });
                // if no transition in 300ms, reset nextViewOptions
                // the expire should take care of it, but will be cancelled in some
                // cases. This directive is an exception to the rules of history.js
                $timeout( function() {
                  $ionicHistory.nextViewOptions({
                    historyRoot: false,
                    disableAnimate: false
                  });
                }, 300);
                $scope.closeModal();
              }
            });
          }
        };
      })
    
      /**
      * Plugin extension point (see services/plugin-services.js)
      */
      .directive('csExtensionPoint', function ($state, $compile, $controller, $templateCache, PluginService) {
        'ngInject';
    
        var getTemplate = function(extensionPoint) {
          var template = extensionPoint.templateUrl ? $templateCache.get(extensionPoint.templateUrl) : extensionPoint.template;
          if (!template) {
            console.error('[plugin] Could not found template for extension :' + (extensionPoint.templateUrl ? extensionPoint.templateUrl : extensionPoint.template));
            return '';
          }
          if (extensionPoint.controller) {
            template = '<ng-controller ng-controller="'+extensionPoint.controller+'">' + template + '</div>';
          }
          return template;
        };
    
        var compiler = function(tElement, tAttributes) {
    
          if (angular.isDefined(tAttributes.name)) {
            var extensionPoints = PluginService.extensions.points.getActivesByName(tAttributes.name);
            if (extensionPoints.length > 0) {
              tElement.html("");
              _.forEach(extensionPoints, function(extensionPoint){
                tElement.append(getTemplate(extensionPoint));
              });
            }
          }
    
          return {
            pre: function(scope, iElement, iAttrs){
              PluginService.extensions.points.current.set(iAttrs.name);
            },
            post: function(){
              PluginService.extensions.points.current.set();
            }
          };
        };
    
    
        return {
          restrict: "E",
          compile: compiler,
          scope: {
              content:'='
          }
        };
      })
    
      .directive('onReadFile', function ($parse) {
        'ngInject';
    
        return {
          restrict: 'A',
          scope: false,
          link: function(scope, element, attrs) {
            var fn = $parse(attrs.onReadFile);
    
            element.on('change', function(onChangeEvent) {
              var reader = new FileReader();
              var fileData = {
                name: this.files[0].name,
                size: this.files[0].size,
                type: this.files[0].type
              };
    
              reader.onload = function(onLoadEvent) {
                scope.$applyAsync(function() {
                  fn(scope, {
                    file: {
                      fileContent: onLoadEvent.target.result,
                      fileData : fileData}
                  });
                });
              };
              reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
            });
          }
        };
      })
    
      .directive("dropZone", function($parse) {
        'ngInject';
        return {
          restrict: 'A',
          scope: false,
          link: function(scope, elem, attrs) {
            var fn = $parse(attrs.dropZone);
            elem.bind('dragover', function (e) {
              e.stopPropagation();
              e.preventDefault();
            });
            elem.bind('dragenter', function(e) {
              e.stopPropagation();
              e.preventDefault();
            });
            elem.bind('dragleave', function(e) {
              e.stopPropagation();
              e.preventDefault();
            });
            elem.bind('drop', function(e) {
              e.stopPropagation();
              e.preventDefault();
              var file = e.dataTransfer.files[0];
              var fileData = {
                name: file.name,
                size: file.size,
                type: file.type
              };
    
              var reader = new FileReader();
              reader.onload = function(onLoadEvent) {
                scope.$apply(function () {
                  fn(scope, {
                    file: {
                      file: file,
                      fileContent: onLoadEvent.target.result,
                      fileData : fileData}
                  });
                });
              };
              reader.readAsText(e.dataTransfer.files[0]);
            });
          }
        };
      })
    
    
      // See http://embed.plnkr.co/2vgnFe/
      .directive('fileSelect', function($parse) {
        'ngInject';
    
        return {
          restrict: 'A',
          scope: false,
          template: '<input type="file" style="display: none;" />' +
            '<ng-transclude></ng-transclude>',
          transclude: true,
          link: function (scope, element, attrs) {
            var fn = $parse(attrs.fileSelect);
    
            var fileInput = element.children('input[file]');
    
            if (attrs.accept) {
              fileInput[0].accept = attrs.accept;
            }
    
            fileInput.on('change', function (onChangeEvent) {
              var reader = new FileReader();
              var file = this.files[0];
              var fileData = {
                name: file.name,
                size: file.size,
                type: file.type
              };
    
              reader.onload = function(onLoadEvent) {
                scope.$applyAsync(function() {
                  fn(scope, {
                    file: {
                      file: file,
                      fileContent: onLoadEvent.target.result,
                      fileData : fileData}
                  });
    
                  // Reset the input file
                  fileInput[0].value = '';
    
                });
              };
              reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
            });
    
            element.on('click', function () {
              fileInput[0].click();
            });
          }
        };
      })
    
    
      // Un-authenticate when window closed
      // see: https://stackoverflow.com/questions/28197316/javascript-or-angularjs-defer-browser-close-or-tab-close-between-refresh
      .directive('windowExitUnauth', function($window, csSettings, csWallet) {
        'ngInject';
    
        return {
          restrict: 'AE',
          link: function(element, attrs){
            var myEvent = $window.attachEvent || $window.addEventListener,
              chkevent = $window.attachEvent ? 'onunload' : 'unload'; /// make IE7, IE8 compatible
    
            myEvent(chkevent, function (e) { // For >=IE7, Chrome, Firefox
              if (csSettings.data && csSettings.data.keepAuthIdle != csSettings.constants.KEEP_AUTH_IDLE_SESSION) {
                return csWallet.unauth();
              }
            });
          }
        };
      })
    
      // Jdenticon directive (to generate icon from a string)
      // see:
      .directive('jdenticon', function($parse) {
        'ngInject';
    
        return {
          restrict: 'A',
          scope: false,
          template: '<canvas></canvas>',
          transclude: false,
          link: function (scope, element, attrs) {
            var value = attrs.jdenticon;
            var size = attrs.jdenticonSize || 54;
            var canvas = element.children('canvas')[0];
    
            if (!value) {
              canvas.height = 0;
              canvas.width = 0;
            }
            else {
              canvas.height  = size;
              canvas.width  = size;
    
              var ctx = canvas.getContext("2d");
              jdenticon.drawIcon(ctx, value, size);
            }
          }
        };
      });