diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 5894de42d8..10ad3bbd1a 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -41,6 +41,7 @@ const TYPING_TIMEOUT = 1000; const CHILD_INDENT = 12; const COLORED_TAGS_RE = new RegExp("^[0-" + Zotero.Tags.MAX_COLORED_TAGS + "]{1}$"); const COLUMN_PREFS_FILEPATH = OS.Path.join(Zotero.Profile.dir, "treePrefs.json"); +const EMOJI_RE = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu; function makeItemRenderer(itemTree) { function renderPrimaryCell(index, data, column) { @@ -76,7 +77,7 @@ function makeItemRenderer(itemTree) { retracted.classList.add("retracted"); } - let tags = item.getTagColors().map(color => itemTree._getTagSwatch(color)); + let tags = item.getColoredTags().map(x => itemTree._getTagSwatch(x.tag, x.color)); let textSpan = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); textSpan.className = "cell-text"; @@ -3511,10 +3512,25 @@ var ItemTree = class ItemTree extends LibraryTree { return icon; } - _getTagSwatch(color) { + _isOnlyEmoji(str) { + // Remove emoji and zero-width joiner and see if anything's left + return !str.replace(EMOJI_RE, '').replace(/\u200D/g,''); + } + + _getTagSwatch(tag, color) { let span = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); span.className = 'tag-swatch'; - span.style.backgroundColor = color; + // If only emoji, display directly + // + // TODO: Check for a maximum number of graphemes, which is hard to do + // https://stackoverflow.com/a/54369605 + if (this._isOnlyEmoji(tag)) { + span.textContent = tag; + } + // Otherwise display color + else { + span.style.backgroundColor = color; + } return span; } }; diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index fbf0698a62..6746ecde1a 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -4254,6 +4254,17 @@ Zotero.Item.prototype.getImageSrc = function() { Zotero.Item.prototype.getTagColors = function () { + Zotero.warn("Zotero.Item::getTagColors() is deprecated -- use Zotero.Item::getColoredTags()"); + return this.getColoredTags().map(x => x.color); +}; + + +/** + * Return tags and colors + * + * @return {Object[]} - Array of object with 'tag' and 'color' properties + */ +Zotero.Item.prototype.getColoredTags = function () { var tags = this.getTags(); if (!tags.length) return []; @@ -4262,14 +4273,13 @@ Zotero.Item.prototype.getTagColors = function () { for (let tag of tags) { let data = tagColors.get(tag.tag); if (data) { - colorData.push(data); + colorData.push({tag: tag.tag, ...data}); } } - return colorData.sort((a, b) => a.position - b.position).map(val => val.color); + return colorData.sort((a, b) => a.position - b.position).map(x => ({ tag: x.tag, color: x.color })); }; - /** * Compares this item to another * diff --git a/scss/components/_item-tree.scss b/scss/components/_item-tree.scss index 6383f3dc36..1187a07365 100644 --- a/scss/components/_item-tree.scss +++ b/scss/components/_item-tree.scss @@ -19,10 +19,10 @@ .tag-swatch { display: inline-block; - min-width: 8px; - min-height: 8px; + min-width: .728em; + min-height: .728em; margin-inline-start: 3px; - border-radius: 1px; + border-radius: .15em; } }