1 ( function( window, document, settings ) { |
1 ( function( window, document, settings ) { |
2 var src, ready; |
2 var src, ready, ii, tests; |
|
3 |
|
4 /* |
|
5 * Create a canvas element for testing native browser support |
|
6 * of emoji. |
|
7 */ |
|
8 var canvas = document.createElement( 'canvas' ); |
|
9 var context = canvas.getContext && canvas.getContext( '2d' ); |
|
10 |
|
11 /** |
|
12 * Check if two sets of Emoji characters render the same. |
|
13 * |
|
14 * @param set1 array Set of Emoji characters. |
|
15 * @param set2 array Set of Emoji characters. |
|
16 * @returns {boolean} True if the two sets render the same. |
|
17 */ |
|
18 function emojiSetsRenderIdentically( set1, set2 ) { |
|
19 var stringFromCharCode = String.fromCharCode; |
|
20 |
|
21 // Cleanup from previous test. |
|
22 context.clearRect( 0, 0, canvas.width, canvas.height ); |
|
23 context.fillText( stringFromCharCode.apply( this, set1 ), 0, 0 ); |
|
24 var rendered1 = canvas.toDataURL(); |
|
25 |
|
26 // Cleanup from previous test. |
|
27 context.clearRect( 0, 0, canvas.width, canvas.height ); |
|
28 context.fillText( stringFromCharCode.apply( this, set2 ), 0, 0 ); |
|
29 var rendered2 = canvas.toDataURL(); |
|
30 |
|
31 return rendered1 === rendered2; |
|
32 } |
3 |
33 |
4 /** |
34 /** |
5 * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph |
35 * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph |
6 * made of two characters, so some browsers (notably, Firefox OS X) don't support them. |
36 * made of two characters, so some browsers (notably, Firefox OS X) don't support them. |
7 * |
37 * |
8 * @since 4.2.0 |
38 * @since 4.2.0 |
9 * |
39 * |
10 * @param type {String} Whether to test for support of "simple" or "flag" emoji. |
40 * @param type {String} Whether to test for support of "flag" or "emoji". |
11 * @return {Boolean} True if the browser can render emoji, false if it cannot. |
41 * @return {Boolean} True if the browser can render emoji, false if it cannot. |
12 */ |
42 */ |
13 function browserSupportsEmoji( type ) { |
43 function browserSupportsEmoji( type ) { |
14 var canvas = document.createElement( 'canvas' ), |
44 var isIdentical; |
15 context = canvas.getContext && canvas.getContext( '2d' ); |
|
16 |
45 |
17 if ( ! context || ! context.fillText ) { |
46 if ( ! context || ! context.fillText ) { |
18 return false; |
47 return false; |
19 } |
48 } |
20 |
49 |
24 * check for bold rendering support to avoid invisible emoji in Chrome. |
53 * check for bold rendering support to avoid invisible emoji in Chrome. |
25 */ |
54 */ |
26 context.textBaseline = 'top'; |
55 context.textBaseline = 'top'; |
27 context.font = '600 32px Arial'; |
56 context.font = '600 32px Arial'; |
28 |
57 |
29 if ( type === 'flag' ) { |
58 switch ( type ) { |
30 /* |
59 case 'flag': |
31 * This works because the image will be one of three things: |
60 /* |
32 * - Two empty squares, if the browser doesn't render emoji |
61 * Test for UN flag compatibility. This is the least supported of the letter locale flags, |
33 * - Two squares with 'G' and 'B' in them, if the browser doesn't render flag emoji |
62 * so gives us an easy test for full support. |
34 * - The British flag |
63 * |
35 * |
64 * To test for support, we try to render it, and compare the rendering to how it would look if |
36 * The first two will encode to small images (1-2KB data URLs), the third will encode |
65 * the browser doesn't render it correctly ([U] + [N]). |
37 * to a larger image (4-5KB data URL). |
66 */ |
38 */ |
67 isIdentical = emojiSetsRenderIdentically( |
39 context.fillText( String.fromCharCode( 55356, 56812, 55356, 56807 ), 0, 0 ); |
68 [ 55356, 56826, 55356, 56819 ], |
40 return canvas.toDataURL().length > 3000; |
69 [ 55356, 56826, 8203, 55356, 56819 ] |
41 } else { |
70 ); |
42 /* |
71 |
43 * This creates a smiling emoji, and checks to see if there is any image data in the |
72 if ( isIdentical ) { |
44 * center pixel. In browsers that don't support emoji, the character will be rendered |
73 return false; |
45 * as an empty square, so the center pixel will be blank. |
74 } |
46 */ |
75 |
47 context.fillText( String.fromCharCode( 55357, 56835 ), 0, 0 ); |
76 /* |
48 return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; |
77 * Test for English flag compatibility. England is a country in the United Kingdom, it |
|
78 * does not have a two letter locale code but rather an five letter sub-division code. |
|
79 * |
|
80 * To test for support, we try to render it, and compare the rendering to how it would look if |
|
81 * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]). |
|
82 */ |
|
83 isIdentical = emojiSetsRenderIdentically( |
|
84 [ 55356, 57332, 56128, 56423, 56128, 56418, 56128, 56421, 56128, 56430, 56128, 56423, 56128, 56447 ], |
|
85 [ 55356, 57332, 8203, 56128, 56423, 8203, 56128, 56418, 8203, 56128, 56421, 8203, 56128, 56430, 8203, 56128, 56423, 8203, 56128, 56447 ] |
|
86 ); |
|
87 |
|
88 return ! isIdentical; |
|
89 case 'emoji': |
|
90 /* |
|
91 * She's the hero Emoji deserves, but not the one it needs right now. |
|
92 * |
|
93 * To test for support, try to render a new emoji (female superhero), |
|
94 * then compare it to how it would look if the browser doesn't render it correctly |
|
95 * (superhero + female sign). |
|
96 */ |
|
97 isIdentical = emojiSetsRenderIdentically( |
|
98 [55358, 56760, 9792, 65039], |
|
99 [55358, 56760, 8203, 9792, 65039] |
|
100 ); |
|
101 return ! isIdentical; |
49 } |
102 } |
|
103 |
|
104 return false; |
50 } |
105 } |
51 |
106 |
52 function addScript( src ) { |
107 function addScript( src ) { |
53 var script = document.createElement( 'script' ); |
108 var script = document.createElement( 'script' ); |
54 |
109 |
55 script.src = src; |
110 script.src = src; |
56 script.type = 'text/javascript'; |
111 script.defer = script.type = 'text/javascript'; |
57 document.getElementsByTagName( 'head' )[0].appendChild( script ); |
112 document.getElementsByTagName( 'head' )[0].appendChild( script ); |
58 } |
113 } |
59 |
114 |
|
115 tests = Array( 'flag', 'emoji' ); |
|
116 |
60 settings.supports = { |
117 settings.supports = { |
61 simple: browserSupportsEmoji( 'simple' ), |
118 everything: true, |
62 flag: browserSupportsEmoji( 'flag' ) |
119 everythingExceptFlag: true |
63 }; |
120 }; |
|
121 |
|
122 for( ii = 0; ii < tests.length; ii++ ) { |
|
123 settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] ); |
|
124 |
|
125 settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ]; |
|
126 |
|
127 if ( 'flag' !== tests[ ii ] ) { |
|
128 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ]; |
|
129 } |
|
130 } |
|
131 |
|
132 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag; |
64 |
133 |
65 settings.DOMReady = false; |
134 settings.DOMReady = false; |
66 settings.readyCallback = function() { |
135 settings.readyCallback = function() { |
67 settings.DOMReady = true; |
136 settings.DOMReady = true; |
68 }; |
137 }; |
69 |
138 |
70 if ( ! settings.supports.simple || ! settings.supports.flag ) { |
139 if ( ! settings.supports.everything ) { |
71 ready = function() { |
140 ready = function() { |
72 settings.readyCallback(); |
141 settings.readyCallback(); |
73 }; |
142 }; |
74 |
143 |
75 if ( document.addEventListener ) { |
144 if ( document.addEventListener ) { |