author | ymh <ymh.work@gmail.com> |
Fri, 05 Sep 2025 18:40:08 +0200 | |
changeset 21 | 48c4eec2b7e6 |
parent 16 | a86126ab1dd4 |
permissions | -rw-r--r-- |
9 | 1 |
( function( tinymce ) { |
5 | 2 |
tinymce.PluginManager.add( 'wpemoji', function( editor ) { |
3 |
var typing, |
|
9 | 4 |
wp = window.wp, |
5 |
settings = window._wpemojiSettings, |
|
5 | 6 |
env = tinymce.Env, |
7 |
ua = window.navigator.userAgent, |
|
8 |
isWin = ua.indexOf( 'Windows' ) > -1, |
|
9 |
isWin8 = ( function() { |
|
10 |
var match = ua.match( /Windows NT 6\.(\d)/ ); |
|
11 |
||
12 |
if ( match && match[1] > 1 ) { |
|
13 |
return true; |
|
14 |
} |
|
15 |
||
16 |
return false; |
|
17 |
}()); |
|
18 |
||
7
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
19 |
if ( ! wp || ! wp.emoji || settings.supports.everything ) { |
5 | 20 |
return; |
21 |
} |
|
22 |
||
23 |
function setImgAttr( image ) { |
|
24 |
image.className = 'emoji'; |
|
25 |
image.setAttribute( 'data-mce-resize', 'false' ); |
|
26 |
image.setAttribute( 'data-mce-placeholder', '1' ); |
|
27 |
image.setAttribute( 'data-wp-emoji', '1' ); |
|
28 |
} |
|
29 |
||
30 |
function replaceEmoji( node ) { |
|
31 |
var imgAttr = { |
|
32 |
'data-mce-resize': 'false', |
|
33 |
'data-mce-placeholder': '1', |
|
34 |
'data-wp-emoji': '1' |
|
35 |
}; |
|
36 |
||
37 |
wp.emoji.parse( node, { imgAttr: imgAttr } ); |
|
38 |
} |
|
39 |
||
40 |
// Test if the node text contains emoji char(s) and replace. |
|
41 |
function parseNode( node ) { |
|
42 |
var selection, bookmark; |
|
43 |
||
44 |
if ( node && window.twemoji && window.twemoji.test( node.textContent || node.innerText ) ) { |
|
45 |
if ( env.webkit ) { |
|
46 |
selection = editor.selection; |
|
47 |
bookmark = selection.getBookmark(); |
|
48 |
} |
|
49 |
||
50 |
replaceEmoji( node ); |
|
51 |
||
52 |
if ( env.webkit ) { |
|
53 |
selection.moveToBookmark( bookmark ); |
|
54 |
} |
|
55 |
} |
|
56 |
} |
|
57 |
||
58 |
if ( isWin8 ) { |
|
16 | 59 |
/* |
60 |
* Windows 8+ emoji can be "typed" with the onscreen keyboard. |
|
61 |
* That triggers the normal keyboard events, but not the 'input' event. |
|
62 |
* Thankfully it sets keyCode 231 when the onscreen keyboard inserts any emoji. |
|
63 |
*/ |
|
5 | 64 |
editor.on( 'keyup', function( event ) { |
65 |
if ( event.keyCode === 231 ) { |
|
66 |
parseNode( editor.selection.getNode() ); |
|
67 |
} |
|
68 |
} ); |
|
69 |
} else if ( ! isWin ) { |
|
16 | 70 |
/* |
71 |
* In MacOS inserting emoji doesn't trigger the stanradr keyboard events. |
|
72 |
* Thankfully it triggers the 'input' event. |
|
73 |
* This works in Android and iOS as well. |
|
74 |
*/ |
|
5 | 75 |
editor.on( 'keydown keyup', function( event ) { |
76 |
typing = ( event.type === 'keydown' ); |
|
77 |
} ); |
|
78 |
||
79 |
editor.on( 'input', function() { |
|
80 |
if ( typing ) { |
|
81 |
return; |
|
82 |
} |
|
83 |
||
84 |
parseNode( editor.selection.getNode() ); |
|
85 |
}); |
|
86 |
} |
|
87 |
||
88 |
editor.on( 'setcontent', function( event ) { |
|
89 |
var selection = editor.selection, |
|
90 |
node = selection.getNode(); |
|
91 |
||
92 |
if ( window.twemoji && window.twemoji.test( node.textContent || node.innerText ) ) { |
|
93 |
replaceEmoji( node ); |
|
94 |
||
95 |
// In IE all content in the editor is left selected after wp.emoji.parse()... |
|
96 |
// Collapse the selection to the beginning. |
|
97 |
if ( env.ie && env.ie < 9 && event.load && node && node.nodeName === 'BODY' ) { |
|
98 |
selection.collapse( true ); |
|
99 |
} |
|
100 |
} |
|
101 |
} ); |
|
102 |
||
103 |
// Convert Twemoji compatible pasted emoji replacement images into our format. |
|
104 |
editor.on( 'PastePostProcess', function( event ) { |
|
105 |
if ( window.twemoji ) { |
|
106 |
tinymce.each( editor.dom.$( 'img.emoji', event.node ), function( image ) { |
|
107 |
if ( image.alt && window.twemoji.test( image.alt ) ) { |
|
108 |
setImgAttr( image ); |
|
109 |
} |
|
110 |
}); |
|
111 |
} |
|
112 |
}); |
|
113 |
||
114 |
editor.on( 'postprocess', function( event ) { |
|
115 |
if ( event.content ) { |
|
116 |
event.content = event.content.replace( /<img[^>]+data-wp-emoji="[^>]+>/g, function( img ) { |
|
117 |
var alt = img.match( /alt="([^"]+)"/ ); |
|
118 |
||
119 |
if ( alt && alt[1] ) { |
|
120 |
return alt[1]; |
|
121 |
} |
|
122 |
||
123 |
return img; |
|
124 |
}); |
|
125 |
} |
|
126 |
} ); |
|
127 |
||
128 |
editor.on( 'resolvename', function( event ) { |
|
129 |
if ( event.target.nodeName === 'IMG' && editor.dom.getAttrib( event.target, 'data-wp-emoji' ) ) { |
|
130 |
event.preventDefault(); |
|
131 |
} |
|
132 |
} ); |
|
133 |
} ); |
|
9 | 134 |
} )( window.tinymce ); |