pc035860 / angular-highlightjs

AngularJS directive for syntax highlighting with highlight.js
http://pc035860.github.io/angular-highlightjs/example/
MIT License
294 stars 53 forks source link

Showing "loading" message #77

Open grtjn opened 8 years ago

grtjn commented 8 years ago

I am using hljs-include to pull in code from back-end, which takes half a second. Enough for end-users to notice. I also noticed that hljs initially shows the contents of the directive before replacing it with the result from the include. So I added a "loading.." message in there. Next thought was to add a spinner, something like:

<hljs hljs-include="uri">loading.. <i class="fa fa-spinner fa-spin"></i></hljs>

Unfortunately, the i tag gets escaped, and shown as is. If I add hljs-no-escape, it gets stripped away. Would be fun if I could show a loading message with a spinner somehow. Is that possible with current hljs?

pc035860 commented 8 years ago

hljs-include uses $templateCache (same as ng-include) internally. Which means actually you can handle the code loading request your self, and you can write a new directive for displaying "loading" message.

$scope.loaded = !!$templateCache.get(uri);

if (!$scope.loaded) {
    loadTheUri(uri).then(function (result) {
        $templateCache.put(uri, result);
        $scope.loaded = true;
    });
}
<div>
    <div ng-if="!loaded">
        loading... <i class="fa fa-spinner fa-spin"></i>
    </div>
    <div ng-if="loaded">
        <div hljs hljs-include="uri"></div>
    </div>
</div>
grtjn commented 8 years ago

Interesting, let me experiment with this..

grtjn commented 8 years ago

I created this helper function, and pointed hljs to hljsUri:

    ctrl.loadHljs = function(uri) {
      $scope.loadingHljs = !$templateCache.get(uri);

      if ($scope.loadingHljs) {
        $http.get(uri, {
          cache: $templateCache,
          transformResponse: function(data, headersGetter) {
            // Return the raw string, so $http doesn't parse it
            // if it's json.
            return data;
          }
        }).then(function (result) {
          $scope.loadingHljs = false;
          $scope.hljsUri = uri;
        });
      } else {
        $scope.hljsUri = uri;
      }
    };

I still notice a lag, though. It seems likes hljs needs time to process and paint the source? That would not be a surprise, but the loading message disappears once the cache is loaded, the background of hljs appears, though empty, and a few tenth of a second later, the source is shown. I guess that if this would be added as a feature in hljs, it would be possible to show the loading message longer. It would also require less mess..

Thanks for the suggestion though, I'll use it for the time being!

ghost commented 7 years ago

Maybe the #73 issue would help your case too @grtjn ?