summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Eastwood <contact@ericeastwood.com>2017-02-22 01:39:34 -0600
committerEric Eastwood <contact@ericeastwood.com>2017-02-22 01:39:34 -0600
commit10a881046f34d58a8094da141ea1f34ee073bb3e (patch)
treeec9b024bea7d271d83d5e245b96f6bbbcc547168
parent11a10ccca8bbb10593cc35771320e864bad14cc0 (diff)
downloadgitlab-ce-26371-native-emojis.tar.gz
Use ES5 `[...'🖐🏿']` compatible `spreadString` helper26371-native-emojis
-rw-r--r--app/assets/javascripts/application.js1
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji.js.es67
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/spread_string.js50
-rw-r--r--app/assets/javascripts/extensions/array.js.es66
-rw-r--r--app/assets/javascripts/extensions/string.js2
-rw-r--r--package.json4
-rw-r--r--spec/javascripts/awards_handler_spec.js1
-rw-r--r--spec/javascripts/gl_emoji_spec.js18
-rw-r--r--yarn.lock69
9 files changed, 77 insertions, 81 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 10230a84174..90b07cba823 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -47,7 +47,6 @@ require('./shortcuts_issuable');
require('./shortcuts_network');
require('vendor/jquery.nicescroll');
requireAll(require.context('./extensions', false, /^\.\/.*\.(js|es6)$/));
-require('string.prototype.codepointat');
requireAll(require.context('./behaviors', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./blob', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./templates', false, /^\.\/.*\.(js|es6)$/));
diff --git a/app/assets/javascripts/behaviors/gl_emoji.js.es6 b/app/assets/javascripts/behaviors/gl_emoji.js.es6
index fcc7c70406d..d2cd9410bcf 100644
--- a/app/assets/javascripts/behaviors/gl_emoji.js.es6
+++ b/app/assets/javascripts/behaviors/gl_emoji.js.es6
@@ -1,6 +1,7 @@
const installCustomElements = require('document-register-element');
const emojiMap = require('emoji-map');
const generatedUnicodeSupportMap = require('./gl_emoji/unicode_support_map');
+const spreadString = require('./gl_emoji/spread_string');
installCustomElements(window);
@@ -43,7 +44,7 @@ function isKeycapEmoji(emojiUnicode) {
const tone1 = 127995;// parseInt('1F3FB', 16)
const tone5 = 127999;// parseInt('1F3FF', 16)
function isSkinToneComboEmoji(emojiUnicode) {
- return emojiUnicode.length > 2 && [...emojiUnicode].some((char) => {
+ return emojiUnicode.length > 2 && spreadString(emojiUnicode).some((char) => {
const cp = char.codePointAt(0);
return cp >= tone1 && cp <= tone5;
});
@@ -51,7 +52,7 @@ function isSkinToneComboEmoji(emojiUnicode) {
const horseRacingCodePoint = 127943;// parseInt('1F3C7', 16)
function isHorceRacingSkinToneComboEmoji(emojiUnicode) {
- return [...emojiUnicode][0].codePointAt(0) === horseRacingCodePoint &&
+ return spreadString(emojiUnicode)[0].codePointAt(0) === horseRacingCodePoint &&
isSkinToneComboEmoji(emojiUnicode);
}
@@ -61,7 +62,7 @@ const personEndCodePoint = 128105; // parseInt('1F469', 16)
function isPersonZwjEmoji(emojiUnicode) {
let hasPersonEmoji = false;
let hasZwj = false;
- [...emojiUnicode].forEach((character) => {
+ spreadString(emojiUnicode).forEach((character) => {
const cp = character.codePointAt(0);
if (cp === zwj) {
hasZwj = true;
diff --git a/app/assets/javascripts/behaviors/gl_emoji/spread_string.js b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js
new file mode 100644
index 00000000000..26deb5a9f9f
--- /dev/null
+++ b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js
@@ -0,0 +1,50 @@
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt#Fixing_charCodeAt()_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_known
+function knownCharCodeAt(givenString, index) {
+ const str = `${givenString}`;
+ const end = str.length;
+
+ const surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
+ let idx = index;
+ while ((surrogatePairs.exec(str)) != null) {
+ const li = surrogatePairs.lastIndex;
+ if (li - 2 < idx) {
+ idx += 1;
+ } else {
+ break;
+ }
+ }
+
+ if (idx >= end || idx < 0) {
+ return NaN;
+ }
+
+ const code = str.charCodeAt(idx);
+
+ let hi;
+ let low;
+ if (code >= 0xD800 && code <= 0xDBFF) {
+ hi = code;
+ low = str.charCodeAt(idx + 1);
+ // Go one further, since one of the "characters" is part of a surrogate pair
+ return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
+ }
+ return code;
+}
+
+// See http://stackoverflow.com/a/38901550/796832
+// ES5/PhantomJS compatible version of spreading a string
+//
+// [...'foo'] -> ['f', 'o', 'o']
+// [...'🖐🏿'] -> ['🖐', '🏿']
+function spreadString(str) {
+ const arr = [];
+ let i = 0;
+ while (!isNaN(knownCharCodeAt(str, i))) {
+ const codePoint = knownCharCodeAt(str, i);
+ arr.push(String.fromCodePoint(codePoint));
+ i += 1;
+ }
+ return arr;
+}
+
+module.exports = spreadString;
diff --git a/app/assets/javascripts/extensions/array.js.es6 b/app/assets/javascripts/extensions/array.js.es6
index 41bf07f989e..f8256a8d26d 100644
--- a/app/assets/javascripts/extensions/array.js.es6
+++ b/app/assets/javascripts/extensions/array.js.es6
@@ -2,12 +2,6 @@
'use strict';
-const from = require('array.from');
-
-if (!Array.from) {
- from.shim();
-}
-
Array.prototype.first = function() {
return this[0];
};
diff --git a/app/assets/javascripts/extensions/string.js b/app/assets/javascripts/extensions/string.js
new file mode 100644
index 00000000000..fe23be0bbc1
--- /dev/null
+++ b/app/assets/javascripts/extensions/string.js
@@ -0,0 +1,2 @@
+require('string.prototype.codepointat');
+require('string.fromcodepoint');
diff --git a/package.json b/package.json
index 1f3f2ba3fa4..387fb7b0986 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,6 @@
"webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
- "array.from": "^1.0.3",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.22.0",
@@ -21,8 +20,8 @@
"d3": "^3.5.11",
"document-register-element": "^1.3.0",
"dropzone": "^4.2.0",
- "es6-promise": "^4.0.5",
"emoji-unicode-version": "^0.2.1",
+ "es6-promise": "^4.0.5",
"jquery": "^2.2.1",
"jquery-ui": "git+https://github.com/jquery/jquery-ui#1.11.4",
"jquery-ujs": "^1.2.1",
@@ -31,6 +30,7 @@
"pikaday": "^1.5.1",
"select2": "3.5.2-browserify",
"stats-webpack-plugin": "^0.4.3",
+ "string.fromcodepoint": "^0.2.1",
"string.prototype.codepointat": "^0.2.0",
"timeago.js": "^2.0.5",
"underscore": "^1.8.3",
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index 8bfa1d73fc6..1837d706cc1 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -1,7 +1,6 @@
/* 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 */
/* global AwardsHandler */
-require('string.prototype.codepointat');
require('es6-promise').polyfill();
require('~/awards_handler');
diff --git a/spec/javascripts/gl_emoji_spec.js b/spec/javascripts/gl_emoji_spec.js
index 235b38a24b3..c7d996fcdbd 100644
--- a/spec/javascripts/gl_emoji_spec.js
+++ b/spec/javascripts/gl_emoji_spec.js
@@ -1,6 +1,6 @@
+require('~/extensions/string');
require('~/extensions/array');
-require('string.prototype.codepointat');
const glEmoji = require('~/behaviors/gl_emoji');
@@ -200,8 +200,6 @@ describe('gl_emoji', () => {
});
});
- // TODO: Find `Array.from` polyfill for PhantomJS
- // `array.from` doesn't work well with astral symbols, https://github.com/mathiasbynens/Array.from/issues/47
describe('isSkinToneComboEmoji', () => {
it('should detect hand_splayed_tone5', () => {
expect(isSkinToneComboEmoji('🖐🏿')).toBeTruthy();
@@ -337,8 +335,11 @@ describe('gl_emoji', () => {
it('use native keycap on >=57 chrome', () => {
const emojiKey = 'five';
const unicodeSupportMap = Object.assign({}, emptySupportMap, {
- isChrome: true,
- chromeVersion: 57,
+ '3.0': true,
+ meta: {
+ isChrome: true,
+ chromeVersion: 57,
+ },
});
const isSupported = isEmojiUnicodeSupported(
unicodeSupportMap,
@@ -351,8 +352,11 @@ describe('gl_emoji', () => {
it('fallback keycap on <57 chrome', () => {
const emojiKey = 'five';
const unicodeSupportMap = Object.assign({}, emptySupportMap, {
- isChrome: true,
- chromeVersion: 50,
+ '3.0': true,
+ meta: {
+ isChrome: true,
+ chromeVersion: 50,
+ },
});
const isSupported = isEmojiUnicodeSupported(
unicodeSupportMap,
diff --git a/yarn.lock b/yarn.lock
index 0a5af5d7e34..5ee580244ce 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -142,13 +142,6 @@ array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
-array.from@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/array.from/-/array.from-1.0.3.tgz#cb586aad92067f341229f41e0ed643281dba56b7"
- dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.6.1"
-
arraybuffer.slice@0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca"
@@ -1338,13 +1331,6 @@ defaults@^1.0.2:
dependencies:
clone "^1.0.2"
-define-properties@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
- dependencies:
- foreach "^2.0.5"
- object-keys "^1.0.8"
-
del@^2.0.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
@@ -1529,23 +1515,6 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.6.1:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
- dependencies:
- es-to-primitive "^1.1.1"
- function-bind "^1.1.0"
- is-callable "^1.1.3"
- is-regex "^1.0.3"
-
-es-to-primitive@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
- dependencies:
- is-callable "^1.1.1"
- is-date-object "^1.0.1"
- is-symbol "^1.0.1"
-
es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7:
version "0.10.12"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047"
@@ -2006,10 +1975,6 @@ for-own@^0.1.4:
dependencies:
for-in "^0.1.5"
-foreach@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
-
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -2066,7 +2031,7 @@ fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10:
mkdirp ">=0.5 0"
rimraf "2"
-function-bind@^1.0.2, function-bind@^1.1.0:
+function-bind@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
@@ -2406,14 +2371,6 @@ is-builtin-module@^1.0.0:
dependencies:
builtin-modules "^1.0.0"
-is-callable@^1.1.1, is-callable@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
-
-is-date-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
-
is-dotfile@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
@@ -2511,12 +2468,6 @@ is-property@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
-is-regex@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
- dependencies:
- has "^1.0.1"
-
is-relative@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5"
@@ -2533,10 +2484,6 @@ is-stream@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-is-symbol@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
-
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -2688,7 +2635,7 @@ jquery-ujs@^1.2.1:
dependencies:
jquery ">=1.8.0"
-jquery@^2.2.1, jquery@>=1.8.0:
+jquery@>=1.8.0, jquery@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-2.2.1.tgz#3c3e16854ad3d2ac44ac65021b17426d22ad803f"
@@ -2885,7 +2832,7 @@ loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
-loader-utils@0.2.x, loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5:
+loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5:
version "0.2.16"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d"
dependencies:
@@ -3240,10 +3187,6 @@ object-component@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
-object-keys@^1.0.8:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
-
object.omit@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
@@ -4029,7 +3972,7 @@ source-map-support@^0.4.2:
dependencies:
source-map "^0.5.3"
-source-map@0.1.x, source-map@^0.1.41:
+source-map@^0.1.41:
version "0.1.43"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
dependencies:
@@ -4144,6 +4087,10 @@ string-width@^2.0.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^3.0.0"
+string.fromcodepoint@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz#8d978333c0bc92538f50f383e4888f3e5619d653"
+
string.prototype.codepointat@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz#6b26e9bd3afcaa7be3b4269b526de1b82000ac78"