<commit_before>angular.module('hyloDirectives', ['ngResource', 'hyloFilters']).

directive('ngEnter', function() {
  return function(scope, element, attrs) {
    element.bind("keydown keypress", function(event) {
      if (event.which === 13) {
        scope.$apply(function() {
          scope.$eval(attrs.ngEnter);
        });

        event.preventDefault();
      }
    });
  };
}).

directive('contenteditable', ['$sce', '$filter', function($sce, $filter) {
  return {
    restrict: 'A', // only activate on element attribute
    require: '?ngModel', // get a hold of NgModelController
    link: function(scope, element, attrs, ngModel) {
      if(!ngModel) return; // do nothing if no ng-model

      function read() {
        var html = element.html();
        // When we clear the content editable the browser leaves a <br> behind
        // If strip-br attribute is provided then we strip this out
        if (attrs.stripBr && html === '<br>') {
          html = '';
        }

        ngModel.$setViewValue(html);
      }

      //update mediumEditor when ngModel updates
      ngModel.$render = function() {
        mediumEditor.value(ngModel.$viewValue);
      };

      var mediumEditor = new Medium({
        element: angular.element(element)[0],
        mode: Medium.partialMode,
        placeholder: attrs.placeholder,
        autoHR: false,
        pasteAsText: true,
        pasteEventHandler: function(e) {
            e.preventDefault();
            var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('Paste something..');
            document.execCommand('insertText', false, text);
        }
      });

      scope.$on("$destroy", function handleDestroyEvent() {
        mediumEditor.destroy();
      });

      // Listen for change events to enable binding
      element.on('blur keyup change', function(e) {
        scope.$apply(read);
      });

      read(); // initialize
    }
  };
}]).

directive('ngFocusMe', ['$timeout', '$parse', '$window', function($timeout, $parse, $window) {
  return {
    //scope: true,   // optionally create a child scope
    link: function(scope, element, attrs) {
      var model = $parse(attrs.ngFocusMe);
      scope.$watch(model, function(value) {
        if(value === true) {
          var rect = element[0].getBoundingClientRect();

          // Test to see if the comment box is within the viewport... if it is, just focus without scrolling
          if (rect.top >= 0 &&
              rect.left >= 0 &&
              rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
              rect.right <= (window.innerWidth || document.documentElement.clientWidth)) {

            $timeout(function() {
              element[0].focus();
            }, 1);
          } else {
            $('html,body').animate({
              scrollTop: $(element[0]).offset().top - ($($window).height() - 190)
            }, {
              duration: 300,
              done: function() {
                element[0].focus();
              }
            });
          }
        }
      });
      // to address @blesh's comment, set attribute value to 'false'
      // on blur event:
      element.bind('blur', function() {
        scope.$apply(model.assign(scope, false));
      });
    }
  };
}]).

directive('seedText', ['$sce', '$compile', '$filter', '$parse', function($sce, $compile, $filter, $parse) {
    return {
      restrict: 'A',
      replace: true,
      template: '<span></span>',
      transclude: 'element',
      link: function(scope, iElement, iAttrs, controller, $transclude) {
        var parsed = $parse(iAttrs.seedText);
        function getStringValue() { return (parsed(scope) || '').toString(); }

        scope.$watch(getStringValue, function seedTextWatchFn(value) {

          /* Filter the seed text */
          var linkyText = $filter('linky')(value, '_blank');
          var linkyShortText = $filter('linkyShort')(linkyText);
          var carriageReturnText = $filter('convertCarriageReturn')(linkyShortText);


          var hashedText = $filter('hashtag')(carriageReturnText);

          var paddedVal = '<span>' + $sce.getTrustedHtml(hashedText) + '</span>'

          iElement.html($compile(paddedVal)(scope));
        });
      }
    }
}]).

directive('dotdotdot', ['$timeout', function($timeout) {
  return {
    link: function linkDotDotDot(scope, elm) {
      $timeout(function() { angular.element(elm).dotdotdot() }, 0);
    }
  };
}]).

