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
Dynamic Syntax Highlighting with AngularJS and Highlight.js
提问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 注入。我正在使用AngularJS和highlight.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,在您的情况下,它基本上是:
- Fetches the template you have provided with
include
directive applies - Invokes highlightjslibrary API on the templatewhich produces HTML markup with highlighted elements having correct style for particular language
- The highlighted HTML markupis then passed over to angularjs
$compile
- 获取您提供的模板应用
include
指令 - 在模板上调用highlightjs库 API,该 API生成 HTML 标记,其中突出显示的元素具有特定语言的正确样式
- 然后将突出显示的 HTML 标记传递给 angularjs
$compile
Afterwards no highglighting takes place - in particular even when interpolated content changes.
之后不会发生高亮显示 - 特别是即使插入的内容发生变化。
One way to solve it is to use source
directive from angular-highlightjs
which 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 highlight
directive 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 - 您信任它。