1 /** |
1 /** |
2 * @output wp-includes/js/wp-emoji-loader.js |
2 * @output wp-includes/js/wp-emoji-loader.js |
3 */ |
3 */ |
4 |
4 |
5 ( function( window, document, settings ) { |
5 /** |
6 var src, ready, ii, tests; |
6 * Emoji Settings as exported in PHP via _print_emoji_detection_script(). |
7 |
7 * @typedef WPEmojiSettings |
8 // Create a canvas element for testing native browser support of emoji. |
8 * @type {object} |
9 var canvas = document.createElement( 'canvas' ); |
9 * @property {?object} source |
10 var context = canvas.getContext && canvas.getContext( '2d' ); |
10 * @property {?string} source.concatemoji |
|
11 * @property {?string} source.twemoji |
|
12 * @property {?string} source.wpemoji |
|
13 * @property {?boolean} DOMReady |
|
14 * @property {?Function} readyCallback |
|
15 */ |
|
16 |
|
17 /** |
|
18 * Support tests. |
|
19 * @typedef SupportTests |
|
20 * @type {object} |
|
21 * @property {?boolean} flag |
|
22 * @property {?boolean} emoji |
|
23 */ |
|
24 |
|
25 /** |
|
26 * IIFE to detect emoji support and load Twemoji if needed. |
|
27 * |
|
28 * @param {Window} window |
|
29 * @param {Document} document |
|
30 * @param {WPEmojiSettings} settings |
|
31 */ |
|
32 ( function wpEmojiLoader( window, document, settings ) { |
|
33 if ( typeof Promise === 'undefined' ) { |
|
34 return; |
|
35 } |
|
36 |
|
37 var sessionStorageKey = 'wpEmojiSettingsSupports'; |
|
38 var tests = [ 'flag', 'emoji' ]; |
|
39 |
|
40 /** |
|
41 * Checks whether the browser supports offloading to a Worker. |
|
42 * |
|
43 * @since 6.3.0 |
|
44 * |
|
45 * @private |
|
46 * |
|
47 * @returns {boolean} |
|
48 */ |
|
49 function supportsWorkerOffloading() { |
|
50 return ( |
|
51 typeof Worker !== 'undefined' && |
|
52 typeof OffscreenCanvas !== 'undefined' && |
|
53 typeof URL !== 'undefined' && |
|
54 URL.createObjectURL && |
|
55 typeof Blob !== 'undefined' |
|
56 ); |
|
57 } |
|
58 |
|
59 /** |
|
60 * @typedef SessionSupportTests |
|
61 * @type {object} |
|
62 * @property {number} timestamp |
|
63 * @property {SupportTests} supportTests |
|
64 */ |
|
65 |
|
66 /** |
|
67 * Get support tests from session. |
|
68 * |
|
69 * @since 6.3.0 |
|
70 * |
|
71 * @private |
|
72 * |
|
73 * @returns {?SupportTests} Support tests, or null if not set or older than 1 week. |
|
74 */ |
|
75 function getSessionSupportTests() { |
|
76 try { |
|
77 /** @type {SessionSupportTests} */ |
|
78 var item = JSON.parse( |
|
79 sessionStorage.getItem( sessionStorageKey ) |
|
80 ); |
|
81 if ( |
|
82 typeof item === 'object' && |
|
83 typeof item.timestamp === 'number' && |
|
84 new Date().valueOf() < item.timestamp + 604800 && // Note: Number is a week in seconds. |
|
85 typeof item.supportTests === 'object' |
|
86 ) { |
|
87 return item.supportTests; |
|
88 } |
|
89 } catch ( e ) {} |
|
90 return null; |
|
91 } |
|
92 |
|
93 /** |
|
94 * Persist the supports in session storage. |
|
95 * |
|
96 * @since 6.3.0 |
|
97 * |
|
98 * @private |
|
99 * |
|
100 * @param {SupportTests} supportTests Support tests. |
|
101 */ |
|
102 function setSessionSupportTests( supportTests ) { |
|
103 try { |
|
104 /** @type {SessionSupportTests} */ |
|
105 var item = { |
|
106 supportTests: supportTests, |
|
107 timestamp: new Date().valueOf() |
|
108 }; |
|
109 |
|
110 sessionStorage.setItem( |
|
111 sessionStorageKey, |
|
112 JSON.stringify( item ) |
|
113 ); |
|
114 } catch ( e ) {} |
|
115 } |
11 |
116 |
12 /** |
117 /** |
13 * Checks if two sets of Emoji characters render the same visually. |
118 * Checks if two sets of Emoji characters render the same visually. |
14 * |
119 * |
|
120 * This function may be serialized to run in a Worker. Therefore, it cannot refer to variables from the containing |
|
121 * scope. Everything must be passed by parameters. |
|
122 * |
15 * @since 4.9.0 |
123 * @since 4.9.0 |
16 * |
124 * |
17 * @private |
125 * @private |
18 * |
126 * |
19 * @param {number[]} set1 Set of Emoji character codes. |
127 * @param {CanvasRenderingContext2D} context 2D Context. |
20 * @param {number[]} set2 Set of Emoji character codes. |
128 * @param {string} set1 Set of Emoji to test. |
|
129 * @param {string} set2 Set of Emoji to test. |
21 * |
130 * |
22 * @return {boolean} True if the two sets render the same. |
131 * @return {boolean} True if the two sets render the same. |
23 */ |
132 */ |
24 function emojiSetsRenderIdentically( set1, set2 ) { |
133 function emojiSetsRenderIdentically( context, set1, set2 ) { |
25 var stringFromCharCode = String.fromCharCode; |
|
26 |
|
27 // Cleanup from previous test. |
134 // Cleanup from previous test. |
28 context.clearRect( 0, 0, canvas.width, canvas.height ); |
135 context.clearRect( 0, 0, context.canvas.width, context.canvas.height ); |
29 context.fillText( stringFromCharCode.apply( this, set1 ), 0, 0 ); |
136 context.fillText( set1, 0, 0 ); |
30 var rendered1 = canvas.toDataURL(); |
137 var rendered1 = new Uint32Array( |
|
138 context.getImageData( |
|
139 0, |
|
140 0, |
|
141 context.canvas.width, |
|
142 context.canvas.height |
|
143 ).data |
|
144 ); |
31 |
145 |
32 // Cleanup from previous test. |
146 // Cleanup from previous test. |
33 context.clearRect( 0, 0, canvas.width, canvas.height ); |
147 context.clearRect( 0, 0, context.canvas.width, context.canvas.height ); |
34 context.fillText( stringFromCharCode.apply( this, set2 ), 0, 0 ); |
148 context.fillText( set2, 0, 0 ); |
35 var rendered2 = canvas.toDataURL(); |
149 var rendered2 = new Uint32Array( |
36 |
150 context.getImageData( |
37 return rendered1 === rendered2; |
151 0, |
38 } |
152 0, |
39 |
153 context.canvas.width, |
40 /** |
154 context.canvas.height |
41 * Detects if the browser supports rendering emoji or flag emoji. |
155 ).data |
42 * |
156 ); |
43 * Flag emoji are a single glyph made of two characters, so some browsers |
157 |
44 * (notably, Firefox OS X) don't support them. |
158 return rendered1.every( function ( rendered2Data, index ) { |
|
159 return rendered2Data === rendered2[ index ]; |
|
160 } ); |
|
161 } |
|
162 |
|
163 /** |
|
164 * Determines if the browser properly renders Emoji that Twemoji can supplement. |
|
165 * |
|
166 * This function may be serialized to run in a Worker. Therefore, it cannot refer to variables from the containing |
|
167 * scope. Everything must be passed by parameters. |
45 * |
168 * |
46 * @since 4.2.0 |
169 * @since 4.2.0 |
47 * |
170 * |
48 * @private |
171 * @private |
49 * |
172 * |
|
173 * @param {CanvasRenderingContext2D} context 2D Context. |
50 * @param {string} type Whether to test for support of "flag" or "emoji". |
174 * @param {string} type Whether to test for support of "flag" or "emoji". |
|
175 * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. |
51 * |
176 * |
52 * @return {boolean} True if the browser can render emoji, false if it cannot. |
177 * @return {boolean} True if the browser can render emoji, false if it cannot. |
53 */ |
178 */ |
54 function browserSupportsEmoji( type ) { |
179 function browserSupportsEmoji( context, type, emojiSetsRenderIdentically ) { |
55 var isIdentical; |
180 var isIdentical; |
56 |
181 |
57 if ( ! context || ! context.fillText ) { |
182 switch ( type ) { |
58 return false; |
183 case 'flag': |
|
184 /* |
|
185 * Test for Transgender flag compatibility. Added in Unicode 13. |
|
186 * |
|
187 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
188 * the browser doesn't render it correctly (white flag emoji + transgender symbol). |
|
189 */ |
|
190 isIdentical = emojiSetsRenderIdentically( |
|
191 context, |
|
192 '\uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F', // as a zero-width joiner sequence |
|
193 '\uD83C\uDFF3\uFE0F\u200B\u26A7\uFE0F' // separated by a zero-width space |
|
194 ); |
|
195 |
|
196 if ( isIdentical ) { |
|
197 return false; |
|
198 } |
|
199 |
|
200 /* |
|
201 * Test for UN flag compatibility. This is the least supported of the letter locale flags, |
|
202 * so gives us an easy test for full support. |
|
203 * |
|
204 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
205 * the browser doesn't render it correctly ([U] + [N]). |
|
206 */ |
|
207 isIdentical = emojiSetsRenderIdentically( |
|
208 context, |
|
209 '\uD83C\uDDFA\uD83C\uDDF3', // as the sequence of two code points |
|
210 '\uD83C\uDDFA\u200B\uD83C\uDDF3' // as the two code points separated by a zero-width space |
|
211 ); |
|
212 |
|
213 if ( isIdentical ) { |
|
214 return false; |
|
215 } |
|
216 |
|
217 /* |
|
218 * Test for English flag compatibility. England is a country in the United Kingdom, it |
|
219 * does not have a two letter locale code but rather a five letter sub-division code. |
|
220 * |
|
221 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
222 * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]). |
|
223 */ |
|
224 isIdentical = emojiSetsRenderIdentically( |
|
225 context, |
|
226 // as the flag sequence |
|
227 '\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F', |
|
228 // with each code point separated by a zero-width space |
|
229 '\uD83C\uDFF4\u200B\uDB40\uDC67\u200B\uDB40\uDC62\u200B\uDB40\uDC65\u200B\uDB40\uDC6E\u200B\uDB40\uDC67\u200B\uDB40\uDC7F' |
|
230 ); |
|
231 |
|
232 return ! isIdentical; |
|
233 case 'emoji': |
|
234 /* |
|
235 * Four and twenty blackbirds baked in a pie. |
|
236 * |
|
237 * To test for Emoji 15.0 support, try to render a new emoji: Blackbird. |
|
238 * |
|
239 * The Blackbird is a ZWJ sequence combining 🐦 Bird and ⬛ large black square., |
|
240 * |
|
241 * 0x1F426 (\uD83D\uDC26) == Bird |
|
242 * 0x200D == Zero-Width Joiner (ZWJ) that links the code points for the new emoji or |
|
243 * 0x200B == Zero-Width Space (ZWS) that is rendered for clients not supporting the new emoji. |
|
244 * 0x2B1B == Large Black Square |
|
245 * |
|
246 * When updating this test for future Emoji releases, ensure that individual emoji that make up the |
|
247 * sequence come from older emoji standards. |
|
248 */ |
|
249 isIdentical = emojiSetsRenderIdentically( |
|
250 context, |
|
251 '\uD83D\uDC26\u200D\u2B1B', // as the zero-width joiner sequence |
|
252 '\uD83D\uDC26\u200B\u2B1B' // separated by a zero-width space |
|
253 ); |
|
254 |
|
255 return ! isIdentical; |
59 } |
256 } |
|
257 |
|
258 return false; |
|
259 } |
|
260 |
|
261 /** |
|
262 * Checks emoji support tests. |
|
263 * |
|
264 * This function may be serialized to run in a Worker. Therefore, it cannot refer to variables from the containing |
|
265 * scope. Everything must be passed by parameters. |
|
266 * |
|
267 * @since 6.3.0 |
|
268 * |
|
269 * @private |
|
270 * |
|
271 * @param {string[]} tests Tests. |
|
272 * @param {Function} browserSupportsEmoji Reference to browserSupportsEmoji function, needed due to minification. |
|
273 * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. |
|
274 * |
|
275 * @return {SupportTests} Support tests. |
|
276 */ |
|
277 function testEmojiSupports( tests, browserSupportsEmoji, emojiSetsRenderIdentically ) { |
|
278 var canvas; |
|
279 if ( |
|
280 typeof WorkerGlobalScope !== 'undefined' && |
|
281 self instanceof WorkerGlobalScope |
|
282 ) { |
|
283 canvas = new OffscreenCanvas( 300, 150 ); // Dimensions are default for HTMLCanvasElement. |
|
284 } else { |
|
285 canvas = document.createElement( 'canvas' ); |
|
286 } |
|
287 |
|
288 var context = canvas.getContext( '2d', { willReadFrequently: true } ); |
60 |
289 |
61 /* |
290 /* |
62 * Chrome on OS X added native emoji rendering in M41. Unfortunately, |
291 * Chrome on OS X added native emoji rendering in M41. Unfortunately, |
63 * it doesn't work when the font is bolder than 500 weight. So, we |
292 * it doesn't work when the font is bolder than 500 weight. So, we |
64 * check for bold rendering support to avoid invisible emoji in Chrome. |
293 * check for bold rendering support to avoid invisible emoji in Chrome. |
65 */ |
294 */ |
66 context.textBaseline = 'top'; |
295 context.textBaseline = 'top'; |
67 context.font = '600 32px Arial'; |
296 context.font = '600 32px Arial'; |
68 |
297 |
69 switch ( type ) { |
298 var supports = {}; |
70 case 'flag': |
299 tests.forEach( function ( test ) { |
71 /* |
300 supports[ test ] = browserSupportsEmoji( context, test, emojiSetsRenderIdentically ); |
72 * Test for Transgender flag compatibility. This flag is shortlisted for the Emoji 13 spec, |
301 } ); |
73 * but has landed in Twemoji early, so we can add support for it, too. |
302 return supports; |
74 * |
|
75 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
76 * the browser doesn't render it correctly (white flag emoji + transgender symbol). |
|
77 */ |
|
78 isIdentical = emojiSetsRenderIdentically( |
|
79 [ 0x1F3F3, 0xFE0F, 0x200D, 0x26A7, 0xFE0F ], |
|
80 [ 0x1F3F3, 0xFE0F, 0x200B, 0x26A7, 0xFE0F ] |
|
81 ); |
|
82 |
|
83 if ( isIdentical ) { |
|
84 return false; |
|
85 } |
|
86 |
|
87 /* |
|
88 * Test for UN flag compatibility. This is the least supported of the letter locale flags, |
|
89 * so gives us an easy test for full support. |
|
90 * |
|
91 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
92 * the browser doesn't render it correctly ([U] + [N]). |
|
93 */ |
|
94 isIdentical = emojiSetsRenderIdentically( |
|
95 [ 0xD83C, 0xDDFA, 0xD83C, 0xDDF3 ], |
|
96 [ 0xD83C, 0xDDFA, 0x200B, 0xD83C, 0xDDF3 ] |
|
97 ); |
|
98 |
|
99 if ( isIdentical ) { |
|
100 return false; |
|
101 } |
|
102 |
|
103 /* |
|
104 * Test for English flag compatibility. England is a country in the United Kingdom, it |
|
105 * does not have a two letter locale code but rather an five letter sub-division code. |
|
106 * |
|
107 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
108 * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]). |
|
109 */ |
|
110 isIdentical = emojiSetsRenderIdentically( |
|
111 [ 0xD83C, 0xDFF4, 0xDB40, 0xDC67, 0xDB40, 0xDC62, 0xDB40, 0xDC65, 0xDB40, 0xDC6E, 0xDB40, 0xDC67, 0xDB40, 0xDC7F ], |
|
112 [ 0xD83C, 0xDFF4, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC62, 0x200B, 0xDB40, 0xDC65, 0x200B, 0xDB40, 0xDC6E, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC7F ] |
|
113 ); |
|
114 |
|
115 return ! isIdentical; |
|
116 case 'emoji': |
|
117 /* |
|
118 * Why can't we be friends? Everyone can now shake hands in emoji, regardless of skin tone! |
|
119 * |
|
120 * To test for Emoji 14.0 support, try to render a new emoji: Handshake: Light Skin Tone, Dark Skin Tone. |
|
121 * |
|
122 * The Handshake: Light Skin Tone, Dark Skin Tone emoji is a ZWJ sequence combining 🫱 Rightwards Hand, |
|
123 * 🏻 Light Skin Tone, a Zero Width Joiner, 🫲 Leftwards Hand, and 🏿 Dark Skin Tone. |
|
124 * |
|
125 * 0x1FAF1 == Rightwards Hand |
|
126 * 0x1F3FB == Light Skin Tone |
|
127 * 0x200D == Zero-Width Joiner (ZWJ) that links the code points for the new emoji or |
|
128 * 0x200B == Zero-Width Space (ZWS) that is rendered for clients not supporting the new emoji. |
|
129 * 0x1FAF2 == Leftwards Hand |
|
130 * 0x1F3FF == Dark Skin Tone. |
|
131 * |
|
132 * When updating this test for future Emoji releases, ensure that individual emoji that make up the |
|
133 * sequence come from older emoji standards. |
|
134 */ |
|
135 isIdentical = emojiSetsRenderIdentically( |
|
136 [0x1FAF1, 0x1F3FB, 0x200D, 0x1FAF2, 0x1F3FF], |
|
137 [0x1FAF1, 0x1F3FB, 0x200B, 0x1FAF2, 0x1F3FF] |
|
138 ); |
|
139 |
|
140 return ! isIdentical; |
|
141 } |
|
142 |
|
143 return false; |
|
144 } |
303 } |
145 |
304 |
146 /** |
305 /** |
147 * Adds a script to the head of the document. |
306 * Adds a script to the head of the document. |
148 * |
307 * |
149 * @ignore |
308 * @ignore |
150 * |
309 * |
151 * @since 4.2.0 |
310 * @since 4.2.0 |
152 * |
311 * |
153 * @param {Object} src The url where the script is located. |
312 * @param {string} src The url where the script is located. |
|
313 * |
154 * @return {void} |
314 * @return {void} |
155 */ |
315 */ |
156 function addScript( src ) { |
316 function addScript( src ) { |
157 var script = document.createElement( 'script' ); |
317 var script = document.createElement( 'script' ); |
158 |
|
159 script.src = src; |
318 script.src = src; |
160 script.defer = script.type = 'text/javascript'; |
319 script.defer = true; |
161 document.getElementsByTagName( 'head' )[0].appendChild( script ); |
320 document.head.appendChild( script ); |
162 } |
321 } |
163 |
|
164 tests = Array( 'flag', 'emoji' ); |
|
165 |
322 |
166 settings.supports = { |
323 settings.supports = { |
167 everything: true, |
324 everything: true, |
168 everythingExceptFlag: true |
325 everythingExceptFlag: true |
169 }; |
326 }; |
170 |
327 |
171 /* |
328 // Create a promise for DOMContentLoaded since the worker logic may finish after the event has fired. |
172 * Tests the browser support for flag emojis and other emojis, and adjusts the |
329 var domReadyPromise = new Promise( function ( resolve ) { |
173 * support settings accordingly. |
330 document.addEventListener( 'DOMContentLoaded', resolve, { |
174 */ |
331 once: true |
175 for( ii = 0; ii < tests.length; ii++ ) { |
332 } ); |
176 settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] ); |
333 } ); |
177 |
334 |
178 settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ]; |
335 // Obtain the emoji support from the browser, asynchronously when possible. |
179 |
336 new Promise( function ( resolve ) { |
180 if ( 'flag' !== tests[ ii ] ) { |
337 var supportTests = getSessionSupportTests(); |
181 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ]; |
338 if ( supportTests ) { |
|
339 resolve( supportTests ); |
|
340 return; |
182 } |
341 } |
183 } |
342 |
184 |
343 if ( supportsWorkerOffloading() ) { |
185 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag; |
344 try { |
186 |
345 // Note that the functions are being passed as arguments due to minification. |
187 // Sets DOMReady to false and assigns a ready function to settings. |
346 var workerScript = |
188 settings.DOMReady = false; |
347 'postMessage(' + |
189 settings.readyCallback = function() { |
348 testEmojiSupports.toString() + |
190 settings.DOMReady = true; |
349 '(' + |
191 }; |
350 [ |
192 |
351 JSON.stringify( tests ), |
193 // When the browser can not render everything we need to load a polyfill. |
352 browserSupportsEmoji.toString(), |
194 if ( ! settings.supports.everything ) { |
353 emojiSetsRenderIdentically.toString() |
195 ready = function() { |
354 ].join( ',' ) + |
196 settings.readyCallback(); |
355 '));'; |
197 }; |
356 var blob = new Blob( [ workerScript ], { |
198 |
357 type: 'text/javascript' |
199 /* |
358 } ); |
200 * Cross-browser version of adding a dom ready event. |
359 var worker = new Worker( URL.createObjectURL( blob ), { name: 'wpTestEmojiSupports' } ); |
201 */ |
360 worker.onmessage = function ( event ) { |
202 if ( document.addEventListener ) { |
361 supportTests = event.data; |
203 document.addEventListener( 'DOMContentLoaded', ready, false ); |
362 setSessionSupportTests( supportTests ); |
204 window.addEventListener( 'load', ready, false ); |
363 worker.terminate(); |
205 } else { |
364 resolve( supportTests ); |
206 window.attachEvent( 'onload', ready ); |
365 }; |
207 document.attachEvent( 'onreadystatechange', function() { |
366 return; |
208 if ( 'complete' === document.readyState ) { |
367 } catch ( e ) {} |
209 settings.readyCallback(); |
368 } |
|
369 |
|
370 supportTests = testEmojiSupports( tests, browserSupportsEmoji, emojiSetsRenderIdentically ); |
|
371 setSessionSupportTests( supportTests ); |
|
372 resolve( supportTests ); |
|
373 } ) |
|
374 // Once the browser emoji support has been obtained from the session, finalize the settings. |
|
375 .then( function ( supportTests ) { |
|
376 /* |
|
377 * Tests the browser support for flag emojis and other emojis, and adjusts the |
|
378 * support settings accordingly. |
|
379 */ |
|
380 for ( var test in supportTests ) { |
|
381 settings.supports[ test ] = supportTests[ test ]; |
|
382 |
|
383 settings.supports.everything = |
|
384 settings.supports.everything && settings.supports[ test ]; |
|
385 |
|
386 if ( 'flag' !== test ) { |
|
387 settings.supports.everythingExceptFlag = |
|
388 settings.supports.everythingExceptFlag && |
|
389 settings.supports[ test ]; |
210 } |
390 } |
211 } ); |
391 } |
212 } |
392 |
213 |
393 settings.supports.everythingExceptFlag = |
214 src = settings.source || {}; |
394 settings.supports.everythingExceptFlag && |
215 |
395 ! settings.supports.flag; |
216 if ( src.concatemoji ) { |
396 |
217 addScript( src.concatemoji ); |
397 // Sets DOMReady to false and assigns a ready function to settings. |
218 } else if ( src.wpemoji && src.twemoji ) { |
398 settings.DOMReady = false; |
219 addScript( src.twemoji ); |
399 settings.readyCallback = function () { |
220 addScript( src.wpemoji ); |
400 settings.DOMReady = true; |
221 } |
401 }; |
222 } |
402 } ) |
223 |
403 .then( function () { |
|
404 return domReadyPromise; |
|
405 } ) |
|
406 .then( function () { |
|
407 // When the browser can not render everything we need to load a polyfill. |
|
408 if ( ! settings.supports.everything ) { |
|
409 settings.readyCallback(); |
|
410 |
|
411 var src = settings.source || {}; |
|
412 |
|
413 if ( src.concatemoji ) { |
|
414 addScript( src.concatemoji ); |
|
415 } else if ( src.wpemoji && src.twemoji ) { |
|
416 addScript( src.twemoji ); |
|
417 addScript( src.wpemoji ); |
|
418 } |
|
419 } |
|
420 } ); |
224 } )( window, document, window._wpemojiSettings ); |
421 } )( window, document, window._wpemojiSettings ); |