replaces links/imgs by buttons in the emoji-picker

This commit is contained in:
Joffrey JAFFEUX 2017-07-21 19:42:46 +02:00
parent 54e0075a3e
commit e36d9f55c3
6 changed files with 91 additions and 85 deletions

View File

@ -77,10 +77,10 @@ export default Ember.Component.extend({
selectedDiversityChanged() {
keyValueStore.setObject({key: EMOJI_SELECTED_DIVERSITY, value: this.get("selectedDiversity")});
$.each($list.find(".emoji.diversity[src!='']"), (_, icon) => this._setIconSrc(icon, true) );
$.each($list.find(".emoji.diversity"), (_, button) => this._setButtonBackground(button, true) );
if(this.get("filter") !== "") {
$.each($results.find(".emoji.diversity"), (_, icon) => this._setIconSrc(icon, true) );
$.each($results.find(".emoji.diversity"), (_, button) => this._setButtonBackground(button, true) );
}
},
@ -88,7 +88,7 @@ export default Ember.Component.extend({
recentEmojisChanged() {
const $recentSection = $list.find(".section[data-section='recent']");
const $recentSectionGroup = $recentSection.find(".section-group");
const $recentCategory = $picker.find(".category-icon a[title='recent']").parent();
const $recentCategory = $picker.find(".category-icon button[data-section='recent']").parent();
// we set height to 0 to avoid it being taken into account for scroll position
if(_.isEmpty(this.get("recentEmojis"))) {
@ -102,8 +102,7 @@ export default Ember.Component.extend({
const recentEmojis = _.map(this.get("recentEmojis"), code => {
return { code, src: emojiUrlFor(code) };
});
const model = { recentEmojis };
const template = findRawTemplate("emoji-picker-recent")(model);
const template = findRawTemplate("emoji-picker-recent")({recentEmojis});
$recentSectionGroup.html(template);
this._bindHover($recentSectionGroup);
},
@ -136,6 +135,13 @@ export default Ember.Component.extend({
this._setDiversity();
this._positionPicker();
this._scrollTo();
this._loadCategoriesEmojis();
});
},
_loadCategoriesEmojis() {
$.each($picker.find(".categories-column button.emoji"), (_, button) => {
this._setButtonBackground(button, false);
});
},
@ -188,9 +194,7 @@ export default Ember.Component.extend({
const hasDiversity = isSkinTonableEmoji(code);
const diversity = hasDiversity ? "diversity" : "";
const scaledCode = this._codeWithDiversity(code, hasDiversity);
return `<a title="${code}">
<img src="${emojiUrlFor(scaledCode)}" data-code="${code}" class="emoji ${diversity}" />
</a>`;
return `<button style="background-image: url('${emojiUrlFor(scaledCode)}')" type="button" class="emoji ${diversity}" tabindex="-1" title="${code}"></button>`;
})
).show();
this._bindHover($results);
@ -214,15 +218,14 @@ export default Ember.Component.extend({
},
_bindCategoryClick() {
$picker.find(".category-icon").on("click", "a", (event) => {
$picker.find(".category-icon").on("click", "button.emoji", (event) => {
this.set("filter", "");
$results.empty();
$list.show();
const section = $(event.currentTarget).attr("title");
const section = $(event.currentTarget).data("section");
const $section = $list.find(`.section[data-section="${section}"]`);
const scrollTop = $list.scrollTop() + ($section.offset().top - $list.offset().top);
this._scrollTo(scrollTop);
return false;
});
@ -233,12 +236,12 @@ export default Ember.Component.extend({
($hoverables || $list.find(".section-group")).on({
mouseover: (event) => {
const code = this._codeForEmojiLink($(event.currentTarget));
const code = this._codeForEmojiButton($(event.currentTarget));
const html = `<img src="${emojiUrlFor(code)}" class="emoji"> <span>:${code}:<span>`;
replaceInfoContent(html);
},
mouseleave: () => replaceInfoContent()
}, "a");
}, "button.emoji");
},
_bindResizing() {
@ -263,7 +266,7 @@ export default Ember.Component.extend({
_bindEmojiClick($emojisContainer) {
const handler = (event) => {
const code = this._codeForEmojiLink($(event.currentTarget));
const code = this._codeForEmojiButton($(event.currentTarget));
if($(event.currentTarget).parents(".section[data-section='recent']").length === 0) {
this._trackEmojiUsage(code);
@ -283,7 +286,7 @@ export default Ember.Component.extend({
$emojisContainer
.off("touchstart")
.on("touchstart", "a", (touchStartEvent) => {
.on("touchstart", "button.emoji", (touchStartEvent) => {
const $this = $(touchStartEvent.currentTarget);
$this.on("touchend", (touchEndEvent) => {
handler.bind(self)(touchEndEvent);
@ -292,7 +295,7 @@ export default Ember.Component.extend({
$this.on("touchmove", () => $this.off("touchend") );
});
} else {
$emojisContainer.off("click").on("click", "a", e => handler.bind(this)(e) );
$emojisContainer.off("click").on("click", "button.emoji", e => handler.bind(this)(e) );
}
},
@ -336,7 +339,7 @@ export default Ember.Component.extend({
if(selectedSection) {
const sectionTitle = selectedSection.$section.data("section");
$picker.find(".category-icon").removeClass("current");
$picker.find(`.category-icon a[title='${sectionTitle}']`)
$picker.find(`.category-icon button[data-section='${sectionTitle}']`)
.parent()
.addClass("current");
@ -478,7 +481,7 @@ export default Ember.Component.extend({
_loadSection($section) {
const sectionName = $section.data("section");
if(keyValueStore.getObject(EMOJI_CACHED_SECTIONS).indexOf(sectionName) > -1) {
$.each($section.find(".emoji[src='']"), (_, icon) => this._setIconSrc(icon) );
$.each($section.find(".emoji"), (_, button) => this._setButtonBackground(button) );
} else {
Ember.run.later(
this, () => {
@ -486,7 +489,7 @@ export default Ember.Component.extend({
key: EMOJI_CACHED_SECTIONS,
value: keyValueStore.getObject(EMOJI_CACHED_SECTIONS).concat(sectionName)
});
$.each($section.find(".emoji[src='']"), (_, icon) => this._setIconSrc(icon) );
$.each($section.find(".emoji"), (_, button) => this._setButtonBackground(button) );
},
1500
);
@ -528,24 +531,23 @@ export default Ember.Component.extend({
}
},
_codeForEmojiLink($a) {
const title = $a.attr("title");
const $img = $a.find("img");
return this._codeWithDiversity(title, $img.hasClass("diversity"));
_codeForEmojiButton($button) {
const title = $button.attr("title");
return this._codeWithDiversity(title, $button.hasClass("diversity"));
},
_setIconSrc(icon, diversity) {
const $icon = $(icon);
_setButtonBackground(button, diversity) {
const $button = $(button);
const code = this._codeWithDiversity(
$icon.parent().attr("title"),
diversity || $icon.hasClass("diversity")
$button.attr("title"),
diversity || $button.hasClass("diversity")
);
// force visual reloading if needed
if($icon.attr("src") !== "") {
$icon.attr("src", "");
if($button.css("background-image") !== "none") {
$button.css("background-image", "");
}
$icon.attr("src", emojiUrlFor(code));
$button.css("background-image", `url("${emojiUrlFor(code)}")`);
},
});

View File

@ -1,5 +1,3 @@
{{#each recentEmojis as |emoji|}}
<a title='{{emoji.code}}'>
<img src='{{emoji.src}}' class='emoji'>
</a>
<button style="background-image: url('{{emoji.src}}')" type="button" class="emoji" tabindex="-1" title="{{emoji.code}}"></button>
{{/each}}

View File

@ -1,23 +1,17 @@
<div class='categories-column'>
<div class='category-icon'>
<a href='#' title='recent'>
<img src='<%= Emoji.url_for("star") %>' class='emoji'>
</a>
<button type="button" class="emoji" tabindex="-1" title="star" data-section="recent"></button>
</div>
<% JSON.parse(File.read("lib/emoji/groups.json")).each.with_index do |group, group_index| %>
<div class='category-icon'>
<a href='#' title='<%= group["name"] %>'>
<img src='<%= Emoji.url_for(group["tabicon"]) %>' class='emoji'>
</a>
<button type="button" class="emoji" tabindex="-1" data-section="<%= group["name"] %>" title="<%= group["tabicon"] %>"></button>
</div>
<% end %>
<% if !Emoji.custom.blank? %>
<div class='category-icon'>
<a href='#' title='ungrouped'>
<img src='<%= Emoji.custom.first.url %>' class='emoji'>
</a>
<button data-section="ungrouped" type="button" class="emoji" tabindex="-1" title="<%= Emoji.custom.first.name %>"></button>
</div>
<% end %>
</div>
@ -49,9 +43,7 @@
</div>
<div class='section-group'>
<% group["icons"].each do |icon| %>
<a title='<%= icon["name"] %>'>
<img src='' class='emoji <%= "diversity" if icon["diversity"] %>'>
</a>
<button type="button" class="emoji <%= "diversity" if icon["diversity"] %>" tabindex="-1" title="<%= icon['name']%>"></button>
<% end %>
</div>
</div>
@ -64,9 +56,7 @@
</div>
<div class='section-group'>
{{#each customEmojis as |emoji|}}
<a title='{{emoji.code}}'>
<img src='{{emoji.src}}' class='emoji'>
</a>
<button style="background-url: url("{{emoji.src}}")" type="button" class="emoji" tabindex="-1" title="{{emoji.code}}"></button>
{{/each}}
</div>
</div>

View File

@ -1,3 +1,9 @@
body img.emoji {
width: 20px;
height: 20px;
vertical-align: middle;
}
.emoji-picker {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background-clip: padding-box;
@ -27,6 +33,11 @@
margin: 4px auto;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
button.emoji {
margin: 0;
padding: 0;
}
}
.emoji-picker .category-icon.current, .emoji-picker .category-icon:hover {
@ -48,10 +59,6 @@
flex-direction: column;
}
.emoji-picker .list .emoji {
margin: 5px;
}
.emoji-picker .section-header {
padding: 8px;
margin-bottom: 4px;
@ -84,13 +91,6 @@
padding: 4px;
}
.emoji-picker .section-group a:hover, .emoji-picker .results a:hover {
display: inline-block;
vertical-align: top;
border-radius: 50%;
background-color: lighten($tertiary, 30%);
}
.emoji-picker .footer {
align-items: center;
display: flex;
@ -146,10 +146,30 @@
text-shadow: 0.5px 1.5px 0 rgba(0,0,0,0.3);
}
body img.emoji {
width: 20px;
.emoji-picker button.emoji {
background: transparent;
background-position: center;
background-repeat: no-repeat;
border-radius: 0;
background-size: 20px 20px;
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 20px;
vertical-align: middle;
margin: 0;
padding: 0;
border: 0;
vertical-align: top;
width: 20px;
outline: none;
padding: 3px;
margin: 2px;
}
.emoji-picker .section-group button.emoji:hover, .emoji-picker .results button.emoji:hover {
display: inline-block;
vertical-align: top;
border-radius: 50%;
background-color: lighten($tertiary, 40%);
}
.wmd-emoji-button:before {
@ -213,21 +233,17 @@ body img.emoji {
flex: 1;
}
.emoji-picker .results .emoji {
margin: 5px;
}
.emoji-picker .filter .clear-filter {
position: absolute;
right: 5px;
top: 12px;
border: 0;
background: none;
color: $primary;
color: dark-light-choose(scale-color($header_primary, $lightness: 50%), $header_primary);
outline: none;
display: none;
&:hover {
color: $tertiary;
color: $primary;
}
}

View File

@ -36,7 +36,7 @@ QUnit.test("emojis can be hovered to display info", assert => {
click("button.emoji.btn");
andThen(() => {
$(".emoji-picker a[title='grinning']").trigger('mouseover');
$(".emoji-picker button[title='grinning']").trigger('mouseover');
andThen(() => {
assert.equal(
find('.emoji-picker .info').html().trim(),
@ -52,7 +52,7 @@ QUnit.skip("emoji picker has sections", assert => {
click("#topic-footer-buttons .btn.create");
click("button.emoji.btn");
click(".emoji-picker .categories-column a[title='travel']");
click(".emoji-picker .categories-column button[title='travel']");
andThen(() => {
assert.notEqual(
find('.emoji-picker .list').scrollTop(),
@ -67,7 +67,7 @@ QUnit.skip("emoji picker triggers event when picking emoji", assert => {
click("#topic-footer-buttons .btn.create");
click("button.emoji.btn");
click(".emoji-picker a[title='grinning']");
click(".emoji-picker button[title='grinning']");
andThen(() => {
assert.equal(
find('.d-editor-input').val(),
@ -81,18 +81,18 @@ QUnit.test("emoji picker has a list of recently used emojis", assert => {
visit("/t/internationalization-localization/280");
click("#topic-footer-buttons .btn.create");
click("button.emoji.btn");
click(".emoji-picker .clear-recent");
click(".emoji-picker a[title='grinning']");
click(".emoji-picker .clear-recent");
click(".emoji-picker .section[data-section='people'] button.emoji[title='grinning']");
andThen(() => {
assert.equal(
find('.section[data-section="recent"]').css("display"),
find('.emoji-picker .section[data-section="recent"]').css("display"),
"block",
"it shows recent section"
);
assert.equal(
find('.section[data-section="recent"] .section-group img.emoji').length,
find('.emoji-picker .section[data-section="recent"] .section-group button.emoji').length,
1,
"it adds the emoji code to the recently used emojis list"
);
@ -101,19 +101,19 @@ QUnit.test("emoji picker has a list of recently used emojis", assert => {
click(".emoji-picker .clear-recent");
andThen(() => {
assert.equal(
find('.section[data-section="recent"] .section-group img.emoji').length,
find('.emoji-picker .section[data-section="recent"] .section-group button.emoji').length,
0,
"it has cleared recent emojis"
);
assert.equal(
find('.section[data-section="recent"]').css("display"),
find('.emoji-picker .section[data-section="recent"]').css("display"),
"none",
"it hides recent section"
);
assert.equal(
find('.category-icon a[title="recent"]').parent().css("display"),
find('.emoji-picker .category-icon button.emoji[data-section="recent"]').parent().css("display"),
"none",
"it hides recent category icon"
);
@ -126,18 +126,18 @@ QUnit.skip("emoji picker correctly orders recently used emojis", assert => {
click("button.emoji.btn");
click(".emoji-picker .clear-recent");
click(".emoji-picker a[title='grinning']");
click(".emoji-picker a[title='sunglasses']");
click(".emoji-picker a[title='grinning']");
click(".emoji-picker button[title='grinning']");
click(".emoji-picker button[title='sunglasses']");
click(".emoji-picker button[title='grinning']");
andThen(() => {
assert.equal(
find('.section[data-section="recent"] .section-group img.emoji').length,
find('.section[data-section="recent"] .section-group button.emoji').length,
2,
"it has multiple recent emojis"
);
assert.equal(
find('.section[data-section="recent"] .section-group img.emoji').first().attr('src'),
find('.section[data-section="recent"] .section-group button.emoji').first().attr('src'),
`/images/emoji/emoji_one/grinning.png?v=${v}`,
"it puts the last used emoji in first"
);
@ -151,7 +151,7 @@ QUnit.skip("emoji picker lazy loads emojis", assert => {
click("button.emoji.btn");
andThen(() => {
const $emoji = $('.emoji-picker a[title="massage_woman"] img');
const $emoji = $('.emoji-picker button[title="massage_woman"] img');
assert.equal(
$emoji.attr('src'),
"",

View File

@ -766,7 +766,7 @@ componentTest('emoji', {
jumpEnd(this.$('textarea.d-editor-input')[0]);
click('button.emoji');
click('a[title=grinning]');
click('.emoji-picker .section[data-section="people"] button.emoji[title="grinning"]');
andThen(() => {
assert.equal(this.get('value'), 'hello world.:grinning:');
});