directive('backImg', [function() {
  function link(scope, element, attrs) {
    scope.$watch(attrs.backImg, function(value) {
      if (!value) return;
      var url = value;
      element.css({
        'background-image': 'url(' + url +')'
      });
    });
  }
<commit_msg>update dotdotdot directive to reflect correct way to do it<commit_after>angular.module('hyloDirectives', ['ngResource', 'hyloFilters']).

directive('ngEnter', function() {
  return function(scope, element, attrs) {
    element.bind("keydown keypress", function(event) {
      if (event.which === 13) {
        scope.$apply(function() {
          scope.$eval(attrs.ngEnter);
        });

        event.preventDefault();
      }
    });
  };
}).

directive('contenteditable', ['$sce', '$filter', function($sce, $filter) {
  return {
    restrict: 'A', // only activate on element attribute
    require: '?ngModel', // get a hold of NgModelController
    link: function(scope, element, attrs, ngModel) {
      if(!ngModel) return; // do nothing if no ng-model

      function read() {
        var html = element.html();
        // When we clear the content editable the browser leaves a <br> behind
        // If strip-br attribute is provided then we strip this out
        if (attrs.stripBr && html === '<br>') {
          html = '';
        }

        ngModel.$setViewValue(html);
      }

      //update mediumEditor when ngModel updates
      ngModel.$render = function() {
        mediumEditor.value(ngModel.$viewValue);
      };

      var mediumEditor = new Medium({
        element: angular.element(element)[0],
        mode: Medium.partialMode,
        placeholder: attrs.placeholder,
        autoHR: false,
        pasteAsText: true,
        pasteEventHandler: function(e) {
            e.preventDefault();
            var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('Paste something..');
            document.execCommand('insertText', false, text);
        }
      });

      scope.$on("$destroy", function handleDestroyEvent() {
        mediumEditor.destroy();
      });

      // Listen for change events to enable binding
      element.on('blur keyup change', function(e) {
        scope.$apply(read);
      });

      read(); // initialize
    }
  };
}]).

directive('ngFocusMe', ['$timeout', '$parse', '$window', function($timeout, $parse, $window) {
  return {
    //scope: true,   // optionally create a child scope
    link: function(scope, element, attrs) {
      var model = $parse(attrs.ngFocusMe);
      scope.$watch(model, function(value) {
        if(value === true) {
          var rect = element[0].getBoundingClientRect();

          // Test to see if the comment box is within the viewport... if it is, just focus without scrolling
          if (rect.top >= 0 &&
              rect.left >= 0 &&
              rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
              rect.right <= (window.innerWidth || document.documentElement.clientWidth)) {

            $timeout(function() {
              element[0].focus();
            }, 1);
          } else {
            $('html,body').animate({
              scrollTop: $(element[0]).offset().top - ($($window).height() - 190)
            }, {
              duration: 300,
              done: function() {
                element[0].focus();
              }
            });
          }
        }
      });
      // to address @blesh's comment, set attribute value to 'false'
      // on blur event:
      element.bind('blur', function() {
        scope.$apply(model.assign(scope, false));
      });
    }
  };
}]).

directive('seedText', ['$sce', '$compile', '$filter', '$parse', function($sce, $compile, $filter, $parse) {
    return {
      restrict: 'A',
      replace: true,
      template: '<span></span>',
      transclude: 'element',
      link: function(scope, iElement, iAttrs, controller, $transclude) {
        var parsed = $parse(iAttrs.seedText);
        function getStringValue() { return (parsed(scope) || '').toString(); }

        scope.$watch(getStringValue, function seedTextWatchFn(value) {

          /* Filter the seed text */
          var linkyText = $filter('linky')(value, '_blank');
          var linkyShortText = $filter('linkyShort')(linkyText);
          var carriageReturnText = $filter('convertCarriageReturn')(linkyShortText);


          var hashedText = $filter('hashtag')(carriageReturnText);

          var paddedVal = '<span>' + $sce.getTrustedHtml(hashedText) + '</span>'

          iElement.html($compile(paddedVal)(scope));
        });
      }
    }
}]).

directive('dotdotdot', ['$timeout', function($timeout) {
  return {
    link: function linkDotDotDot(scope, element) {
      scope.$watch(function() {
        element.dotdotdot({watch: true});
      });
    }
  };
}]).

directive('backImg', [function() {
  function link(scope, element, attrs) {
    scope.$watch(attrs.backImg, function(value) {
      if (!value) return;
      var url = value;
      element.css({
        'background-image': 'url(' + url +')'
      });
    });
  }

{'fraction_non_alphanumeric': 0.1572458468289625, 'fraction_numerical': 0.0034479155783094764, 'mean_word_length': 2.323611111111111, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6056459', 'n_tokens_mistral': 2746, 'n_tokens_neox': 2703, 'n_words': 629}