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