Implement 'gr-avatar' without extending 'img'

Extending 'img' does not work with shadow DOM.

Change-Id: I2844a0c43e262bca8fdd7482f8f1d0abf718197b
This commit is contained in:
Urs Wolfer
2016-01-12 20:36:49 +01:00
committed by Dave Borowitz
parent e9e684a26a
commit 3d67c92e65
4 changed files with 26 additions and 24 deletions

View File

@@ -30,7 +30,7 @@ limitations under the License.
a:hover span { a:hover span {
text-decoration: underline; text-decoration: underline;
} }
img { gr-avatar {
height: 1.3em; height: 1.3em;
width: 1.3em; width: 1.3em;
vertical-align: -.3em; vertical-align: -.3em;
@@ -39,7 +39,8 @@ limitations under the License.
<span> <span>
<a href$="[[_computeOwnerLink(account)]]" <a href$="[[_computeOwnerLink(account)]]"
title$="[[_computeAccountTitle(account)]]"> title$="[[_computeAccountTitle(account)]]">
<img is="gr-avatar" account="[[account]]" size="[[avatarSize]]"> <gr-avatar account="[[account]]"
image-size="[[avatarImageSize]]"></gr-avatar>
<span>[[account.name]]</span> <span>[[account.name]]</span>
<span hidden$="[[!_computeShowEmail(showEmail, account)]]"> <span hidden$="[[!_computeShowEmail(showEmail, account)]]">
(<span>[[account.email]]</span>) (<span>[[account.email]]</span>)
@@ -56,7 +57,7 @@ limitations under the License.
properties: { properties: {
account: Object, account: Object,
avatarSize: { avatarImageSize: {
type: Number, type: Number,
value: 32, value: 32,
}, },

View File

@@ -20,7 +20,9 @@ limitations under the License.
<template> <template>
<style> <style>
:host { :host {
display: inline-block;
border-radius: 50%; border-radius: 50%;
background-size: cover;
} }
</style> </style>
</template> </template>
@@ -31,14 +33,12 @@ limitations under the License.
Polymer({ Polymer({
is: 'gr-avatar', is: 'gr-avatar',
extends: 'img',
properties: { properties: {
account: { account: {
type: Object, type: Object,
observer: '_accountChanged', observer: '_accountChanged',
}, },
size: { imageSize: {
type: Number, type: Number,
value: 16, value: 16,
}, },
@@ -50,27 +50,30 @@ limitations under the License.
ready: function() { ready: function() {
app.configReady.then(function(cfg) { app.configReady.then(function(cfg) {
var showAvatar = !!(cfg && cfg.plugin && cfg.plugin.has_avatars); var hasAvatars = !!(cfg && cfg.plugin && cfg.plugin.has_avatars);
if (showAvatar) { if (hasAvatars) {
this.hidden = false; this.hidden = false;
this.updateAvatarSrc(this.account); // src needs to be set if avatar becomes visible this._updateAvatarURL(this.account); // src needs to be set if avatar becomes visible
} }
}.bind(this)); }.bind(this));
}, },
_accountChanged: function(account) { _accountChanged: function(account) {
this.updateAvatarSrc(account); this._updateAvatarURL(account);
}, },
updateAvatarSrc: function(account) { _updateAvatarURL: function(account) {
if (!this.hidden && account) { if (!this.hidden && account) {
this.setAttribute('src', this._buildAvatarURL(account)); var url = this._buildAvatarURL(this.account);
if (url) {
this.style.backgroundImage = 'url("' + url + '")';
}
} }
}, },
_buildAvatarURL: function(account) { _buildAvatarURL: function(account) {
if (!account) { return ''; } if (!account) { return ''; }
return '/accounts/' + account._account_id + '/avatar?s=' + this.size; return '/accounts/' + account._account_id + '/avatar?s=' + this.imageSize;
}, },
}); });

View File

@@ -30,7 +30,7 @@ limitations under the License.
:host(:not([expanded])) { :host(:not([expanded])) {
cursor: pointer; cursor: pointer;
} }
[is="gr-avatar"] { gr-avatar {
position: absolute; position: absolute;
left: var(--default-horizontal-margin); left: var(--default-horizontal-margin);
} }
@@ -53,12 +53,12 @@ limitations under the License.
margin-left: 0; margin-left: 0;
padding: 10px 75px 10px 0; padding: 10px 75px 10px 0;
} }
.collapsed [is="gr-avatar"] { .collapsed gr-avatar {
top: 8px; top: 8px;
height: 1.75em; height: 1.75em;
width: 1.75em; width: 1.75em;
} }
.expanded [is="gr-avatar"] { .expanded gr-avatar {
top: 12px; top: 12px;
height: 2.5em; height: 2.5em;
width: 2.5em; width: 2.5em;
@@ -92,7 +92,7 @@ limitations under the License.
} }
</style> </style>
<div class$="[[_computeClass(expanded, showAvatar)]]"> <div class$="[[_computeClass(expanded, showAvatar)]]">
<img is="gr-avatar" account="[[message.author]]" size="100"> <gr-avatar account="[[message.author]]" image-size="100"></gr-avatar>
<div class="contentContainer"> <div class="contentContainer">
<div class="name" id="name">[[message.author.name]]</div> <div class="name" id="name">[[message.author.name]]</div>
<div class="content"> <div class="content">

View File

@@ -26,7 +26,7 @@ limitations under the License.
<test-fixture id="basic"> <test-fixture id="basic">
<template> <template>
<img is="gr-avatar"> <gr-avatar></gr-avatar>
</template> </template>
</test-fixture> </test-fixture>
@@ -49,20 +49,18 @@ limitations under the License.
test('dom for existing account', function() { test('dom for existing account', function() {
assert.isTrue(element.hasAttribute('hidden'), 'element not hidden initially'); assert.isTrue(element.hasAttribute('hidden'), 'element not hidden initially');
element.hidden = false; element.hidden = false;
assert.isFalse(element.hasAttribute('hidden'), 'element hidden'); element.imageSize = 64;
element.size = 64;
element.account = { element.account = {
_account_id: 123 _account_id: 123
}; };
assert.isFalse(element.hasAttribute('hidden'), 'element hidden');
assert.equal(element.getAttribute('src'), '/accounts/123/avatar?s=64'); assert.isTrue(element.style.backgroundImage.indexOf('/accounts/123/avatar?s=64') > -1);
}); });
test('dom for non available account', function() { test('dom for non available account', function() {
assert.isTrue(element.hasAttribute('hidden'), 'element not hidden initially'); assert.isTrue(element.hasAttribute('hidden'), 'element not hidden initially');
element.account = undefined; element.account = undefined;
assert.isFalse(element.hasAttribute('src'), 'src not set'); assert.isTrue(element.hasAttribute('hidden'), 'element not hidden');
}); });
}); });