javascript 使用 AngularJS 和 Highlight.js 动态语法高亮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25581560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 04:41:31  来源:igfitidea点击:

Dynamic Syntax Highlighting with AngularJS and Highlight.js

javascriptangularjssyntax-highlighting

提问by Mark Good

I am building a site that illustrates common application vulnerabilities such as SQL Injection. I am using AngularJSand highlight.jsto create interactive examples.

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

How can I make both AngularJS and highlight.js update my code snippets?

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

Example

例子

This Fiddledemonstrates how entering ' OR 1=1 --in the Email field could change the intended behavior of the query if the user's input is not validated or sanitized.

这个小提琴演示了' OR 1=1 --如果用户的输入没有被验证或清理,在电子邮件字段中输入如何改变查询的预期行为。

SELECT * FROM dbo.Users WHERE Email='{{email}}' AND Password='{{password}}'  

When a user enters an email address and password, Angular updates the query. However, syntax highlighting does not update.

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

SELECT * FROM dbo.Users WHERE Email='[email protected]' AND Password=''

I tried re-initializing hljs, but when I do angular stops updating the query.

我尝试重新初始化 hljs,但是当我执行 angular 时,会停止更新查询。

hljs.initHighlighting.called = false;
hljs.initHighlighting();

Application

应用

<script>
    var app = angular.module("app", ['hljs']);
    app.controller("controller", function($scope) {
        $scope.email = "[email protected]";
        $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>

采纳答案by miensol

In the jsfiddle you have provided you're using angular-highlightjswhich in your case basically:

在您提供的 jsfiddle 中,您使用的是angular-highlightjs,在您的情况下,它基本上是:

  1. Fetches the template you have provided with includedirective applies
  2. Invokes highlightjslibrary API on the templatewhich produces HTML markup with highlighted elements having correct style for particular language
  3. The highlighted HTML markupis then passed over to angularjs $compile
  1. 获取您提供的模板应用include指令
  2. 模板上调用highlightjs库 API,该 API生成 HTML 标记,其中突出显示的元素具有特定语言的正确样式
  3. 然后将突出显示的 HTML 标记传递给 angularjs$compile

Afterwards no highglighting takes place - in particular even when interpolated content changes.

之后不会发生高亮显示 - 特别是即使插入的内容发生变化。

One way to solve it is to use sourcedirective from angular-highlightjswhich is observed but I think it's simpler to build a custom directive.

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

The trick here is to manually interpolate and highlight content. I've updated your fiddlewith a simplistic highlightdirective that presents the idea:

这里的技巧是手动插入和突出显示内容。我已经用一个简单的指令更新了你的小提琴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);
        });
      }
    }
  };
});

回答by Upayavira

A simpler way I just found is to use a filter:

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

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; })

Then you can say:

然后你可以说:

<pre><code ng-bind-html="someScopeVariable | highlight | unsafe"></code></pre>

The $sce needs to be injected into your app, and tells Angular to display the HTML raw - that you trust it.

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