summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/awards_handler.js10
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji.js206
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/is_emoji_unicode_supported.js121
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/spread_string.js2
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js33
-rw-r--r--app/assets/javascripts/extensions/string.js4
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js8
-rw-r--r--app/assets/javascripts/main.js326
-rw-r--r--config/webpack.config.js3
-rw-r--r--spec/javascripts/awards_handler_spec.js5
-rw-r--r--spec/javascripts/gl_emoji_spec.js23
11 files changed, 375 insertions, 366 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 4667980a960..54836efdf29 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -1,10 +1,8 @@
/* global Cookies */
-const emojiMap = require('emoji-map');
-const emojiAliases = require('emoji-aliases');
-const glEmoji = require('./behaviors/gl_emoji');
-
-const glEmojiTag = glEmoji.glEmojiTag;
+import emojiMap from 'emojis/digests.json';
+import emojiAliases from 'emojis/aliases.json';
+import { glEmojiTag } from './behaviors/gl_emoji';
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
const requestAnimationFrame = window.requestAnimationFrame ||
@@ -515,4 +513,4 @@ AwardsHandler.prototype.destroy = function destroy() {
$('.emoji-menu').remove();
};
-module.exports = AwardsHandler;
+export default AwardsHandler;
diff --git a/app/assets/javascripts/behaviors/gl_emoji.js b/app/assets/javascripts/behaviors/gl_emoji.js
index d1d98c3919f..59741cc9b1a 100644
--- a/app/assets/javascripts/behaviors/gl_emoji.js
+++ b/app/assets/javascripts/behaviors/gl_emoji.js
@@ -1,11 +1,13 @@
-const installCustomElements = require('document-register-element');
-const emojiMap = require('emoji-map');
-const emojiAliases = require('emoji-aliases');
-const generatedUnicodeSupportMap = require('./gl_emoji/unicode_support_map');
-const spreadString = require('./gl_emoji/spread_string');
+import installCustomElements from 'document-register-element';
+import emojiMap from 'emojis/digests.json';
+import emojiAliases from 'emojis/aliases.json';
+import { getUnicodeSupportMap } from './gl_emoji/unicode_support_map';
+import { isEmojiUnicodeSupported } from './gl_emoji/is_emoji_unicode_supported';
installCustomElements(window);
+const generatedUnicodeSupportMap = getUnicodeSupportMap();
+
function emojiImageTag(name, src) {
return `<img class="emoji" title=":${name}:" alt=":${name}:" src="${src}" width="20" height="20" align="absmiddle" />`;
}
@@ -55,163 +57,49 @@ function glEmojiTag(inputName, options) {
`;
}
-// On Windows, flags render as two-letter country codes, see http://emojipedia.org/flags/
-const flagACodePoint = 127462; // parseInt('1F1E6', 16)
-const flagZCodePoint = 127487; // parseInt('1F1FF', 16)
-function isFlagEmoji(emojiUnicode) {
- const cp = emojiUnicode.codePointAt(0);
- // Length 4 because flags are made of 2 characters which are surrogate pairs
- return emojiUnicode.length === 4 && cp >= flagACodePoint && cp <= flagZCodePoint;
-}
-
-// Chrome <57 renders keycaps oddly
-// See https://bugs.chromium.org/p/chromium/issues/detail?id=632294
-// Same issue on Windows also fixed in Chrome 57, http://i.imgur.com/rQF7woO.png
-function isKeycapEmoji(emojiUnicode) {
- return emojiUnicode.length === 3 && emojiUnicode[2] === '\u20E3';
-}
-
-// Check for a skin tone variation emoji which aren't always supported
-const tone1 = 127995;// parseInt('1F3FB', 16)
-const tone5 = 127999;// parseInt('1F3FF', 16)
-function isSkinToneComboEmoji(emojiUnicode) {
- return emojiUnicode.length > 2 && spreadString(emojiUnicode).some((char) => {
- const cp = char.codePointAt(0);
- return cp >= tone1 && cp <= tone5;
- });
-}
-
-// macOS supports most skin tone emoji's but
-// doesn't support the skin tone versions of horse racing
-const horseRacingCodePoint = 127943;// parseInt('1F3C7', 16)
-function isHorceRacingSkinToneComboEmoji(emojiUnicode) {
- return spreadString(emojiUnicode)[0].codePointAt(0) === horseRacingCodePoint &&
- isSkinToneComboEmoji(emojiUnicode);
-}
-
-// Check for `family_*`, `kiss_*`, `couple_*`
-// For ex. Windows 8.1 Firefox 51.0.1, doesn't support these
-const zwj = 8205; // parseInt('200D', 16)
-const personStartCodePoint = 128102; // parseInt('1F466', 16)
-const personEndCodePoint = 128105; // parseInt('1F469', 16)
-function isPersonZwjEmoji(emojiUnicode) {
- let hasPersonEmoji = false;
- let hasZwj = false;
- spreadString(emojiUnicode).forEach((character) => {
- const cp = character.codePointAt(0);
- if (cp === zwj) {
- hasZwj = true;
- } else if (cp >= personStartCodePoint && cp <= personEndCodePoint) {
- hasPersonEmoji = true;
+function installGlEmojiElement() {
+ const GlEmojiElementProto = Object.create(HTMLElement.prototype);
+ GlEmojiElementProto.createdCallback = function createdCallback() {
+ const emojiUnicode = this.textContent.trim();
+ const {
+ name,
+ unicodeVersion,
+ fallbackSrc,
+ fallbackSpriteClass,
+ } = this.dataset;
+
+ const isEmojiUnicode = this.childNodes && Array.prototype.every.call(
+ this.childNodes,
+ childNode => childNode.nodeType === 3,
+ );
+ const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
+ const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
+
+ if (
+ isEmojiUnicode &&
+ !isEmojiUnicodeSupported(generatedUnicodeSupportMap, emojiUnicode, unicodeVersion)
+ ) {
+ // CSS sprite fallback takes precedence over image fallback
+ if (hasCssSpriteFalback) {
+ // 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 = assembleFallbackImageSrc(name);
+ this.innerHTML = emojiImageTag(name, src);
+ }
}
- });
-
- return hasPersonEmoji && hasZwj;
-}
-
-// Helper so we don't have to run `isFlagEmoji` twice
-// in `isEmojiUnicodeSupported` logic
-function checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) {
- const isFlagResult = isFlagEmoji(emojiUnicode);
- return (
- (unicodeSupportMap.flag && isFlagResult) ||
- !isFlagResult
- );
-}
-
-// Helper so we don't have to run `isSkinToneComboEmoji` twice
-// in `isEmojiUnicodeSupported` logic
-function checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) {
- const isSkinToneResult = isSkinToneComboEmoji(emojiUnicode);
- return (
- (unicodeSupportMap.skinToneModifier && isSkinToneResult) ||
- !isSkinToneResult
- );
-}
-
-// Helper func so we don't have to run `isHorceRacingSkinToneComboEmoji` twice
-// in `isEmojiUnicodeSupported` logic
-function checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) {
- const isHorseRacingSkinToneResult = isHorceRacingSkinToneComboEmoji(emojiUnicode);
- return (
- (unicodeSupportMap.horseRacing && isHorseRacingSkinToneResult) ||
- !isHorseRacingSkinToneResult
- );
-}
-
-// Helper so we don't have to run `isPersonZwjEmoji` twice
-// in `isEmojiUnicodeSupported` logic
-function checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode) {
- const isPersonZwjResult = isPersonZwjEmoji(emojiUnicode);
- return (
- (unicodeSupportMap.personZwj && isPersonZwjResult) ||
- !isPersonZwjResult
- );
-}
-
-// Takes in a support map and determines whether
-// the given unicode emoji is supported on the platform.
-//
-// Combines all the edge case tests into a one-stop shop method
-function isEmojiUnicodeSupported(unicodeSupportMap = {}, emojiUnicode, unicodeVersion) {
- const isOlderThanChrome57 = unicodeSupportMap.meta && unicodeSupportMap.meta.isChrome &&
- unicodeSupportMap.meta.chromeVersion < 57;
+ };
- // For comments about each scenario, see the comments above each individual respective function
- return unicodeSupportMap[unicodeVersion] &&
- !(isOlderThanChrome57 && isKeycapEmoji(emojiUnicode)) &&
- checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) &&
- checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) &&
- checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) &&
- checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode);
+ document.registerElement('gl-emoji', {
+ prototype: GlEmojiElementProto,
+ });
}
-const GlEmojiElementProto = Object.create(HTMLElement.prototype);
-GlEmojiElementProto.createdCallback = function createdCallback() {
- const emojiUnicode = this.textContent.trim();
- const {
- name,
- unicodeVersion,
- fallbackSrc,
- fallbackSpriteClass,
- } = this.dataset;
-
- const isEmojiUnicode = this.childNodes && Array.prototype.every.call(
- this.childNodes,
- childNode => childNode.nodeType === 3,
- );
- const hasImageFallback = fallbackSrc && fallbackSrc.length > 0;
- const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0;
-
- if (
- isEmojiUnicode &&
- !isEmojiUnicodeSupported(generatedUnicodeSupportMap, emojiUnicode, unicodeVersion)
- ) {
- // CSS sprite fallback takes precedence over image fallback
- if (hasCssSpriteFalback) {
- // 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 = assembleFallbackImageSrc(name);
- this.innerHTML = emojiImageTag(name, src);
- }
- }
-};
-
-document.registerElement('gl-emoji', {
- prototype: GlEmojiElementProto,
-});
-
-module.exports = {
- emojiImageTag,
+export {
+ installGlEmojiElement,
glEmojiTag,
- isEmojiUnicodeSupported,
- isFlagEmoji,
- isKeycapEmoji,
- isSkinToneComboEmoji,
- isHorceRacingSkinToneComboEmoji,
- isPersonZwjEmoji,
+ emojiImageTag,
};
diff --git a/app/assets/javascripts/behaviors/gl_emoji/is_emoji_unicode_supported.js b/app/assets/javascripts/behaviors/gl_emoji/is_emoji_unicode_supported.js
new file mode 100644
index 00000000000..5e3c45f7e92
--- /dev/null
+++ b/app/assets/javascripts/behaviors/gl_emoji/is_emoji_unicode_supported.js
@@ -0,0 +1,121 @@
+import spreadString from './spread_string';
+
+// On Windows, flags render as two-letter country codes, see http://emojipedia.org/flags/
+const flagACodePoint = 127462; // parseInt('1F1E6', 16)
+const flagZCodePoint = 127487; // parseInt('1F1FF', 16)
+function isFlagEmoji(emojiUnicode) {
+ const cp = emojiUnicode.codePointAt(0);
+ // Length 4 because flags are made of 2 characters which are surrogate pairs
+ return emojiUnicode.length === 4 && cp >= flagACodePoint && cp <= flagZCodePoint;
+}
+
+// Chrome <57 renders keycaps oddly
+// See https://bugs.chromium.org/p/chromium/issues/detail?id=632294
+// Same issue on Windows also fixed in Chrome 57, http://i.imgur.com/rQF7woO.png
+function isKeycapEmoji(emojiUnicode) {
+ return emojiUnicode.length === 3 && emojiUnicode[2] === '\u20E3';
+}
+
+// Check for a skin tone variation emoji which aren't always supported
+const tone1 = 127995;// parseInt('1F3FB', 16)
+const tone5 = 127999;// parseInt('1F3FF', 16)
+function isSkinToneComboEmoji(emojiUnicode) {
+ return emojiUnicode.length > 2 && spreadString(emojiUnicode).some((char) => {
+ const cp = char.codePointAt(0);
+ return cp >= tone1 && cp <= tone5;
+ });
+}
+
+// macOS supports most skin tone emoji's but
+// doesn't support the skin tone versions of horse racing
+const horseRacingCodePoint = 127943;// parseInt('1F3C7', 16)
+function isHorceRacingSkinToneComboEmoji(emojiUnicode) {
+ return spreadString(emojiUnicode)[0].codePointAt(0) === horseRacingCodePoint &&
+ isSkinToneComboEmoji(emojiUnicode);
+}
+
+// Check for `family_*`, `kiss_*`, `couple_*`
+// For ex. Windows 8.1 Firefox 51.0.1, doesn't support these
+const zwj = 8205; // parseInt('200D', 16)
+const personStartCodePoint = 128102; // parseInt('1F466', 16)
+const personEndCodePoint = 128105; // parseInt('1F469', 16)
+function isPersonZwjEmoji(emojiUnicode) {
+ let hasPersonEmoji = false;
+ let hasZwj = false;
+ spreadString(emojiUnicode).forEach((character) => {
+ const cp = character.codePointAt(0);
+ if (cp === zwj) {
+ hasZwj = true;
+ } else if (cp >= personStartCodePoint && cp <= personEndCodePoint) {
+ hasPersonEmoji = true;
+ }
+ });
+
+ return hasPersonEmoji && hasZwj;
+}
+
+// Helper so we don't have to run `isFlagEmoji` twice
+// in `isEmojiUnicodeSupported` logic
+function checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) {
+ const isFlagResult = isFlagEmoji(emojiUnicode);
+ return (
+ (unicodeSupportMap.flag && isFlagResult) ||
+ !isFlagResult
+ );
+}
+
+// Helper so we don't have to run `isSkinToneComboEmoji` twice
+// in `isEmojiUnicodeSupported` logic
+function checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) {
+ const isSkinToneResult = isSkinToneComboEmoji(emojiUnicode);
+ return (
+ (unicodeSupportMap.skinToneModifier && isSkinToneResult) ||
+ !isSkinToneResult
+ );
+}
+
+// Helper func so we don't have to run `isHorceRacingSkinToneComboEmoji` twice
+// in `isEmojiUnicodeSupported` logic
+function checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) {
+ const isHorseRacingSkinToneResult = isHorceRacingSkinToneComboEmoji(emojiUnicode);
+ return (
+ (unicodeSupportMap.horseRacing && isHorseRacingSkinToneResult) ||
+ !isHorseRacingSkinToneResult
+ );
+}
+
+// Helper so we don't have to run `isPersonZwjEmoji` twice
+// in `isEmojiUnicodeSupported` logic
+function checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode) {
+ const isPersonZwjResult = isPersonZwjEmoji(emojiUnicode);
+ return (
+ (unicodeSupportMap.personZwj && isPersonZwjResult) ||
+ !isPersonZwjResult
+ );
+}
+
+// Takes in a support map and determines whether
+// the given unicode emoji is supported on the platform.
+//
+// Combines all the edge case tests into a one-stop shop method
+function isEmojiUnicodeSupported(unicodeSupportMap = {}, emojiUnicode, unicodeVersion) {
+ const isOlderThanChrome57 = unicodeSupportMap.meta && unicodeSupportMap.meta.isChrome &&
+ unicodeSupportMap.meta.chromeVersion < 57;
+
+ // For comments about each scenario, see the comments above each individual respective function
+ return unicodeSupportMap[unicodeVersion] &&
+ !(isOlderThanChrome57 && isKeycapEmoji(emojiUnicode)) &&
+ checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) &&
+ checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) &&
+ checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) &&
+ checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode);
+}
+
+export {
+ isEmojiUnicodeSupported,
+ isFlagEmoji,
+ isKeycapEmoji,
+ isSkinToneComboEmoji,
+ isHorceRacingSkinToneComboEmoji,
+ isPersonZwjEmoji,
+};
diff --git a/app/assets/javascripts/behaviors/gl_emoji/spread_string.js b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js
index 2380349c4fa..327764ec6e9 100644
--- a/app/assets/javascripts/behaviors/gl_emoji/spread_string.js
+++ b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js
@@ -47,4 +47,4 @@ function spreadString(str) {
return arr;
}
-module.exports = spreadString;
+export default spreadString;
diff --git a/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js b/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js
index f31716d4c07..aa522e20c36 100644
--- a/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js
+++ b/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js
@@ -68,7 +68,7 @@ const chromeVersion = chromeMatches && chromeMatches[1] && parseInt(chromeMatche
// See 32px, https://i.imgur.com/htY6Zym.png
// See 16px, https://i.imgur.com/FPPsIF8.png
const fontSize = 16;
-function testUnicodeSupportMap(testMap) {
+function generateUnicodeSupportMap(testMap) {
const testMapKeys = Object.keys(testMap);
const numTestEntries = testMapKeys
.reduce((list, testKey) => list.concat(testMap[testKey]), []).length;
@@ -138,17 +138,24 @@ function testUnicodeSupportMap(testMap) {
return resultMap;
}
-let unicodeSupportMap;
-const userAgentFromCache = window.localStorage.getItem('gl-emoji-user-agent');
-try {
- unicodeSupportMap = JSON.parse(window.localStorage.getItem('gl-emoji-unicode-support-map'));
-} catch (err) {
- // swallow
-}
-if (!unicodeSupportMap || userAgentFromCache !== navigator.userAgent) {
- unicodeSupportMap = testUnicodeSupportMap(unicodeSupportTestMap);
- window.localStorage.setItem('gl-emoji-user-agent', navigator.userAgent);
- window.localStorage.setItem('gl-emoji-unicode-support-map', JSON.stringify(unicodeSupportMap));
+function getUnicodeSupportMap() {
+ let unicodeSupportMap;
+ const userAgentFromCache = window.localStorage.getItem('gl-emoji-user-agent');
+ try {
+ unicodeSupportMap = JSON.parse(window.localStorage.getItem('gl-emoji-unicode-support-map'));
+ } catch (err) {
+ // swallow
+ }
+ if (!unicodeSupportMap || userAgentFromCache !== navigator.userAgent) {
+ unicodeSupportMap = generateUnicodeSupportMap(unicodeSupportTestMap);
+ window.localStorage.setItem('gl-emoji-user-agent', navigator.userAgent);
+ window.localStorage.setItem('gl-emoji-unicode-support-map', JSON.stringify(unicodeSupportMap));
+ }
+
+ return unicodeSupportMap;
}
-module.exports = unicodeSupportMap;
+export {
+ getUnicodeSupportMap,
+ generateUnicodeSupportMap,
+};
diff --git a/app/assets/javascripts/extensions/string.js b/app/assets/javascripts/extensions/string.js
index fe23be0bbc1..ae9662444b0 100644
--- a/app/assets/javascripts/extensions/string.js
+++ b/app/assets/javascripts/extensions/string.js
@@ -1,2 +1,2 @@
-require('string.prototype.codepointat');
-require('string.fromcodepoint');
+import 'string.prototype.codepointat';
+import 'string.fromcodepoint';
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 1bc04a5ad96..4f7ce1fa197 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -1,10 +1,8 @@
/* eslint-disable func-names, space-before-function-paren, no-template-curly-in-string, comma-dangle, object-shorthand, quotes, dot-notation, no-else-return, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-param-reassign, no-useless-escape, prefer-template, consistent-return, wrap-iife, prefer-arrow-callback, camelcase, no-unused-vars, no-useless-return, vars-on-top, max-len */
-const emojiMap = require('emoji-map');
-const emojiAliases = require('emoji-aliases');
-const glEmoji = require('./behaviors/gl_emoji');
-
-const glEmojiTag = glEmoji.glEmojiTag;
+import emojiMap from 'emojis/digests.json';
+import emojiAliases from 'emojis/aliases.json';
+import { glEmojiTag } from '~/behaviors/gl_emoji';
// Creates the variables for setting up GFM auto-completion
(function() {
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 79164edff0e..689a6c3a93a 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -1,4 +1,4 @@
-/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import */
+/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import, import/first */
/* global bp */
/* global Cookies */
/* global Flash */
@@ -13,19 +13,20 @@ import Dropzone from 'dropzone';
import Sortable from 'vendor/Sortable';
// libraries with import side-effects
-require('mousetrap');
-require('mousetrap/plugins/pause/mousetrap-pause');
-require('vendor/fuzzaldrin-plus');
-require('es6-promise').polyfill();
+import 'mousetrap';
+import 'mousetrap/plugins/pause/mousetrap-pause';
+import 'vendor/fuzzaldrin-plus';
+import promisePolyfill from 'es6-promise';
// extensions
-require('./extensions/string');
-require('./extensions/array');
-require('./extensions/custom_event');
-require('./extensions/element');
-require('./extensions/jquery');
-require('./extensions/object');
-require('es6-promise').polyfill();
+import './extensions/string';
+import './extensions/array';
+import './extensions/custom_event';
+import './extensions/element';
+import './extensions/jquery';
+import './extensions/object';
+
+promisePolyfill.polyfill();
// expose common libraries as globals (TODO: remove these)
window.jQuery = jQuery;
@@ -37,174 +38,171 @@ window.Dropzone = Dropzone;
window.Sortable = Sortable;
// shortcuts
-require('./shortcuts');
-require('./shortcuts_navigation');
-require('./shortcuts_dashboard_navigation');
-require('./shortcuts_issuable');
-require('./shortcuts_network');
+import './shortcuts';
+import './shortcuts_blob';
+import './shortcuts_dashboard_navigation';
+import './shortcuts_navigation';
+import './shortcuts_find_file';
+import './shortcuts_issuable';
+import './shortcuts_network';
// behaviors
-require('./behaviors/autosize');
-require('./behaviors/details_behavior');
-require('./behaviors/quick_submit');
-require('./behaviors/requires_input');
-require('./behaviors/toggler_behavior');
-require('./behaviors/bind_in_out');
+import './behaviors/autosize';
+import './behaviors/details_behavior';
+import './behaviors/quick_submit';
+import './behaviors/requires_input';
+import './behaviors/toggler_behavior';
+import './behaviors/bind_in_out';
+import { installGlEmojiElement } from './behaviors/gl_emoji';
+installGlEmojiElement();
// blob
-require('./blob/blob_ci_yaml');
-require('./blob/blob_dockerfile_selector');
-require('./blob/blob_dockerfile_selectors');
-require('./blob/blob_file_dropzone');
-require('./blob/blob_gitignore_selector');
-require('./blob/blob_gitignore_selectors');
-require('./blob/blob_license_selector');
-require('./blob/blob_license_selectors');
-require('./blob/template_selector');
+import './blob/blob_ci_yaml';
+import './blob/blob_dockerfile_selector';
+import './blob/blob_dockerfile_selectors';
+import './blob/blob_file_dropzone';
+import './blob/blob_gitignore_selector';
+import './blob/blob_gitignore_selectors';
+import './blob/blob_license_selector';
+import './blob/blob_license_selectors';
+import './blob/template_selector';
// templates
-require('./templates/issuable_template_selector');
-require('./templates/issuable_template_selectors');
+import './templates/issuable_template_selector';
+import './templates/issuable_template_selectors';
// commit
-require('./commit/file.js');
-require('./commit/image_file.js');
+import './commit/file';
+import './commit/image_file';
// lib/utils
-require('./lib/utils/animate');
-require('./lib/utils/bootstrap_linked_tabs');
-require('./lib/utils/common_utils');
-require('./lib/utils/datetime_utility');
-require('./lib/utils/notify');
-require('./lib/utils/pretty_time');
-require('./lib/utils/text_utility');
-require('./lib/utils/type_utility');
-require('./lib/utils/url_utility');
+import './lib/utils/animate';
+import './lib/utils/bootstrap_linked_tabs';
+import './lib/utils/common_utils';
+import './lib/utils/datetime_utility';
+import './lib/utils/notify';
+import './lib/utils/pretty_time';
+import './lib/utils/text_utility';
+import './lib/utils/type_utility';
+import './lib/utils/url_utility';
// u2f
-require('./u2f/authenticate');
-require('./u2f/error');
-require('./u2f/register');
-require('./u2f/util');
+import './u2f/authenticate';
+import './u2f/error';
+import './u2f/register';
+import './u2f/util';
// droplab
-require('./droplab/droplab');
-require('./droplab/droplab_ajax');
-require('./droplab/droplab_ajax_filter');
-require('./droplab/droplab_filter');
+import './droplab/droplab';
+import './droplab/droplab_ajax';
+import './droplab/droplab_ajax_filter';
+import './droplab/droplab_filter';
// everything else
-require('./abuse_reports');
-require('./activities');
-require('./admin');
-require('./ajax_loading_spinner');
-require('./api');
-require('./aside');
-require('./autosave');
-const AwardsHandler = require('./awards_handler');
-require('./breakpoints');
-require('./broadcast_message');
-require('./build');
-require('./build_artifacts');
-require('./build_variables');
-require('./ci_lint_editor');
-require('./commit');
-require('./commits');
-require('./compare');
-require('./compare_autocomplete');
-require('./confirm_danger_modal');
-require('./copy_as_gfm');
-require('./copy_to_clipboard');
-require('./create_label');
-require('./diff');
-require('./dispatcher');
-require('./dropzone_input');
-require('./due_date_select');
-require('./files_comment_button');
-require('./flash');
-require('./gfm_auto_complete');
-require('./gl_dropdown');
-require('./gl_field_error');
-require('./gl_field_errors');
-require('./gl_form');
-require('./group_avatar');
-require('./group_label_subscription');
-require('./groups_select');
-require('./header');
-require('./importer_status');
-require('./issuable');
-require('./issuable_context');
-require('./issuable_form');
-require('./issue');
-require('./issue_status_select');
-require('./issues_bulk_assignment');
-require('./label_manager');
-require('./labels');
-require('./labels_select');
-require('./layout_nav');
-require('./line_highlighter');
-require('./logo');
-require('./member_expiration_date');
-require('./members');
-require('./merge_request');
-require('./merge_request_tabs');
-require('./merge_request_widget');
-require('./merged_buttons');
-require('./milestone');
-require('./milestone_select');
-require('./mini_pipeline_graph_dropdown');
-require('./namespace_select');
-require('./new_branch_form');
-require('./new_commit_form');
-require('./notes');
-require('./notifications_dropdown');
-require('./notifications_form');
-require('./pager');
-require('./pipelines');
-require('./preview_markdown');
-require('./project');
-require('./project_avatar');
-require('./project_find_file');
-require('./project_fork');
-require('./project_import');
-require('./project_label_subscription');
-require('./project_new');
-require('./project_select');
-require('./project_show');
-require('./project_variables');
-require('./projects_list');
-require('./render_gfm');
-require('./render_math');
-require('./right_sidebar');
-require('./search');
-require('./search_autocomplete');
-require('./shortcuts');
-require('./shortcuts_blob');
-require('./shortcuts_dashboard_navigation');
-require('./shortcuts_find_file');
-require('./shortcuts_issuable');
-require('./shortcuts_navigation');
-require('./shortcuts_network');
-require('./signin_tabs_memoizer');
-require('./single_file_diff');
-require('./smart_interval');
-require('./snippets_list');
-require('./star');
-require('./subbable_resource');
-require('./subscription');
-require('./subscription_select');
-require('./syntax_highlight');
-require('./task_list');
-require('./todos');
-require('./tree');
-require('./user');
-require('./user_tabs');
-require('./username_validator');
-require('./users_select');
-require('./version_check_image');
-require('./visibility_select');
-require('./wikis');
-require('./zen_mode');
+import './abuse_reports';
+import './activities';
+import './admin';
+import './ajax_loading_spinner';
+import './api';
+import './aside';
+import './autosave';
+import AwardsHandler from './awards_handler';
+import './breakpoints';
+import './broadcast_message';
+import './build';
+import './build_artifacts';
+import './build_variables';
+import './ci_lint_editor';
+import './commit';
+import './commits';
+import './compare';
+import './compare_autocomplete';
+import './confirm_danger_modal';
+import './copy_as_gfm';
+import './copy_to_clipboard';
+import './create_label';
+import './diff';
+import './dispatcher';
+import './dropzone_input';
+import './due_date_select';
+import './files_comment_button';
+import './flash';
+import './gfm_auto_complete';
+import './gl_dropdown';
+import './gl_field_error';
+import './gl_field_errors';
+import './gl_form';
+import './group_avatar';
+import './group_label_subscription';
+import './groups_select';
+import './header';
+import './importer_status';
+import './issuable';
+import './issuable_context';
+import './issuable_form';
+import './issue';
+import './issue_status_select';
+import './issues_bulk_assignment';
+import './label_manager';
+import './labels';
+import './labels_select';
+import './layout_nav';
+import './line_highlighter';
+import './logo';
+import './member_expiration_date';
+import './members';
+import './merge_request';
+import './merge_request_tabs';
+import './merge_request_widget';
+import './merged_buttons';
+import './milestone';
+import './milestone_select';
+import './mini_pipeline_graph_dropdown';
+import './namespace_select';
+import './new_branch_form';
+import './new_commit_form';
+import './notes';
+import './notifications_dropdown';
+import './notifications_form';
+import './pager';
+import './pipelines';
+import './preview_markdown';
+import './project';
+import './project_avatar';
+import './project_find_file';
+import './project_fork';
+import './project_import';
+import './project_label_subscription';
+import './project_new';
+import './project_select';
+import './project_show';
+import './project_variables';
+import './projects_list';
+import './render_gfm';
+import './render_math';
+import './right_sidebar';
+import './search';
+import './search_autocomplete';
+import './signin_tabs_memoizer';
+import './single_file_diff';
+import './smart_interval';
+import './snippets_list';
+import './star';
+import './subbable_resource';
+import './subscription';
+import './subscription_select';
+import './syntax_highlight';
+import './task_list';
+import './todos';
+import './tree';
+import './user';
+import './user_tabs';
+import './username_validator';
+import './users_select';
+import './version_check_image';
+import './visibility_select';
+import './wikis';
+import './zen_mode';
(function () {
document.addEventListener('beforeunload', function () {
diff --git a/config/webpack.config.js b/config/webpack.config.js
index ff5f1412261..8e2b11a4145 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -133,8 +133,7 @@ var config = {
extensions: ['.js', '.es6', '.js.es6'],
alias: {
'~': path.join(ROOT_PATH, 'app/assets/javascripts'),
- 'emoji-map$': path.join(ROOT_PATH, 'fixtures/emojis/digests.json'),
- 'emoji-aliases$': path.join(ROOT_PATH, 'fixtures/emojis/aliases.json'),
+ 'emojis': path.join(ROOT_PATH, 'fixtures/emojis'),
'empty_states': path.join(ROOT_PATH, 'app/views/shared/empty_states'),
'icons': path.join(ROOT_PATH, 'app/views/shared/icons'),
'vendor': path.join(ROOT_PATH, 'vendor/assets/javascripts'),
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index d8517e4d3d1..dc0a62ade50 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -1,8 +1,9 @@
/* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, comma-dangle, new-parens, no-unused-vars, quotes, jasmine/no-spec-dupes, prefer-template, max-len */
-require('es6-promise').polyfill();
+import promisePolyfill from 'es6-promise';
+import AwardsHandler from '~/awards_handler';
-const AwardsHandler = require('~/awards_handler');
+promisePolyfill.polyfill();
(function() {
var awardsHandler, lazyAssert, urlRoot, openAndWaitForEmojiMenu;
diff --git a/spec/javascripts/gl_emoji_spec.js b/spec/javascripts/gl_emoji_spec.js
index e94e220b19f..7ab0b37f2ec 100644
--- a/spec/javascripts/gl_emoji_spec.js
+++ b/spec/javascripts/gl_emoji_spec.js
@@ -1,16 +1,15 @@
+import '~/extensions/string';
+import '~/extensions/array';
-require('~/extensions/string');
-require('~/extensions/array');
-
-const glEmoji = require('~/behaviors/gl_emoji');
-
-const glEmojiTag = glEmoji.glEmojiTag;
-const isEmojiUnicodeSupported = glEmoji.isEmojiUnicodeSupported;
-const isFlagEmoji = glEmoji.isFlagEmoji;
-const isKeycapEmoji = glEmoji.isKeycapEmoji;
-const isSkinToneComboEmoji = glEmoji.isSkinToneComboEmoji;
-const isHorceRacingSkinToneComboEmoji = glEmoji.isHorceRacingSkinToneComboEmoji;
-const isPersonZwjEmoji = glEmoji.isPersonZwjEmoji;
+import { glEmojiTag } from '~/behaviors/gl_emoji';
+import {
+ isEmojiUnicodeSupported,
+ isFlagEmoji,
+ isKeycapEmoji,
+ isSkinToneComboEmoji,
+ isHorceRacingSkinToneComboEmoji,
+ isPersonZwjEmoji,
+} from '~/behaviors/gl_emoji/is_emoji_unicode_supported';
const emptySupportMap = {
personZwj: false,