Set a maximum length on topic display

This change introduces the gr-limited-text element, which, given a
string of text and a numeric limit, will display the text up to that
limit. If the length of the text exceeds that limit, an ellipsis is
added to indicate the truncation and a tooltip is enabled to display the
full string.

Displaying the topic string is limited to a reasonable number of
characters in this way in both the change metadata and the change list.

Bug: Issue 7197
Change-Id: If826fc2f2657e8ed12275e65f25f2d40c3180838
This commit is contained in:
Wyatt Allen
2017-09-18 17:57:20 -07:00
parent 9023bae37a
commit 8553bf460e
8 changed files with 193 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ limitations under the License.
<link rel="import" href="../../shared/gr-account-link/gr-account-link.html">
<link rel="import" href="../../shared/gr-change-star/gr-change-star.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
<link rel="import" href="../../shared/gr-limited-text/gr-limited-text.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-change-list-item">
@@ -146,7 +147,10 @@ limitations under the License.
[[change.branch]]
</a>
<template is="dom-if" if="[[change.topic]]">
(<a href$="[[_computeTopicURL(change)]]">[[change.topic]]</a>)
(<a href$="[[_computeTopicURL(change)]]"><!--
--><gr-limited-text limit="30" text="[[change.topic]]">
</gr-limited-text><!--
--></a>)
</template>
</td>
<td class="cell updated"

View File

@@ -215,6 +215,7 @@ limitations under the License.
<template is="dom-if" if="[[change.topic]]">
<gr-linked-chip
text="[[change.topic]]"
limit="40"
href="[[_computeTopicURL(change.topic)]]"
removable="[[!_topicReadOnly]]"
on-remove="_handleTopicRemoved"></gr-linked-chip>

View File

@@ -0,0 +1,23 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<dom-module id="gr-limited-text">
<template>[[_computeDisplayText(text, limit)]]</template>
<script src="gr-limited-text.js"></script>
</dom-module>

View File

@@ -0,0 +1,69 @@
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function() {
'use strict';
/*
* The gr-limited-text element is for displaying text with a maximum length
* (in number of characters) to display. If the length of the text exceeds the
* configured limit, then an ellipsis indicates that the text was truncated
* and a tooltip containing the full text is enabled.
*/
Polymer({
is: 'gr-limited-text',
properties: {
/** The un-truncated text to display. */
text: String,
/** The maximum length for the text to display before truncating. */
limit: Number,
/** Boolean property used by Gerrit.TooltipBehavior. */
hasTooltip: {
type: Boolean,
value: false,
},
},
observers: [
'_updateTitle(text, limit)',
],
behaviors: [
Gerrit.TooltipBehavior,
],
/**
* The text or limit have changed. Recompute whether a tooltip needs to be
* enabled.
*/
_updateTitle(text, limit) {
this.hasTooltip = text.length > limit;
if (this.hasTooltip) {
this.setAttribute('title', text);
} else {
this.removeAttribute('title');
}
},
_computeDisplayText(text, limit) {
if (text.length > limit) {
return text.substr(0, limit - 1) + '…';
}
return text;
},
});
})();

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-limited-text</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-limited-text.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-limited-text></gr-limited-text>
</template>
</test-fixture>
<script>
suite('gr-limited-text tests', () => {
let element;
let sandbox;
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('_updateTitle', () => {
const updateSpy = sandbox.spy(element, '_updateTitle');
element.text = 'abc 123';
flushAsynchronousOperations();
assert.isFalse(updateSpy.called);
assert.isNotOk(element.getAttribute('title'));
assert.isFalse(element.hasTooltip);
element.limit = 10;
flushAsynchronousOperations();
assert.isTrue(updateSpy.calledOnce);
assert.isNotOk(element.getAttribute('title'));
assert.isFalse(element.hasTooltip);
element.limit = 3;
flushAsynchronousOperations();
assert.isTrue(updateSpy.calledTwice);
assert.equal(element.getAttribute('title'), 'abc 123');
assert.isTrue(element.hasTooltip);
element.limit = 100;
flushAsynchronousOperations();
assert.isTrue(updateSpy.calledThrice);
assert.isNotOk(element.getAttribute('title'));
assert.isFalse(element.hasTooltip);
});
test('_computeDisplayText', () => {
assert.equal(element._computeDisplayText('foo bar', 100), 'foo bar');
assert.equal(element._computeDisplayText('foo bar', 4), 'foo…');
});
});
</script>

View File

@@ -15,7 +15,9 @@ limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../gr-limited-text/gr-limited-text.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-linked-chip">
@@ -61,7 +63,14 @@ limitations under the License.
}
</style>
<div class$="container [[_getBackgroundClass(transparentBackground)]]">
<a href$="[[href]]">[[text]]</a>
<template is="dom-if" if="[[limit]]">
<a href$="[[href]]">
<gr-limited-text limit="[[limit]]" text="[[text]]"></gr-limited-text>
</a>
</template>
<template is="dom-if" if="[[!limit]]">
<a href$="[[href]]">[[text]]</a>
</template>
<gr-button
id="remove"
hidden$="[[!removable]]"

View File

@@ -33,6 +33,9 @@
type: Boolean,
value: false,
},
/** If provided, sets the maximum length of the content. */
limit: Number,
},
_getBackgroundClass(transparent) {

View File

@@ -136,6 +136,7 @@ limitations under the License.
'shared/gr-js-api-interface/gr-change-actions-js-api_test.html',
'shared/gr-js-api-interface/gr-change-reply-js-api_test.html',
'shared/gr-js-api-interface/gr-js-api-interface_test.html',
'shared/gr-limited-text/gr-limited-text_test.html',
'shared/gr-linked-chip/gr-linked-chip_test.html',
'shared/gr-linked-text/gr-linked-text_test.html',
'shared/gr-list-view/gr-list-view_test.html',