1 /*! angular-highlightjs
5 https://github.com/pc035860/angular-highlightjs.git */
7 /* commonjs package manager support (eg componentjs) */
8 if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){
9 module.exports = 'hljs';
12 (function (window, angular, undefined) {
15 function shouldHighlightStatics(attrs) {
28 var ngModule = angular.module('hljs', []);
33 ngModule.provider('hljsService', function () {
34 var _hljsOptions = {};
37 setOptions: function (options) {
38 angular.extend(_hljsOptions, options);
40 getOptions: function () {
41 return angular.copy(_hljsOptions);
43 $get: ['$window', function ($window) {
44 ($window.hljs.configure || angular.noop)(_hljsOptions);
53 ngModule.factory('hljsCache', [
55 function ($cacheFactory) {
56 return $cacheFactory('hljsCache');
62 ngModule.controller('HljsCtrl', [
63 'hljsCache', 'hljsService',
64 function HljsCtrl (hljsCache, hljsService) {
72 ctrl.init = function (codeElm) {
76 ctrl.setLanguage = function (lang) {
80 ctrl.highlight(_code);
84 ctrl.highlightCallback = function (cb) {
88 ctrl.highlight = function (code) {
99 cacheKey = ctrl._cacheKey(_lang, _code);
100 res = hljsCache.get(cacheKey);
103 res = hljsService.highlight(_lang, hljsService.fixMarkup(_code), true);
104 hljsCache.put(cacheKey, res);
108 // language auto-detect
109 cacheKey = ctrl._cacheKey(_code);
110 res = hljsCache.get(cacheKey);
113 res = hljsService.highlightAuto(hljsService.fixMarkup(_code));
114 hljsCache.put(cacheKey, res);
118 _elm.html(res.value);
119 // language as class on the <code> tag
120 _elm.addClass(res.language);
122 if (_hlCb !== null && angular.isFunction(_hlCb)) {
127 ctrl.clear = function () {
135 ctrl.release = function () {
139 ctrl._cacheKey = function () {
140 var args = Array.prototype.slice.call(arguments),
141 glue = "!angular-highlightjs!";
142 return args.join(glue);
147 var hljsDir, languageDirFactory, sourceDirFactory, includeDirFactory;
152 hljsDir = ['$compile', '$parse', function ($compile, $parse) {
155 controller: 'HljsCtrl',
156 compile: function(tElm, tAttrs, transclude) {
158 // strip the starting "new line" character
159 var staticHTML = tElm[0].innerHTML.replace(/^(\r\n|\r|\n)/m, ''),
160 staticText = tElm[0].textContent.replace(/^(\r\n|\r|\n)/m, '');
163 tElm.html('<pre><code class="hljs"></code></pre>');
165 return function postLink(scope, iElm, iAttrs, ctrl) {
166 var compileCheck, escapeCheck;
168 if (angular.isDefined(iAttrs.compile)) {
169 compileCheck = $parse(iAttrs.compile);
172 if (angular.isDefined(iAttrs.escape)) {
173 escapeCheck = $parse(iAttrs.escape);
174 } else if (angular.isDefined(iAttrs.noEscape)) {
175 escapeCheck = $parse('false');
178 ctrl.init(iElm.find('code'));
180 if (iAttrs.onhighlight) {
181 ctrl.highlightCallback(function () {
182 scope.$eval(iAttrs.onhighlight);
186 if ((staticHTML || staticText) && shouldHighlightStatics(iAttrs)) {
192 if (escapeCheck && !escapeCheck(scope)) {
199 ctrl.highlight(code);
201 // Check if the highlight result needs to be compiled
202 if (compileCheck && compileCheck(scope)) {
203 // compile the new DOM and link it to the current scope.
204 // NOTE: we only compile .childNodes so that
205 // we don't get into infinite loop compiling ourselves
206 $compile(iElm.find('code').contents())(scope);
210 scope.$on('$destroy', function () {
221 languageDirFactory = function (dirName) {
222 return [function () {
226 link: function (scope, iElm, iAttrs, ctrl) {
230 iAttrs.$observe(dirName, function (lang) {
231 if (angular.isDefined(lang)) {
232 ctrl.setLanguage(lang);
243 sourceDirFactory = function (dirName) {
244 return ['$compile', '$parse', function ($compile, $parse) {
248 link: function(scope, iElm, iAttrs, ctrl) {
255 if (angular.isDefined(iAttrs.compile)) {
256 compileCheck = $parse(iAttrs.compile);
259 scope.$watch(iAttrs[dirName], function (newCode, oldCode) {
261 ctrl.highlight(newCode);
263 // Check if the highlight result needs to be compiled
264 if (compileCheck && compileCheck(scope)) {
265 // compile the new DOM and link it to the current scope.
266 // NOTE: we only compile .childNodes so that
267 // we don't get into infinite loop compiling ourselves
268 $compile(iElm.find('code').contents())(scope);
283 includeDirFactory = function (dirName) {
285 '$http', '$templateCache', '$q', '$compile', '$parse',
286 function ($http, $templateCache, $q, $compile, $parse) {
290 compile: function(tElm, tAttrs, transclude) {
291 var srcExpr = tAttrs[dirName];
293 return function postLink(scope, iElm, iAttrs, ctrl) {
294 var changeCounter = 0, compileCheck;
300 if (angular.isDefined(iAttrs.compile)) {
301 compileCheck = $parse(iAttrs.compile);
304 scope.$watch(srcExpr, function (src) {
305 var thisChangeId = ++changeCounter;
307 if (src && angular.isString(src)) {
308 var templateCachePromise, dfd;
310 templateCachePromise = $templateCache.get(src);
311 if (!templateCachePromise) {
314 cache: $templateCache,
315 transformResponse: function(data, headersGetter) {
316 // Return the raw string, so $http doesn't parse it
320 }).success(function (code) {
321 if (thisChangeId !== changeCounter) {
325 }).error(function() {
326 if (thisChangeId === changeCounter) {
331 templateCachePromise = dfd.promise;
334 $q.when(templateCachePromise)
335 .then(function (code) {
340 // $templateCache from $http
341 if (angular.isArray(code)) {
345 else if (angular.isObject(code)) {
350 code = code.replace(/^(\r\n|\r|\n)/m, '');
351 ctrl.highlight(code);
353 // Check if the highlight result needs to be compiled
354 if (compileCheck && compileCheck(scope)) {
355 // compile the new DOM and link it to the current scope.
356 // NOTE: we only compile .childNodes so that
357 // we don't get into infinite loop compiling ourselves
358 $compile(iElm.find('code').contents())(scope);
376 .directive('hljs', hljsDir)
377 .directive('language', languageDirFactory('language'))
378 .directive('source', sourceDirFactory('source'))
379 .directive('include', includeDirFactory('include'));
380 })(window, window.angular);