Actually scroll lint panels into view

The trick to writing horrible hacks such as this is to recognize angular
as a technology stack that may be endearing to some as one can do easy
stuff quickly. But fundamentally, it is built on top of crazy shit.

Like: Yes, I just wrote a directive that for some reason automatically
has access to the scope of the repeated item, and fires an event each
time the last `np-repeat` item was seen (delayed by one render loop
cycle, of course). And – obviously – when defining the directive it is
in camelCase  but when using it in the template it has to by in
dash-case.

Great times.
This commit is contained in:
Pascal Hertleif 2016-08-28 21:08:14 +02:00
parent 816cf56b89
commit 3e2bb3fd81

View file

@ -62,7 +62,8 @@
</div>
</div>
<article class="panel panel-default" id="{{lint.id}}" ng-repeat="lint in data | filter:byLevels | filter:search | orderBy:'id' track by lint.id">
<article class="panel panel-default" id="{{lint.id}}"
ng-repeat="lint in data | filter:byLevels | filter:search | orderBy:'id' track by lint.id" on-finish-render="ngRepeatFinished">
<header class="panel-heading" ng-click="open[lint.id] = !open[lint.id]">
<button class="btn btn-default btn-sm pull-right" style="margin-top: -6px;">
<span ng-show="open[lint.id]">&minus;</span>
@ -96,7 +97,7 @@
<a href="https://github.com/Manishearth/rust-clippy">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"/>
</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/7.0.0/markdown-it.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.5.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.5.0/languages/rust.min.js"></script>
@ -122,8 +123,17 @@
function scrollToLint(lintId) {
var target = document.getElementById(lintId);
if (!target) { return; }
document.body.scrollTop = target.offsetTop;
if (!target) {
return;
}
target.scrollIntoView();
}
function scrollToLintByURL($scope) {
var removeListener = $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
scrollToLint(window.location.hash.slice(1));
removeListener();
});
}
angular.module("clippy", [])
@ -136,6 +146,18 @@
);
};
})
.directive('onFinishRender', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit(attr.onFinishRender);
});
}
}
};
})
.controller("lintList", function ($scope, $http, $timeout) {
// Level filter
var LEVEL_FILTERS_DEFAULT = {Allow: true, Warn: true, Deny: true, Deprecated: true};
@ -149,7 +171,9 @@
$scope.loading = true;
if (window.location.hash.length > 1) {
$scope.search = window.location.hash.slice(1);
$scope.open[window.location.hash.slice(1)] = true;
scrollToLintByURL($scope);
}
$http.get('./lints.json')
@ -157,9 +181,7 @@
$scope.data = data;
$scope.loading = false;
$timeout(function () {
scrollToLint(window.location.hash.slice(1));
}, 100);
scrollToLintByURL($scope);
})
.error(function (data) {
$scope.error = data;
@ -169,12 +191,11 @@
window.addEventListener('hashchange', function () {
// trigger re-render
$timeout(function () {
$scope.search = "";
$scope.levels = LEVEL_FILTERS_DEFAULT;
// quick n dirty: wait for re-render to finish
$timeout(function () {
scrollToLint(window.location.hash.slice(1));
}, 100);
$scope.search = window.location.hash.slice(1);
$scope.open[window.location.hash.slice(1)] = true;
scrollToLintByURL($scope);
});
return true;
}, false);
@ -182,4 +203,4 @@
})();
</script>
</body>
</html>
</html>