Commit b70b5714 authored by Tim Zallmann's avatar Tim Zallmann

Improvements to Emoji Loading Mechanism

Fixed Emojis FrontendFixture Creature
parent 7db81dd6
...@@ -13,62 +13,57 @@ class GlEmoji extends HTMLElement { ...@@ -13,62 +13,57 @@ class GlEmoji extends HTMLElement {
const { fallbackSpriteClass, fallbackSrc } = this.dataset; const { fallbackSpriteClass, fallbackSrc } = this.dataset;
let { name, unicodeVersion } = this.dataset; let { name, unicodeVersion } = this.dataset;
return initEmojiMap() return initEmojiMap().then(() => {
.then(() => { if (!unicodeVersion) {
if (!unicodeVersion) { const emojiInfo = getEmojiInfo(name);
const emojiInfo = getEmojiInfo(name);
if (emojiInfo) { if (emojiInfo) {
if (name !== emojiInfo.name) { if (name !== emojiInfo.name) {
({ name } = emojiInfo); ({ name } = emojiInfo);
this.dataset.name = emojiInfo.name; this.dataset.name = emojiInfo.name;
} }
unicodeVersion = emojiInfo.u; unicodeVersion = emojiInfo.u;
this.dataset.uni = unicodeVersion; this.dataset.unicodeVersion = unicodeVersion;
emojiUnicode = emojiInfo.e; emojiUnicode = emojiInfo.e;
this.innerHTML = emojiInfo.e; this.innerHTML = emojiInfo.e;
this.title = emojiInfo.d; this.title = emojiInfo.d;
}
} }
}
const isEmojiUnicode = const isEmojiUnicode =
this.childNodes && this.childNodes &&
Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3); Array.prototype.every.call(this.childNodes, childNode => childNode.nodeType === 3);
if ( if (
emojiUnicode && emojiUnicode &&
isEmojiUnicode && isEmojiUnicode &&
!isEmojiUnicodeSupported(emojiUnicode, unicodeVersion) !isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)
) { ) {
const hasImageFallback = fallbackSrc && fallbackSrc.length > 0; const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
const hasCssSpriteFallback = fallbackSpriteClass && fallbackSpriteClass.length > 0; const hasCssSpriteFallback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
// CSS sprite fallback takes precedence over image fallback // CSS sprite fallback takes precedence over image fallback
if (hasCssSpriteFallback) { if (hasCssSpriteFallback) {
if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) { if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) {
const emojiSpriteLinkTag = document.createElement('link'); const emojiSpriteLinkTag = document.createElement('link');
emojiSpriteLinkTag.setAttribute('rel', 'stylesheet'); emojiSpriteLinkTag.setAttribute('rel', 'stylesheet');
emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path); emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path);
document.head.appendChild(emojiSpriteLinkTag); document.head.appendChild(emojiSpriteLinkTag);
gon.emoji_sprites_css_added = true; gon.emoji_sprites_css_added = true;
}
// IE 11 doesn't like adding multiple at once :(
this.classList.add('emoji-icon');
this.classList.add(fallbackSpriteClass);
} else if (hasImageFallback) {
this.innerHTML = emojiImageTag(name, fallbackSrc);
} else {
const src = emojiFallbackImageSrc(name);
this.innerHTML = emojiImageTag(name, src);
} }
// IE 11 doesn't like adding multiple at once :(
this.classList.add('emoji-icon');
this.classList.add(fallbackSpriteClass);
} else if (hasImageFallback) {
this.innerHTML = emojiImageTag(name, fallbackSrc);
} else {
const src = emojiFallbackImageSrc(name);
this.innerHTML = emojiImageTag(name, src);
} }
}) }
.catch(error => { });
// Only reject is already handled in initEmojiMap
throw error;
});
} }
} }
......
...@@ -5,40 +5,49 @@ import axios from '../lib/utils/axios_utils'; ...@@ -5,40 +5,49 @@ import axios from '../lib/utils/axios_utils';
import AccessorUtilities from '../lib/utils/accessor'; import AccessorUtilities from '../lib/utils/accessor';
let emojiMap = null; let emojiMap = null;
let emojiPromise = null;
let validEmojiNames = null; let validEmojiNames = null;
export const EMOJI_VERSION = '1'; export const EMOJI_VERSION = '1';
const EMOJI_VERSION_LOCALSTORAGE = `EMOJIS_${EMOJI_VERSION}`;
const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
export function initEmojiMap() { export function initEmojiMap() {
return new Promise((resolve, reject) => { emojiPromise =
if (emojiMap) { emojiPromise ||
resolve(emojiMap); new Promise((resolve, reject) => {
} else if (isLocalStorageAvailable && window.localStorage.getItem(EMOJI_VERSION_LOCALSTORAGE)) { if (emojiMap) {
emojiMap = JSON.parse(window.localStorage.getItem(EMOJI_VERSION_LOCALSTORAGE)); resolve(emojiMap);
validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; } else if (
resolve(emojiMap); isLocalStorageAvailable &&
} else { window.localStorage.getItem('gl-emoji-map-version') === EMOJI_VERSION &&
// We load the JSON file direct from the server window.localStorage.getItem('gl-emoji-map')
// because it can't be loaded from a CDN due to ) {
// cross domain problems with JSON emojiMap = JSON.parse(window.localStorage.getItem('gl-emoji-map'));
axios validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)];
.get(`${gon.relative_url_root || ''}/-/emojis/${EMOJI_VERSION}/emojis.json`) resolve(emojiMap);
.then(({ data }) => { } else {
emojiMap = data; // We load the JSON file direct from the server
validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; // because it can't be loaded from a CDN due to
resolve(emojiMap); // cross domain problems with JSON
if (isLocalStorageAvailable) { axios
window.localStorage.setItem(EMOJI_VERSION_LOCALSTORAGE, JSON.stringify(emojiMap)); .get(`${gon.relative_url_root || ''}/-/emojis/${EMOJI_VERSION}/emojis.json`)
} .then(({ data }) => {
}) emojiMap = data;
.catch(err => { validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)];
reject(err); resolve(emojiMap);
}); if (isLocalStorageAvailable) {
} window.localStorage.setItem('gl-emoji-map-version', EMOJI_VERSION);
}); window.localStorage.setItem('gl-emoji-map', JSON.stringify(emojiMap));
}
})
.catch(err => {
reject(err);
});
}
});
return emojiPromise;
} }
export function normalizeEmojiName(name) { export function normalizeEmojiName(name) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe 'Emojis (JavaScript fixtures)', type: :request do RSpec.describe 'Emojis (JavaScript fixtures)', type: :request do
include JavaScriptFixturesHelpers include JavaScriptFixturesHelpers
before(:all) do before(:all) do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment