Diff: STRATO-apps/wordpress_03/app/wp-includes/js/wp-emoji.js
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
/**
2
+
* wp-emoji.js is used to replace emoji with images in browsers when the browser
3
+
* doesn't support emoji natively.
4
+
*
5
+
* @output wp-includes/js/wp-emoji.js
6
+
*/
7
+
8
+
( function( window, settings ) {
9
+
/**
10
+
* Replaces emoji with images when browsers don't support emoji.
11
+
*
12
+
* @since 4.2.0
13
+
* @access private
14
+
*
15
+
* @class
16
+
*
17
+
* @see Twitter Emoji library
18
+
* @link https://github.com/twitter/twemoji
19
+
*
20
+
* @return {Object} The wpEmoji parse and test functions.
21
+
*/
22
+
function wpEmoji() {
23
+
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
24
+
25
+
// Compression and maintain local scope.
26
+
document = window.document,
27
+
28
+
// Private.
29
+
twemoji, timer,
30
+
loaded = false,
31
+
count = 0,
32
+
ie11 = window.navigator.userAgent.indexOf( 'Trident/7.0' ) > 0;
33
+
34
+
/**
35
+
* Detect if the browser supports SVG.
36
+
*
37
+
* @since 4.6.0
38
+
* @private
39
+
*
40
+
* @see Modernizr
41
+
* @link https://github.com/Modernizr/Modernizr/blob/master/feature-detects/svg/asimg.js
42
+
*
43
+
* @return {boolean} True if the browser supports svg, false if not.
44
+
*/
45
+
function browserSupportsSvgAsImage() {
46
+
if ( !! document.implementation.hasFeature ) {
47
+
return document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' );
48
+
}
49
+
50
+
// document.implementation.hasFeature is deprecated. It can be presumed
51
+
// if future browsers remove it, the browser will support SVGs as images.
52
+
return true;
53
+
}
54
+
55
+
/**
56
+
* Runs when the document load event is fired, so we can do our first parse of
57
+
* the page.
58
+
*
59
+
* Listens to all the DOM mutations and checks for added nodes that contain
60
+
* emoji characters and replaces those with twitter emoji images.
61
+
*
62
+
* @since 4.2.0
63
+
* @private
64
+
*/
65
+
function load() {
66
+
if ( loaded ) {
67
+
return;
68
+
}
69
+
70
+
// Ensure twemoji is available on the global window before proceeding.
71
+
if ( typeof window.twemoji === 'undefined' ) {
72
+
// Break if waiting for longer than 30 seconds.
73
+
if ( count > 600 ) {
74
+
return;
75
+
}
76
+
77
+
// Still waiting.
78
+
window.clearTimeout( timer );
79
+
timer = window.setTimeout( load, 50 );
80
+
count++;
81
+
82
+
return;
83
+
}
84
+
85
+
twemoji = window.twemoji;
86
+
loaded = true;
87
+
88
+
// Initialize the mutation observer, which checks all added nodes for
89
+
// replaceable emoji characters.
90
+
if ( MutationObserver ) {
91
+
new MutationObserver( function( mutationRecords ) {
92
+
var i = mutationRecords.length,
93
+
addedNodes, removedNodes, ii, node;
94
+
95
+
while ( i-- ) {
96
+
addedNodes = mutationRecords[ i ].addedNodes;
97
+
removedNodes = mutationRecords[ i ].removedNodes;
98
+
ii = addedNodes.length;
99
+
100
+
/*
101
+
* Checks if an image has been replaced by a text element
102
+
* with the same text as the alternate description of the replaced image.
103
+
* (presumably because the image could not be loaded).
104
+
* If it is, do absolutely nothing.
105
+
*
106
+
* Node type 3 is a TEXT_NODE.
107
+
*
108
+
* @link https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
109
+
*/
110
+
if (
111
+
ii === 1 && removedNodes.length === 1 &&
112
+
addedNodes[0].nodeType === 3 &&
113
+
removedNodes[0].nodeName === 'IMG' &&
114
+
addedNodes[0].data === removedNodes[0].alt &&
115
+
'load-failed' === removedNodes[0].getAttribute( 'data-error' )
116
+
) {
117
+
return;
118
+
}
119
+
120
+
// Loop through all the added nodes.
121
+
while ( ii-- ) {
122
+
node = addedNodes[ ii ];
123
+
124
+
// Node type 3 is a TEXT_NODE.
125
+
if ( node.nodeType === 3 ) {
126
+
if ( ! node.parentNode ) {
127
+
continue;
128
+
}
129
+
130
+
if ( ie11 ) {
131
+
/*
132
+
* IE 11's implementation of MutationObserver is buggy.
133
+
* It unnecessarily splits text nodes when it encounters a HTML
134
+
* template interpolation symbol ( "{{", for example ). So, we
135
+
* join the text nodes back together as a work-around.
136
+
*
137
+
* Node type 3 is a TEXT_NODE.
138
+
*/
139
+
while( node.nextSibling && 3 === node.nextSibling.nodeType ) {
140
+
node.nodeValue = node.nodeValue + node.nextSibling.nodeValue;
141
+
node.parentNode.removeChild( node.nextSibling );
142
+
}
143
+
}
144
+
145
+
node = node.parentNode;
146
+
}
147
+
148
+
if ( test( node.textContent ) ) {
149
+
parse( node );
150
+
}
151
+
}
152
+
}
153
+
} ).observe( document.body, {
154
+
childList: true,
155
+
subtree: true
156
+
} );
157
+
}
158
+
159
+
parse( document.body );
160
+
}
161
+
162
+
/**
163
+
* Tests if a text string contains emoji characters.
164
+
*
165
+
* @since 4.3.0
166
+
*
167
+
* @memberOf wp.emoji
168
+
*
169
+
* @param {string} text The string to test.
170
+
*
171
+
* @return {boolean} Whether the string contains emoji characters.
172
+
*/
173
+
function test( text ) {
174
+
// Single char. U+20E3 to detect keycaps. U+00A9 "copyright sign" and U+00AE "registered sign" not included.
175
+
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]/,
176
+
// Surrogate pair range. Only tests for the second half.
177
+
pair = /[\uDC00-\uDFFF]/;
178
+
179
+
if ( text ) {
180
+
return pair.test( text ) || single.test( text );
181
+
}
182
+
183
+
return false;
184
+
}
185
+
186
+
/**
187
+
* Parses any emoji characters into Twemoji images.
188
+
*
189
+
* - When passed an element the emoji characters are replaced inline.
190
+
* - When passed a string the emoji characters are replaced and the result is
191
+
* returned.
192
+
*
193
+
* @since 4.2.0
194
+
*
195
+
* @memberOf wp.emoji
196
+
*
197
+
* @param {HTMLElement|string} object The element or string to parse.
198
+
* @param {Object} args Additional options for Twemoji.
199
+
*
200
+
* @return {HTMLElement|string} A string where all emoji are now image tags of
201
+
* emoji. Or the element that was passed as the first argument.
202
+
*/
203
+
function parse( object, args ) {
204
+
var params;
205
+
206
+
/*
207
+
* If the browser has full support, twemoji is not loaded or our
208
+
* object is not what was expected, we do not parse anything.
209
+
*/
210
+
if ( settings.supports.everything || ! twemoji || ! object ||
211
+
( 'string' !== typeof object && ( ! object.childNodes || ! object.childNodes.length ) ) ) {
212
+
213
+
return object;
214
+
}
215
+
216
+
// Compose the params for the twitter emoji library.
217
+
args = args || {};
218
+
params = {
219
+
base: browserSupportsSvgAsImage() ? settings.svgUrl : settings.baseUrl,
220
+
ext: browserSupportsSvgAsImage() ? settings.svgExt : settings.ext,
221
+
className: args.className || 'emoji',
222
+
callback: function( icon, options ) {
223
+
// Ignore some standard characters that TinyMCE recommends in its character map.
224
+
switch ( icon ) {
225
+
case 'a9':
226
+
case 'ae':
227
+
case '2122':
228
+
case '2194':
229
+
case '2660':
230
+
case '2663':
231
+
case '2665':
232
+
case '2666':
233
+
return false;
234
+
}
235
+
236
+
if ( settings.supports.everythingExceptFlag &&
237
+
! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) && // Country flags.
238
+
! /^(1f3f3-fe0f-200d-1f308|1f3f4-200d-2620-fe0f)$/.test( icon ) // Rainbow and pirate flags.
239
+
) {
240
+
return false;
241
+
}
242
+
243
+
return ''.concat( options.base, icon, options.ext );
244
+
},
245
+
attributes: function() {
246
+
return {
247
+
role: 'img'
248
+
};
249
+
},
250
+
onerror: function() {
251
+
if ( twemoji.parentNode ) {
252
+
this.setAttribute( 'data-error', 'load-failed' );
253
+
twemoji.parentNode.replaceChild( document.createTextNode( twemoji.alt ), twemoji );
254
+
}
255
+
},
256
+
doNotParse: function( node ) {
257
+
if (
258
+
node &&
259
+
node.className &&
260
+
typeof node.className === 'string' &&
261
+
node.className.indexOf( 'wp-exclude-emoji' ) !== -1
262
+
) {
263
+
// Do not parse this node. Emojis will not be replaced in this node and all sub-nodes.
264
+
return true;
265
+
}
266
+
267
+
return false;
268
+
}
269
+
};
270
+
271
+
if ( typeof args.imgAttr === 'object' ) {
272
+
params.attributes = function() {
273
+
return args.imgAttr;
274
+
};
275
+
}
276
+
277
+
return twemoji.parse( object, params );
278
+
}
279
+
280
+
load();
281
+
282
+
return {
283
+
parse: parse,
284
+
test: test
285
+
};
286
+
}
287
+
288
+
window.wp = window.wp || {};
289
+
290
+
/**
291
+
* @namespace wp.emoji
292
+
*/
293
+
window.wp.emoji = new wpEmoji();
294
+
295
+
} )( window, window._wpemojiSettings );
296
+