]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/js/wp-emoji.js
WordPress 4.3.1-scripts
[autoinstalls/wordpress.git] / wp-includes / js / wp-emoji.js
1
2 ( function( window, settings ) {
3         function wpEmoji() {
4                 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
5
6                 /**
7                  * Flag to determine if we should replace emoji characters with images.
8                  *
9                  * @since 4.2.0
10                  *
11                  * @var Boolean
12                  */
13                 replaceEmoji = false,
14
15                 // Private
16                 twemoji, timer,
17                 loaded = false,
18                 count = 0;
19
20                 /**
21                  * Runs when the document load event is fired, so we can do our first parse of the page.
22                  *
23                  * @since 4.2.0
24                  */
25                 function load() {
26                         if ( loaded ) {
27                                 return;
28                         }
29
30                         if ( typeof window.twemoji === 'undefined' ) {
31                                 // Break if waiting for longer than 30 sec.
32                                 if ( count > 600 ) {
33                                         return;
34                                 }
35
36                                 // Still waiting.
37                                 window.clearTimeout( timer );
38                                 timer = window.setTimeout( load, 50 );
39                                 count++;
40
41                                 return;
42                         }
43
44                         twemoji = window.twemoji;
45                         loaded = true;
46
47                         if ( MutationObserver ) {
48                                 new MutationObserver( function( mutationRecords ) {
49                                         var i = mutationRecords.length,
50                                                 addedNodes, removedNodes, ii, node;
51
52                                         while ( i-- ) {
53                                                 addedNodes = mutationRecords[ i ].addedNodes;
54                                                 removedNodes = mutationRecords[ i ].removedNodes;
55                                                 ii = addedNodes.length;
56
57                                                 if (
58                                                         ii === 1 && removedNodes.length === 1 &&
59                                                         addedNodes[0].nodeType === 3 &&
60                                                         removedNodes[0].nodeName === 'IMG' &&
61                                                         addedNodes[0].data === removedNodes[0].alt
62                                                 ) {
63                                                         return;
64                                                 }
65
66                                                 while ( ii-- ) {
67                                                         node = addedNodes[ ii ];
68
69                                                         if ( node.nodeType === 3 ) {
70                                                                 node = node.parentNode;
71                                                         }
72
73                                                         if ( ! node || node.nodeType !== 1 ||
74                                                                 ( node.className && typeof node.className === 'string' && node.className.indexOf( 'wp-exclude-emoji' ) !== -1 ) ) {
75
76                                                                 continue;
77                                                         }
78
79                                                         if ( test( node.textContent ) ) {
80                                                                 parse( node );
81                                                         }
82                                                 }
83                                         }
84                                 } ).observe( document.body, {
85                                         childList: true,
86                                         subtree: true
87                                 } );
88                         }
89
90                         parse( document.body );
91                 }
92
93                 /**
94                  * Test if a text string contains emoji characters.
95                  *
96                  * @since 4.3.0
97                  *
98                  * @param {String} text The string to test
99                  *
100                  * @return {Boolean} Whether the string contains emoji characters.
101                  */
102                 function test( text ) {
103                         // Single char. U+20E3 to detect keycaps. U+00A9 "copyright sign" and U+00AE "registered sign" not included.
104                         var single = /[\u203C\u2049\u20E3\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2300\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638\u2639\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692\u2693\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753\u2754\u2755\u2757\u2763\u2764\u2795\u2796\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05\u2B06\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]/,
105                         // Surrogate pair range. Only tests for the second half. 
106                         pair = /[\uDC00-\uDFFF]/;
107
108                         if ( text ) {
109                                 return  pair.test( text ) || single.test( text );
110                         }
111
112                         return false;
113                 }
114
115                 /**
116                  * Given an element or string, parse any emoji characters into Twemoji images.
117                  *
118                  * @since 4.2.0
119                  *
120                  * @param {HTMLElement|String} object The element or string to parse.
121                  * @param {Object} args Additional options for Twemoji.
122                  */
123                 function parse( object, args ) {
124                         var params;
125
126                         if ( ! replaceEmoji || ! twemoji || ! object ||
127                                 ( 'string' !== typeof object && ( ! object.childNodes || ! object.childNodes.length ) ) ) {
128
129                                 return object;
130                         }
131
132                         args = args || {};
133                         params = {
134                                 base: settings.baseUrl,
135                                 ext: settings.ext,
136                                 className: args.className || 'emoji',
137                                 callback: function( icon, options ) {
138                                         // Ignore some standard characters that TinyMCE recommends in its character map.
139                                         switch ( icon ) {
140                                                 case 'a9':
141                                                 case 'ae':
142                                                 case '2122':
143                                                 case '2194':
144                                                 case '2660':
145                                                 case '2663':
146                                                 case '2665':
147                                                 case '2666':
148                                                         return false;
149                                         }
150
151                                         if ( ! settings.supports.flag && settings.supports.simple &&
152                                                 ! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) ) {
153
154                                                 return false;
155                                         }
156
157                                         return ''.concat( options.base, icon, options.ext );
158                                 }
159                         };
160
161                         if ( typeof args.imgAttr === 'object' ) {
162                                 params.attributes = function() {
163                                         return args.imgAttr;
164                                 };
165                         }
166
167                         return twemoji.parse( object, params );
168                 }
169
170                 /**
171                  * Initialize our emoji support, and set up listeners.
172                  */
173                 if ( settings ) {
174                         replaceEmoji = ! settings.supports.simple || ! settings.supports.flag;
175
176                         if ( settings.DOMReady ) {
177                                 load();
178                         } else {
179                                 settings.readyCallback = load;
180                         }
181                 }
182
183                 return {
184                         replaceEmoji: replaceEmoji,
185                         parse: parse,
186                         test: test
187                 };
188         }
189
190         window.wp = window.wp || {};
191         window.wp.emoji = new wpEmoji();
192
193 } )( window, window._wpemojiSettings );