diff options
author | Eric Eastwood <contact@ericeastwood.com> | 2017-02-22 01:39:34 -0600 |
---|---|---|
committer | Eric Eastwood <contact@ericeastwood.com> | 2017-02-22 01:39:34 -0600 |
commit | 10a881046f34d58a8094da141ea1f34ee073bb3e (patch) | |
tree | ec9b024bea7d271d83d5e245b96f6bbbcc547168 | |
parent | 11a10ccca8bbb10593cc35771320e864bad14cc0 (diff) | |
download | gitlab-ce-26371-native-emojis.tar.gz |
Use ES5 `[...'🖐🏿']` compatible `spreadString` helper26371-native-emojis
-rw-r--r-- | app/assets/javascripts/application.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/behaviors/gl_emoji.js.es6 | 7 | ||||
-rw-r--r-- | app/assets/javascripts/behaviors/gl_emoji/spread_string.js | 50 | ||||
-rw-r--r-- | app/assets/javascripts/extensions/array.js.es6 | 6 | ||||
-rw-r--r-- | app/assets/javascripts/extensions/string.js | 2 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | spec/javascripts/awards_handler_spec.js | 1 | ||||
-rw-r--r-- | spec/javascripts/gl_emoji_spec.js | 18 | ||||
-rw-r--r-- | yarn.lock | 69 |
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" |