1( function( tinymce ) {
2 tinymce.PluginManager.add( 'wpemoji', function( editor ) {
3 var typing,
4 wp = window.wp,
5 settings = window._wpemojiSettings,
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
19 if ( ! wp || ! wp.emoji || settings.supports.everything ) {
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 ) {
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 */
64 editor.on( 'keyup', function( event ) {
65 if ( event.keyCode === 231 ) {
66 parseNode( editor.selection.getNode() );
67 }
68 } );
69 } else if ( ! isWin ) {
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 */
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 } );
134} )( window.tinymce );
135