|
1 /** |
|
2 * @output wp-includes/js/wp-emoji-loader.js |
|
3 */ |
|
4 |
1 ( function( window, document, settings ) { |
5 ( function( window, document, settings ) { |
2 var src, ready, ii, tests; |
6 var src, ready, ii, tests; |
3 |
7 |
4 /* |
8 // Create a canvas element for testing native browser support of emoji. |
5 * Create a canvas element for testing native browser support |
|
6 * of emoji. |
|
7 */ |
|
8 var canvas = document.createElement( 'canvas' ); |
9 var canvas = document.createElement( 'canvas' ); |
9 var context = canvas.getContext && canvas.getContext( '2d' ); |
10 var context = canvas.getContext && canvas.getContext( '2d' ); |
10 |
11 |
11 /** |
12 /** |
12 * Check if two sets of Emoji characters render the same. |
13 * Checks if two sets of Emoji characters render the same visually. |
13 * |
14 * |
14 * @param set1 array Set of Emoji characters. |
15 * @since 4.9.0 |
15 * @param set2 array Set of Emoji characters. |
16 * |
16 * @returns {boolean} True if the two sets render the same. |
17 * @private |
|
18 * |
|
19 * @param {number[]} set1 Set of Emoji character codes. |
|
20 * @param {number[]} set2 Set of Emoji character codes. |
|
21 * |
|
22 * @return {boolean} True if the two sets render the same. |
17 */ |
23 */ |
18 function emojiSetsRenderIdentically( set1, set2 ) { |
24 function emojiSetsRenderIdentically( set1, set2 ) { |
19 var stringFromCharCode = String.fromCharCode; |
25 var stringFromCharCode = String.fromCharCode; |
20 |
26 |
21 // Cleanup from previous test. |
27 // Cleanup from previous test. |
30 |
36 |
31 return rendered1 === rendered2; |
37 return rendered1 === rendered2; |
32 } |
38 } |
33 |
39 |
34 /** |
40 /** |
35 * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph |
41 * Detects if the browser supports rendering emoji or flag emoji. |
36 * made of two characters, so some browsers (notably, Firefox OS X) don't support them. |
42 * |
|
43 * Flag emoji are a single glyph made of two characters, so some browsers |
|
44 * (notably, Firefox OS X) don't support them. |
37 * |
45 * |
38 * @since 4.2.0 |
46 * @since 4.2.0 |
39 * |
47 * |
40 * @param type {String} Whether to test for support of "flag" or "emoji". |
48 * @private |
41 * @return {Boolean} True if the browser can render emoji, false if it cannot. |
49 * |
|
50 * @param {string} type Whether to test for support of "flag" or "emoji". |
|
51 * |
|
52 * @return {boolean} True if the browser can render emoji, false if it cannot. |
42 */ |
53 */ |
43 function browserSupportsEmoji( type ) { |
54 function browserSupportsEmoji( type ) { |
44 var isIdentical; |
55 var isIdentical; |
45 |
56 |
46 if ( ! context || ! context.fillText ) { |
57 if ( ! context || ! context.fillText ) { |
63 * |
74 * |
64 * To test for support, we try to render it, and compare the rendering to how it would look if |
75 * To test for support, we try to render it, and compare the rendering to how it would look if |
65 * the browser doesn't render it correctly ([U] + [N]). |
76 * the browser doesn't render it correctly ([U] + [N]). |
66 */ |
77 */ |
67 isIdentical = emojiSetsRenderIdentically( |
78 isIdentical = emojiSetsRenderIdentically( |
68 [ 55356, 56826, 55356, 56819 ], |
79 [ 0xD83C, 0xDDFA, 0xD83C, 0xDDF3 ], |
69 [ 55356, 56826, 8203, 55356, 56819 ] |
80 [ 0xD83C, 0xDDFA, 0x200B, 0xD83C, 0xDDF3 ] |
70 ); |
81 ); |
71 |
82 |
72 if ( isIdentical ) { |
83 if ( isIdentical ) { |
73 return false; |
84 return false; |
74 } |
85 } |
79 * |
90 * |
80 * To test for support, we try to render it, and compare the rendering to how it would look if |
91 * 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]). |
92 * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]). |
82 */ |
93 */ |
83 isIdentical = emojiSetsRenderIdentically( |
94 isIdentical = emojiSetsRenderIdentically( |
84 [ 55356, 57332, 56128, 56423, 56128, 56418, 56128, 56421, 56128, 56430, 56128, 56423, 56128, 56447 ], |
95 [ 0xD83C, 0xDFF4, 0xDB40, 0xDC67, 0xDB40, 0xDC62, 0xDB40, 0xDC65, 0xDB40, 0xDC6E, 0xDB40, 0xDC67, 0xDB40, 0xDC7F ], |
85 [ 55356, 57332, 8203, 56128, 56423, 8203, 56128, 56418, 8203, 56128, 56421, 8203, 56128, 56430, 8203, 56128, 56423, 8203, 56128, 56447 ] |
96 [ 0xD83C, 0xDFF4, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC62, 0x200B, 0xDB40, 0xDC65, 0x200B, 0xDB40, 0xDC6E, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC7F ] |
86 ); |
97 ); |
87 |
98 |
88 return ! isIdentical; |
99 return ! isIdentical; |
89 case 'emoji': |
100 case 'emoji': |
90 /* |
101 /* |
91 * She's the hero Emoji deserves, but not the one it needs right now. |
102 * Love is love. |
92 * |
103 * |
93 * To test for support, try to render a new emoji (female superhero), |
104 * To test for Emoji 12 support, try to render a new emoji: men holding hands, with different skin |
94 * then compare it to how it would look if the browser doesn't render it correctly |
105 * tone modifiers. |
95 * (superhero + female sign). |
106 * |
|
107 * When updating this test for future Emoji releases, ensure that individual emoji that make up the |
|
108 * sequence come from older emoji standards. |
96 */ |
109 */ |
97 isIdentical = emojiSetsRenderIdentically( |
110 isIdentical = emojiSetsRenderIdentically( |
98 [55358, 56760, 9792, 65039], |
111 [0xD83D, 0xDC68, 0xD83C, 0xDFFE, 0x200D, 0xD83E, 0xDD1D, 0x200D, 0xD83D, 0xDC68, 0xD83C, 0xDFFC], |
99 [55358, 56760, 8203, 9792, 65039] |
112 [0xD83D, 0xDC68, 0xD83C, 0xDFFE, 0x200B, 0xD83E, 0xDD1D, 0x200B, 0xD83D, 0xDC68, 0xD83C, 0xDFFC] |
100 ); |
113 ); |
|
114 |
101 return ! isIdentical; |
115 return ! isIdentical; |
102 } |
116 } |
103 |
117 |
104 return false; |
118 return false; |
105 } |
119 } |
106 |
120 |
|
121 /** |
|
122 * Adds a script to the head of the document. |
|
123 * |
|
124 * @ignore |
|
125 * |
|
126 * @since 4.2.0 |
|
127 * |
|
128 * @param {Object} src The url where the script is located. |
|
129 * @return {void} |
|
130 */ |
107 function addScript( src ) { |
131 function addScript( src ) { |
108 var script = document.createElement( 'script' ); |
132 var script = document.createElement( 'script' ); |
109 |
133 |
110 script.src = src; |
134 script.src = src; |
111 script.defer = script.type = 'text/javascript'; |
135 script.defer = script.type = 'text/javascript'; |
129 } |
157 } |
130 } |
158 } |
131 |
159 |
132 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag; |
160 settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag; |
133 |
161 |
|
162 // Sets DOMReady to false and assigns a ready function to settings. |
134 settings.DOMReady = false; |
163 settings.DOMReady = false; |
135 settings.readyCallback = function() { |
164 settings.readyCallback = function() { |
136 settings.DOMReady = true; |
165 settings.DOMReady = true; |
137 }; |
166 }; |
138 |
167 |
|
168 // When the browser can not render everything we need to load a polyfill. |
139 if ( ! settings.supports.everything ) { |
169 if ( ! settings.supports.everything ) { |
140 ready = function() { |
170 ready = function() { |
141 settings.readyCallback(); |
171 settings.readyCallback(); |
142 }; |
172 }; |
143 |
173 |
|
174 /* |
|
175 * Cross-browser version of adding a dom ready event. |
|
176 */ |
144 if ( document.addEventListener ) { |
177 if ( document.addEventListener ) { |
145 document.addEventListener( 'DOMContentLoaded', ready, false ); |
178 document.addEventListener( 'DOMContentLoaded', ready, false ); |
146 window.addEventListener( 'load', ready, false ); |
179 window.addEventListener( 'load', ready, false ); |
147 } else { |
180 } else { |
148 window.attachEvent( 'onload', ready ); |
181 window.attachEvent( 'onload', ready ); |