atd-nonvis-editor-plugin.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* jshint devel: true, onevar: false, smarttabs: true */
  2. /* global AtD, QTags, AtD_l10n_r0ar, edButtons, edButton, switchEditors, AtD_unbind_proofreader_listeners */
  3. /* exported AtD_unbind_proofreader_listeners */
  4. var AtD_qtbutton, autosave;
  5. /* convienence method to restore the text area from the preview div */
  6. function AtD_restore_text_area() {
  7. var content;
  8. /* swap the preview div for the textarea, notice how I have to restore the appropriate class/id/style attributes */
  9. if( jQuery('#atd-content').get(0) ) {
  10. AtD.remove('atd-content');
  11. content = jQuery('#atd-content').html();
  12. } else {
  13. AtD.remove('content');
  14. content = jQuery('#content').html();
  15. }
  16. if ( navigator.appName === 'Microsoft Internet Explorer' ) {
  17. content = content.replace(/<BR.*?class.*?atd_remove_me.*?>/gi, '\n');
  18. }
  19. // Remove emoji replacement images
  20. if ( typeof window.twemoji !== 'undefined' ) {
  21. content = content.replace( /<img [^>]+>/g, function( img ) {
  22. // The images should have class containing 'emoji'
  23. if ( img.indexOf( 'emoji' ) !== -1 ) {
  24. var alt = img.match( /alt="([^"]+)"/ );
  25. if ( alt && alt[1] && window.twemoji.test( alt[1] ) ) {
  26. return alt[1];
  27. }
  28. }
  29. return img;
  30. });
  31. }
  32. // jQuery('#content').replaceWith( AtD.content_canvas );
  33. jQuery('#content').val( content.replace(/\&lt\;/g, '<').replace(/\&gt\;/g, '>').replace(/\&amp;/g, '&') )
  34. .height(AtD.height)
  35. .show();
  36. jQuery('#atd-content').remove();
  37. if ( AtD_qtbutton ) {
  38. /* change the link text back to its original label */
  39. jQuery(AtD_qtbutton).val( AtD.getLang('button_proofread', 'proofread') );
  40. jQuery(AtD_qtbutton).css({ 'color' : '#464646' });
  41. /* enable the toolbar buttons */
  42. jQuery( AtD_qtbutton ).siblings('input').andSelf().attr( 'disabled', false );
  43. }
  44. /* restore autosave */
  45. if ( AtD.autosave !== undefined ) {
  46. if ( window.wp && window.wp.autosave && window.wp.autosave.server ) {
  47. window.wp.autosave.local.resume && window.wp.autosave.local.resume();
  48. window.wp.autosave.server.resume && window.wp.autosave.server.resume();
  49. } else {
  50. autosave = AtD.autosave;
  51. }
  52. }
  53. }
  54. // add the AtD button properly to quicktags
  55. if ( typeof(QTags) !== 'undefined' && QTags.addButton ) {
  56. jQuery(document).ready(function(){
  57. QTags.addButton( 'AtD', AtD_l10n_r0ar.button_proofread, AtD_check );
  58. });
  59. } else {
  60. edButtons[edButtons.length] = new edButton('ed_AtD', 'AtD', '', '', '');
  61. jQuery(document).ready(function($){
  62. $('#ed_AtD').replaceWith('<input type="button" id="ed_AtD" accesskey="" class="ed_button" onclick="AtD_check(this);" value="' + AtD_l10n_r0ar.button_proofread + '" />');
  63. });
  64. }
  65. function AtD_restore_if_proofreading() {
  66. if ( AtD_qtbutton && jQuery(AtD_qtbutton).val() === AtD.getLang('button_edit_text', 'edit text') ) {
  67. AtD_restore_text_area();
  68. }
  69. }
  70. /* exported AtD_unbind_proofreader_listeners */
  71. function AtD_unbind_proofreader_listeners() {
  72. jQuery('#save-post, #post-preview, #publish, #edButtonPreview').unbind('focus', AtD_restore_if_proofreading );
  73. jQuery('#add_poll, #add_image, #add_video, #add_audio, #add_media').unbind('click', AtD_restore_if_proofreading );
  74. jQuery('#post').unbind('submit', AtD_restore_if_proofreading );
  75. }
  76. function AtD_bind_proofreader_listeners() {
  77. jQuery('#save-post, #post-preview, #publish, #edButtonPreview').focus( AtD_restore_if_proofreading );
  78. jQuery('#add_poll, #add_image, #add_video, #add_audio, #add_media').click( AtD_restore_if_proofreading );
  79. jQuery('#post').submit( AtD_restore_if_proofreading );
  80. }
  81. /* where the magic happens, checks the spelling or restores the form */
  82. function AtD_check(button) {
  83. var callback, divHeight;
  84. if ( jQuery.isFunction( button ) ) {
  85. callback = button;
  86. if ( !AtD_qtbutton ) {
  87. AtD_qtbutton = jQuery( '#qt_content_AtD, #ed_AtD' ).get( 0 );
  88. }
  89. } else {
  90. if ( !button.id ) {
  91. button = button[0];
  92. }
  93. AtD_qtbutton = button;
  94. }
  95. if ( !jQuery('#content').length ) {
  96. if ( 'undefined' !== typeof callback ) {
  97. callback( 0 );
  98. }
  99. AtD_restore_if_proofreading();
  100. return;
  101. }
  102. /* If the text of the link says edit comment, then restore the textarea so the user can edit the text */
  103. if ( jQuery(AtD_qtbutton).val() === AtD.getLang('button_edit_text', 'edit text') ) {
  104. AtD_restore_text_area();
  105. } else {
  106. // Disable editor expand/scroll
  107. if ( window.editorExpand && jQuery( '#postdivrich' ).hasClass( 'wp-editor-expand' ) ) {
  108. AtD.wpEditorExpand = true;
  109. // window.editorExpand.off && window.editorExpand.off();
  110. } else {
  111. AtD.wpEditorExpand = false;
  112. }
  113. /* initialize some of the stuff related to this plugin */
  114. if ( ! AtD.height ) {
  115. AtD.height = jQuery('#content').height();
  116. AtD_bind_proofreader_listeners();
  117. /* make it so clicking the Visual button works when AtD is active */
  118. jQuery('#edButtonPreview').attr( 'onclick', null ).click( function() {
  119. AtD_restore_if_proofreading();
  120. switchEditors.go( 'content', 'tinymce' );
  121. });
  122. /* saved the textarea as we need to restore the original one for the toolbar to continue to function properly */
  123. AtD.content_canvas = jQuery('#content');
  124. /* store the autosave, we're going to make it empty during spellcheck to prevent auto saved text from being
  125. over written with empty text */
  126. AtD.autosave = autosave;
  127. } else {
  128. // Update the height
  129. AtD.height = jQuery('#content').height();
  130. }
  131. /* set the spell check link to a link that lets the user edit the text */
  132. /* disable the button to prevent a race condition where content is deleted if proofread is clicked with a check
  133. in progress. */
  134. jQuery(AtD_qtbutton).css({ 'color' : 'red' }).val( AtD.getLang('button_edit_text', 'edit text') ).attr('disabled', true);
  135. /* replace the div */
  136. var $replacement,
  137. $textarea = jQuery('#content'),
  138. text = $textarea.val().replace( /\&/g, '&amp;' ).replace( /</g, '&lt;' ).replace( /\>/g, '&gt;' ),
  139. fontFamily = $textarea.css('font-family'),
  140. fontSize = $textarea.css('font-size'),
  141. lineHeight = $textarea.css('line-height');
  142. if ( navigator.appName === 'Microsoft Internet Explorer' ) {
  143. text = text.replace( /[\n\r\f]/gm, '<BR class="atd_remove_me">' );
  144. }
  145. $replacement = jQuery( '<div class="input" id="atd-content">' + text + '</div>' );
  146. $textarea.after( $replacement ).hide();
  147. divHeight = AtD.height;
  148. // AtD disables resizing of the Text editor, normalize the size of the replacement div.
  149. if ( divHeight < 200 ) {
  150. divHeight = 200;
  151. } else if ( divHeight > 1000 ) {
  152. divHeight = 1000;
  153. }
  154. var toolBarHeight = jQuery('#ed_toolbar').height();
  155. $replacement.css( {
  156. overflow: 'auto',
  157. 'background-color': 'white',
  158. color: 'black',
  159. 'white-space': 'pre-wrap',
  160. padding: '10px',
  161. 'font-family': fontFamily || 'Consolas, Monaco, monospace',
  162. 'font-size': fontSize || '13px',
  163. 'line-height': lineHeight || '1.5',
  164. height: divHeight,
  165. 'margin-top': toolBarHeight+7+'px'
  166. } );
  167. /* kill autosave... :) */
  168. if ( window.wp && window.wp.autosave && window.wp.autosave.server ) {
  169. window.wp.autosave.local.suspend && window.wp.autosave.local.suspend();
  170. window.wp.autosave.server.suspend && window.wp.autosave.server.suspend();
  171. } else {
  172. autosave = function() { };
  173. }
  174. /* disable the toolbar buttons */
  175. jQuery( AtD_qtbutton ).siblings('input').andSelf().attr( 'disabled', true ); // using .arrt instead of .prop so it's compat with older WP and jQuery
  176. /* check the writing in the textarea */
  177. AtD.check('atd-content', {
  178. success: function(errorCount) {
  179. if ( Number( errorCount ) === 0 && typeof callback !== 'function' ) {
  180. alert( AtD.getLang('message_no_errors_found', 'No writing errors were found') );
  181. }
  182. AtD_restore_if_proofreading();
  183. },
  184. ready: function(errorCount) {
  185. jQuery(AtD_qtbutton).attr('disabled', false);
  186. if ( typeof callback === 'function' ) {
  187. callback( errorCount );
  188. }
  189. },
  190. error: function() {
  191. jQuery(AtD_qtbutton).attr('disabled', false);
  192. if ( typeof callback === 'function' ) {
  193. callback( -1 );
  194. } else {
  195. alert( AtD.getLang('message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.') );
  196. }
  197. AtD_restore_if_proofreading();
  198. },
  199. editSelection: function(element) {
  200. var text = prompt( AtD.getLang('dialog_replace_selection', 'Replace selection with:'), element.text() );
  201. if ( text != null ) {
  202. element.replaceWith( text );
  203. }
  204. },
  205. explain: function(url) {
  206. var left = (screen.width / 2) - (480 / 2);
  207. var top = (screen.height / 2) - (380 / 2);
  208. window.open( url, '', 'width=480,height=380,toolbar=0,status=0,resizable=0,location=0,menuBar=0,left=' + left + ',top=' + top).focus();
  209. },
  210. ignore: function(word) {
  211. jQuery.ajax({
  212. type : 'GET',
  213. url : AtD.rpc_ignore + encodeURI( word ).replace( /&/g, '%26'),
  214. format : 'raw',
  215. error : function(XHR, status, error) {
  216. if ( AtD.callback_f !== undefined && AtD.callback_f.error !== undefined ) {
  217. AtD.callback_f.error(status + ': ' + error);
  218. }
  219. }
  220. });
  221. }
  222. });
  223. }
  224. }