使用AngularJS和Highlight.js进行动态语法突出显示

Mar*_*ood 9 javascript syntax-highlighting angularjs

我正在构建一个站点,说明常见的应用程序漏洞,如SQL注入.我正在使用AngularJShighlight.js来创建交互式示例.

如何让AngularJS和highlight.js更新我的代码片段?

此Fiddle演示了' OR 1=1 --如果未验证或清理用户的输入,如何在"电子邮件"字段中输入可能会更改查询的预期行为.

SELECT * FROM dbo.Users WHERE Email='{{email}}' AND Password='{{password}}'  
Run Code Online (Sandbox Code Playgroud)

当用户输入电子邮件地址和密码时,Angular会更新查询.但是,语法突出显示不会更新.

SELECT * FROM dbo.Users WHERE Email='user@domain.com' AND Password=''
Run Code Online (Sandbox Code Playgroud)

我尝试重新初始化hljs,但是当我做角度停止更新查询时.

hljs.initHighlighting.called = false;
hljs.initHighlighting();
Run Code Online (Sandbox Code Playgroud)

应用

<script>
    var app = angular.module("app", ['hljs']);
    app.controller("controller", function($scope) {
        $scope.email = "user@domain.com";
        $scope.password = "";
    })
</script>
<div ng-app="app" ng-controller="controller">
    <div>
        <div class="row">
            <div class="col-sm-4">Email
                <input type="text" class="form-control" ng-model="email">
            </div>
            <div class="col-sm-4">Password
                <input type="text" class="form-control" ng-model="password">
            </div>
        </div>
        <br>
        <div hljs include="'compile-me'" compile="true" language="sql"></div>
    </div>
    <script type="text/ng-template" id="compile-me">
        SELECT * FROM dbo.Users WHERE Email = '{{email}}'
        AND Password = '{{password}}'
    </script>
</div>
Run Code Online (Sandbox Code Playgroud)

mie*_*sol 8

在jsfiddle中,你提供了使用angular-highlightjs,在你的情况下基本上:

  1. 获取include指令适用的模板
  2. 模板上调用highlightjs库API,该API 生成HTML标记,突出显示的元素具有特定语言的正确样式
  3. 强调的HTML标记,然后传递到angularjs$compile

之后不会发生高亮 - 特别是即使内插内容发生变化也是如此.

解决它的一种方法是使用source指令从中angular-highlightjs观察,但我认为构建自定义指令更简单.

这里的技巧是手动插入和突出显示内容.我用简单的指令更新了你的小提琴highlight,提出了这个想法:

app.directive('highlight', function($interpolate, $window){
    return {
    restrict: 'EA',
    scope: true,
    compile: function (tElem, tAttrs) {
      var interpolateFn = $interpolate(tElem.html(), true);
      tElem.html(''); // stop automatic intepolation

      return function(scope, elem, attrs){
        scope.$watch(interpolateFn, function (value) {
          elem.html(hljs.highlight('sql',value).value);
        });
      }
    }
  };
});
Run Code Online (Sandbox Code Playgroud)


小智 8

我刚发现的一种更简单的方法是使用过滤器:

app.filter('highlight', function($sce) {
  return function(input, lang) {
    if (lang && input) return hljs.highlight(lang, input).value;
    return input;
  }
}).filter('unsafe', function($sce) { return $sce.trustAsHtml; })
Run Code Online (Sandbox Code Playgroud)

然后你可以说:

<pre><code ng-bind-html="someScopeVariable | highlight | unsafe"></code></pre>
Run Code Online (Sandbox Code Playgroud)

$ sce需要注入您的应用程序,并告诉Angular显示HTML raw - 您信任它.