| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * wp-emoji.js is used to replace emoji with images in browsers when the browser | 
					
						
							|  |  |  |  * doesn't support emoji natively. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @output wp-includes/js/wp-emoji.js | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ( function( window, settings ) { | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Replaces emoji with images when browsers don't support emoji. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since      4.2.0 | 
					
						
							|  |  |  | 	 * @access     private | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @class | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @see  Twitter Emoji library | 
					
						
							|  |  |  | 	 * @link https://github.com/twitter/twemoji
 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return {Object} The wpEmoji parse and test functions. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	function wpEmoji() { | 
					
						
							|  |  |  | 		var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Compression and maintain local scope
 | 
					
						
							|  |  |  | 		document = window.document, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Private
 | 
					
						
							|  |  |  | 		twemoji, timer, | 
					
						
							|  |  |  | 		loaded = false, | 
					
						
							|  |  |  | 		count = 0, | 
					
						
							|  |  |  | 		ie11 = window.navigator.userAgent.indexOf( 'Trident/7.0' ) > 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * Detect if the browser supports SVG. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.6.0 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @private | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @see Modernizr | 
					
						
							|  |  |  | 		 * @link https://github.com/Modernizr/Modernizr/blob/master/feature-detects/svg/asimg.js
 | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @return {boolean} True if the browser supports svg, false if not. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 		function browserSupportsSvgAsImage() { | 
					
						
							|  |  |  | 			if ( !! document.implementation.hasFeature ) { | 
					
						
							|  |  |  | 				return document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// document.implementation.hasFeature is deprecated. It can be presumed
 | 
					
						
							|  |  |  | 			// if future browsers remove it, the browser will support SVGs as images.
 | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * Runs when the document load event is fired, so we can do our first parse of | 
					
						
							|  |  |  | 		 * the page. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * Listens to all the DOM mutations and checks for added nodes that contain | 
					
						
							|  |  |  | 		 * emoji characters and replaces those with twitter emoji images. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.2.0 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @private | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 		function load() { | 
					
						
							|  |  |  | 			if ( loaded ) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 			// Ensure twemoji is available on the global window before proceeding.
 | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 			if ( typeof window.twemoji === 'undefined' ) { | 
					
						
							|  |  |  | 				// Break if waiting for longer than 30 sec.
 | 
					
						
							|  |  |  | 				if ( count > 600 ) { | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Still waiting.
 | 
					
						
							|  |  |  | 				window.clearTimeout( timer ); | 
					
						
							|  |  |  | 				timer = window.setTimeout( load, 50 ); | 
					
						
							|  |  |  | 				count++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			twemoji = window.twemoji; | 
					
						
							|  |  |  | 			loaded = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 			// Initialize the mutation observer, which checks all added nodes for
 | 
					
						
							|  |  |  | 			// replaceable emoji characters.
 | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 			if ( MutationObserver ) { | 
					
						
							|  |  |  | 				new MutationObserver( function( mutationRecords ) { | 
					
						
							|  |  |  | 					var i = mutationRecords.length, | 
					
						
							|  |  |  | 						addedNodes, removedNodes, ii, node; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					while ( i-- ) { | 
					
						
							|  |  |  | 						addedNodes = mutationRecords[ i ].addedNodes; | 
					
						
							|  |  |  | 						removedNodes = mutationRecords[ i ].removedNodes; | 
					
						
							|  |  |  | 						ii = addedNodes.length; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 						/* | 
					
						
							|  |  |  | 						 * Checks if an image has been replaced by a text element | 
					
						
							|  |  |  | 						 * with the same text as the alternate description of the replaced image. | 
					
						
							|  |  |  | 						 * (presumably because the image could not be loaded). | 
					
						
							|  |  |  | 						 * If it is, do absolutely nothing. | 
					
						
							|  |  |  | 						 * | 
					
						
							|  |  |  | 						 * Node type 3 is a TEXT_NODE. | 
					
						
							|  |  |  | 						 * | 
					
						
							|  |  |  | 						 * @link https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
 | 
					
						
							|  |  |  | 						 */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							ii === 1 && removedNodes.length === 1 && | 
					
						
							|  |  |  | 							addedNodes[0].nodeType === 3 && | 
					
						
							|  |  |  | 							removedNodes[0].nodeName === 'IMG' && | 
					
						
							|  |  |  | 							addedNodes[0].data === removedNodes[0].alt && | 
					
						
							|  |  |  | 							'load-failed' === removedNodes[0].getAttribute( 'data-error' ) | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							return; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 						// Loop through all the added nodes.
 | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 						while ( ii-- ) { | 
					
						
							|  |  |  | 							node = addedNodes[ ii ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 							// Node type 3 is a TEXT_NODE.
 | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 							if ( node.nodeType === 3 ) { | 
					
						
							|  |  |  | 								if ( ! node.parentNode ) { | 
					
						
							|  |  |  | 									continue; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								if ( ie11 ) { | 
					
						
							|  |  |  | 									/* | 
					
						
							|  |  |  | 									 * IE 11's implementation of MutationObserver is buggy. | 
					
						
							|  |  |  | 									 * It unnecessarily splits text nodes when it encounters a HTML | 
					
						
							|  |  |  | 									 * template interpolation symbol ( "{{", for example ). So, we | 
					
						
							|  |  |  | 									 * join the text nodes back together as a work-around. | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 									 * | 
					
						
							|  |  |  | 									 * Node type 3 is a TEXT_NODE. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 									 */ | 
					
						
							|  |  |  | 									while( node.nextSibling && 3 === node.nextSibling.nodeType ) { | 
					
						
							|  |  |  | 										node.nodeValue = node.nodeValue + node.nextSibling.nodeValue; | 
					
						
							|  |  |  | 										node.parentNode.removeChild( node.nextSibling ); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								node = node.parentNode; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 							/* | 
					
						
							|  |  |  | 							 * If the class name of a non-element node contains 'wp-exclude-emoji' ignore it. | 
					
						
							|  |  |  | 							 * | 
					
						
							|  |  |  | 							 * Node type 1 is an ELEMENT_NODE. | 
					
						
							|  |  |  | 							 */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 							if ( ! node || node.nodeType !== 1 || | 
					
						
							|  |  |  | 								( node.className && typeof node.className === 'string' && node.className.indexOf( 'wp-exclude-emoji' ) !== -1 ) ) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							if ( test( node.textContent ) ) { | 
					
						
							|  |  |  | 								parse( node ); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} ).observe( document.body, { | 
					
						
							|  |  |  | 					childList: true, | 
					
						
							|  |  |  | 					subtree: true | 
					
						
							|  |  |  | 				} ); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			parse( document.body ); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * Tests if a text string contains emoji characters. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.3.0 | 
					
						
							|  |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @memberOf wp.emoji | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @param {string} text The string to test. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @return {boolean} Whether the string contains emoji characters. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 		function test( text ) { | 
					
						
							|  |  |  | 			// Single char. U+20E3 to detect keycaps. U+00A9 "copyright sign" and U+00AE "registered sign" not included.
 | 
					
						
							|  |  |  | 			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]/, | 
					
						
							|  |  |  | 			// Surrogate pair range. Only tests for the second half.
 | 
					
						
							|  |  |  | 			pair = /[\uDC00-\uDFFF]/; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ( text ) { | 
					
						
							|  |  |  | 				return  pair.test( text ) || single.test( text ); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * Parses any emoji characters into Twemoji images. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * - When passed an element the emoji characters are replaced inline. | 
					
						
							|  |  |  | 		 * - When passed a string the emoji characters are replaced and the result is | 
					
						
							|  |  |  | 		 *   returned. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.2.0 | 
					
						
							|  |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * @memberOf wp.emoji | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @param {HTMLElement|string} object The element or string to parse. | 
					
						
							|  |  |  | 		 * @param {Object}             args   Additional options for Twemoji. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @return {HTMLElement|string} A string where all emoji are now image tags of | 
					
						
							|  |  |  | 		 *                              emoji. Or the element that was passed as the first argument. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 		function parse( object, args ) { | 
					
						
							|  |  |  | 			var params; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 			/* | 
					
						
							|  |  |  | 			 * If the browser has full support, twemoji is not loaded or our | 
					
						
							|  |  |  | 			 * object is not what was expected, we do not parse anything. | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 			if ( settings.supports.everything || ! twemoji || ! object || | 
					
						
							|  |  |  | 				( 'string' !== typeof object && ( ! object.childNodes || ! object.childNodes.length ) ) ) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				return object; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 			// Compose the params for the twitter emoji library.
 | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 			args = args || {}; | 
					
						
							|  |  |  | 			params = { | 
					
						
							|  |  |  | 				base: browserSupportsSvgAsImage() ? settings.svgUrl : settings.baseUrl, | 
					
						
							|  |  |  | 				ext:  browserSupportsSvgAsImage() ? settings.svgExt : settings.ext, | 
					
						
							|  |  |  | 				className: args.className || 'emoji', | 
					
						
							|  |  |  | 				callback: function( icon, options ) { | 
					
						
							|  |  |  | 					// Ignore some standard characters that TinyMCE recommends in its character map.
 | 
					
						
							|  |  |  | 					switch ( icon ) { | 
					
						
							|  |  |  | 						case 'a9': | 
					
						
							|  |  |  | 						case 'ae': | 
					
						
							|  |  |  | 						case '2122': | 
					
						
							|  |  |  | 						case '2194': | 
					
						
							|  |  |  | 						case '2660': | 
					
						
							|  |  |  | 						case '2663': | 
					
						
							|  |  |  | 						case '2665': | 
					
						
							|  |  |  | 						case '2666': | 
					
						
							|  |  |  | 							return false; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if ( settings.supports.everythingExceptFlag && | 
					
						
							|  |  |  | 						! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) && // Country flags
 | 
					
						
							|  |  |  | 						! /^(1f3f3-fe0f-200d-1f308|1f3f4-200d-2620-fe0f)$/.test( icon )             // Rainbow and pirate flags
 | 
					
						
							|  |  |  | 					) { | 
					
						
							|  |  |  | 						return false; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					return ''.concat( options.base, icon, options.ext ); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				onerror: function() { | 
					
						
							|  |  |  | 					if ( twemoji.parentNode ) { | 
					
						
							|  |  |  | 						this.setAttribute( 'data-error', 'load-failed' ); | 
					
						
							|  |  |  | 						twemoji.parentNode.replaceChild( document.createTextNode( twemoji.alt ), twemoji ); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ( typeof args.imgAttr === 'object' ) { | 
					
						
							|  |  |  | 				params.attributes = function() { | 
					
						
							|  |  |  | 					return args.imgAttr; | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return twemoji.parse( object, params ); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * Initialize our emoji support, and set up listeners. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		if ( settings ) { | 
					
						
							|  |  |  | 			if ( settings.DOMReady ) { | 
					
						
							|  |  |  | 				load(); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				settings.readyCallback = load; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			parse: parse, | 
					
						
							|  |  |  | 			test: test | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window.wp = window.wp || {}; | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @namespace wp.emoji | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	window.wp.emoji = new wpEmoji(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } )( window, window._wpemojiSettings ); |