diff --git a/h/features.py b/h/features.py index 45f634fa274..8148fef04a4 100644 --- a/h/features.py +++ b/h/features.py @@ -14,6 +14,7 @@ 'streamer': "Enable 'live streaming' for annotations via the websocket?", 'search_normalized': "Assume all data has normalized URI fields?", 'show_unanchored_annotations': "Show annotations that fail to anchor?", + 'truncate_annotations': "Truncate long quotes and bodies in annotations?", } diff --git a/h/static/scripts/app.coffee b/h/static/scripts/app.coffee index d62b960127c..1b093e918dc 100644 --- a/h/static/scripts/app.coffee +++ b/h/static/scripts/app.coffee @@ -105,6 +105,7 @@ module.exports = angular.module('h', [ .directive('annotation', require('./directive/annotation')) .directive('deepCount', require('./directive/deep-count')) +.directive('excerpt', require('./directive/excerpt')) .directive('formInput', require('./directive/form-input')) .directive('formValidate', require('./directive/form-validate')) .directive('groupList', require('./directive/group-list').directive) diff --git a/h/static/scripts/directive/annotation.coffee b/h/static/scripts/directive/annotation.coffee index d5690fb1c37..0ecbdb56354 100644 --- a/h/static/scripts/directive/annotation.coffee +++ b/h/static/scripts/directive/annotation.coffee @@ -405,8 +405,8 @@ AnnotationController = [ # ### module.exports = [ - '$document', - ($document) -> + '$document', 'features' + ($document, features) -> linkFn = (scope, elem, attrs, [ctrl, thread, threadFilter, counter]) -> # Observe the isSidebar attribute attrs.$observe 'isSidebar', (value) -> @@ -419,6 +419,9 @@ module.exports = [ scope.$evalAsync -> ctrl.save() + # Give template access to feature flags + scope.feature = features.flagEnabled + scope.share = (event) -> $container = angular.element(event.currentTarget).parent() $container.addClass('open').find('input').focus().select() diff --git a/h/static/scripts/directive/excerpt.js b/h/static/scripts/directive/excerpt.js new file mode 100644 index 00000000000..e3bd8bed815 --- /dev/null +++ b/h/static/scripts/directive/excerpt.js @@ -0,0 +1,60 @@ +'use strict'; + +/** + * @ngdoc directive + * @name excerpt + * @restrict E + * @description This directive truncates its contents to a height specified in + * CSS, and provides controls for expanding and collapsing the + * resulting truncated element. For example, with the following + * template HTML: + * + *
+ * + *
+ *
+ *
+ * + * You would need to define the allowable height of the excerpt in + * CSS: + * + * article.post .excerpt { + * max-height: 10em; + * } + * + * And the excerpt directive will take care of the rest. + * + * You can selectively disable truncation by providing a boolean + * expression to the `enabled` parameter, e.g.: + * + * ... + */ +module.exports = function () { + return { + link: function (scope, elem, attr, ctrl) { + scope.collapsed = true; + + if (typeof scope.enabled === 'undefined') { + scope.enabled = function () { return true; }; + } + + scope.isOverflowing = function () { + var excerpt = elem[0].querySelector('.excerpt'); + if (!excerpt) { + return false; + } + return (excerpt.scrollHeight > excerpt.clientHeight); + }; + + scope.toggle = function () { + scope.collapsed = !scope.collapsed; + }; + }, + scope: { + enabled: '&?', + }, + restrict: 'E', + transclude: true, + templateUrl: 'excerpt.html', + }; +}; diff --git a/h/static/styles/annotations.scss b/h/static/styles/annotations.scss index 01959125871..4bff421a7bb 100644 --- a/h/static/styles/annotations.scss +++ b/h/static/styles/annotations.scss @@ -37,6 +37,26 @@ .annotation-header { margin-top: 0 } .annotation-footer { margin-bottom: 0 } +.annotation-section { + .excerpt { max-height: 4.8em; } + .excerpt-control a { + font-style: italic; + font-family: $serif-font-family; + font-weight: normal; + } + .excerpt--collapsed:after { + height: $base-line-height; + @include background(linear-gradient(to right, + rgba(255,255,255,0) 20%, + rgba(255,255,255,1) 100% + )); + } +} + +.annotation-body { + .excerpt { max-height: 16.2em; } +} + .annotation-user { color: $text-color; font-weight: bold; diff --git a/h/static/styles/common.scss b/h/static/styles/common.scss index 5f604dd8302..797df8ea00c 100644 --- a/h/static/styles/common.scss +++ b/h/static/styles/common.scss @@ -5,6 +5,7 @@ @import 'mixins/responsive'; @import 'grid'; @import 'annotations'; +@import 'excerpt'; @import 'forms'; @import 'markdown-editor'; @import 'spinner'; diff --git a/h/static/styles/excerpt.scss b/h/static/styles/excerpt.scss new file mode 100644 index 00000000000..aa3069b1b4d --- /dev/null +++ b/h/static/styles/excerpt.scss @@ -0,0 +1,31 @@ +@import "compass/css3/images"; +@import "variables"; + +.excerpt { + position: relative; + overflow: hidden; +} + +.excerpt--collapsed:after { + position: absolute; + bottom: 0; + height: $base-line-height * 3; // This controls the apparent height of the gradient. + width: 100%; + content: ""; + pointer-events: none; + @include background(linear-gradient(to bottom, + rgba(255,255,255,0) 20%, + rgba(255,255,255,1) 100% + )); +} + +.excerpt--uncollapsed { + max-height: 100% !important; +} + +.excerpt-control a { + display: block; + text-align: right; + font-weight: bold; + width: 100%; +} diff --git a/h/templates/app.html.jinja2 b/h/templates/app.html.jinja2 index c9703f95d5f..63dd6420054 100644 --- a/h/templates/app.html.jinja2 +++ b/h/templates/app.html.jinja2 @@ -93,6 +93,9 @@ + diff --git a/h/templates/client/annotation.html b/h/templates/client/annotation.html index 2c2137f8988..4ecbf59ba33 100644 --- a/h/templates/client/annotation.html +++ b/h/templates/client/annotation.html @@ -56,12 +56,14 @@
-
+ +
+
@@ -76,11 +78,12 @@ -
+ +
+
diff --git a/h/templates/client/excerpt.html b/h/templates/client/excerpt.html new file mode 100644 index 00000000000..f491dacd902 --- /dev/null +++ b/h/templates/client/excerpt.html @@ -0,0 +1,18 @@ +
+
+
+ +
+ More + Less +
+