[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

/assets/js/ -> editor.js (source)

   1  /* global $gp_editor_options, $gp */
   2  /* eslint camelcase: "off" */
   3  $gp.editor = (
   4      function( $ ) {
   5          return {
   6              current: null,
   7              orginal_translations: null,
   8              init: function( table ) {
   9                  var $previewRows;
  10  
  11                  $gp.init();
  12                  $gp.editor.table = table;
  13                  $gp.editor.install_hooks();
  14  
  15                  // Open the first editor if the current table has only one.
  16                  $previewRows = $gp.editor.table.find( 'tr.preview' );
  17                  if ( 1 === $previewRows.length ) {
  18                      $gp.editor.show( $previewRows.eq( 0 ) );
  19                  }
  20              },
  21              original_id_from_row_id: function( row_id ) {
  22                  return row_id.split( '-' )[ 0 ];
  23              },
  24              translation_id_from_row_id: function( row_id ) {
  25                  return row_id.split( '-' )[ 1 ];
  26              },
  27              show: function( element ) {
  28                  var row_id = element.closest( 'tr' ).attr( 'row' );
  29                  var editor = $( '#editor-' + row_id );
  30                  var gmt_date_added = $( '#gmt-date-added-' + row_id );
  31                  var local_date_added = $( '#local-date-added-' + row_id );
  32                  var offset = new Date().getTimezoneOffset();
  33                  var gmt_date = new Date( gmt_date_added.text() );
  34                  var local_date = new Date( ( gmt_date - ( offset * 60 * 1000 ) ) );
  35  
  36                  if ( ! editor.length ) {
  37                      return;
  38                  }
  39                  if ( $gp.editor.current ) {
  40                      $gp.editor.hide();
  41                  }
  42                  editor.preview = $( '#preview-' + row_id );
  43                  editor.row_id = row_id;
  44                  editor.original_id = $gp.editor.original_id_from_row_id( row_id );
  45                  editor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
  46  
  47                  editor.orginal_translations = $( 'textarea[name="translation[' + editor.original_id + '][]"]', editor ).map( function() {
  48                      return this.value;
  49                  } ).get();
  50  
  51                  $gp.editor.current = editor;
  52  
  53                  local_date_added.text( local_date.toLocaleDateString() + ' ' + local_date.toLocaleTimeString() );
  54  
  55                  editor.show();
  56                  editor.preview.hide();
  57                  $( 'textarea:first', editor ).focus();
  58              },
  59              prev: function() {
  60                  var prev;
  61                  if ( ! $gp.editor.current ) {
  62                      return;
  63                  }
  64  
  65                  // TODO: go to previous page if needed
  66                  prev = $gp.editor.current.prevAll( 'tr.editor' );
  67                  if ( prev.length ) {
  68                      $gp.editor.show( prev.eq( 0 ) );
  69                  } else {
  70                      $gp.editor.hide();
  71                  }
  72              },
  73              next: function() {
  74                  var next;
  75  
  76                  if ( ! $gp.editor.current ) {
  77                      return;
  78                  }
  79  
  80                  // TODO: go to next page if needed.
  81                  next = $gp.editor.current.nextAll( 'tr.editor' );
  82                  if ( next.length ) {
  83                      $gp.editor.show( next.eq( 0 ) );
  84                  } else {
  85                      $gp.editor.hide();
  86                  }
  87              },
  88              hide: function( editor ) {
  89                  editor = editor ? editor : $gp.editor.current;
  90                  if ( ! editor ) {
  91                      return;
  92                  }
  93                  editor.hide();
  94                  editor.preview.show();
  95                  $gp.editor.current = null;
  96              },
  97              install_hooks: function() {
  98                  $( $gp.editor.table )
  99                      .on( 'click', 'a.edit', $gp.editor.hooks.show )
 100                      .on( 'dblclick', 'tr.preview td', $gp.editor.hooks.show )
 101                      .on( 'change', 'select.priority', $gp.editor.hooks.set_priority )
 102                      .on( 'click', 'button.close', $gp.editor.hooks.cancel )
 103                      .on( 'click', 'a.discard-warning', $gp.editor.hooks.discard_warning )
 104                      .on( 'click', 'button.copy', $gp.editor.hooks.copy )
 105                      .on( 'click', 'button.inserttab', $gp.editor.hooks.tab )
 106                      .on( 'click', 'button.insertnl', $gp.editor.hooks.newline )
 107                      .on( 'click', 'button.approve', $gp.editor.hooks.set_status_current )
 108                      .on( 'click', 'button.reject', $gp.editor.hooks.set_status_rejected )
 109                      .on( 'click', 'button.fuzzy', $gp.editor.hooks.set_status_fuzzy )
 110                      .on( 'click', 'button.ok', $gp.editor.hooks.ok )
 111                      .on( 'keydown', 'tr.editor textarea', $gp.editor.hooks.keydown );
 112                  $( '#translations' ).tooltip( {
 113                      items: '.glossary-word',
 114                      content: function() {
 115                          var content = $( '<ul>' );
 116                          $.each( $( this ).data( 'translations' ), function( i, e ) {
 117                              var def = $( '<li>' );
 118                              if ( e.locale_entry ) {
 119                                  def.append( $( '<span>', { text: e.locale_entry } ).addClass( 'locale-entry bubble' ) );
 120                              }
 121                              def.append( $( '<span>', { text: e.pos } ).addClass( 'pos' ) );
 122                              def.append( $( '<span>', { text: e.translation } ).addClass( 'translation' ) );
 123                              def.append( $( '<span>', { text: e.comment } ).addClass( 'comment' ) );
 124                              content.append( def );
 125                          } );
 126                          return content;
 127                      },
 128                      hide: false,
 129                      show: false,
 130                  } );
 131  
 132                  $.valHooks.textarea = {
 133                      get: function( elem ) {
 134                          return elem.value.replace( /\r?\n/g, '\r\n' );
 135                      },
 136                  };
 137              },
 138              keydown: function( e ) {
 139                  var target, container, approve, reject, copy;
 140  
 141                  if ( 27 === e.keyCode || ( 90 === e.keyCode && e.shiftKey && e.ctrlKey ) ) { // Escape or Ctrl-Shift-Z = Cancel.
 142                      $gp.editor.hide();
 143                  } else if ( 33 === e.keyCode || ( 38 === e.keyCode && e.ctrlKey ) ) { // Page Up or Ctrl-Up Arrow = Previous editor.
 144                      $gp.editor.prev();
 145                  } else if ( 34 === e.keyCode || ( 40 === e.keyCode && e.ctrlKey ) ) { // Page Down or Ctrl-Down Arrow = Next editor.
 146                      $gp.editor.next();
 147                  } else if ( 13 === e.keyCode && e.shiftKey ) { // Shift-Enter = Save.
 148                      target = $( e.target );
 149  
 150                      if ( 0 === e.altKey && target.val().length ) {
 151                          container = target.closest( '.textareas' ).prev();
 152  
 153                          if ( container.children() ) {
 154                              target.val( container.find( '.original' ).text() );
 155                          } else {
 156                              target.val( container.text() );
 157                          }
 158                      }
 159  
 160                      if ( target.nextAll( 'textarea' ).length ) {
 161                          target.nextAll( 'textarea' ).eq( 0 ).focus();
 162                      } else {
 163                          $gp.editor.save( target.parents( 'tr.editor' ).find( 'button.ok' ) );
 164                      }
 165                  } else if ( ( 13 === e.keyCode && e.ctrlKey ) || ( 66 === e.keyCode && e.shiftKey && e.ctrlKey ) ) { // Ctrl-Enter or Ctrl-Shift-B = Copy original.
 166                      copy = $( '.editor:visible' ).find( '.copy' );
 167  
 168                      if ( copy.length > 0 ) {
 169                          copy.trigger( 'click' );
 170                      }
 171                  } else if ( ( 107 === e.keyCode && e.ctrlKey ) || ( 65 === e.keyCode && e.shiftKey && e.ctrlKey ) ) { // Ctrl-+ or Ctrl-Shift-A = Approve.
 172                      approve = $( '.editor:visible' ).find( '.approve' );
 173  
 174                      if ( approve.length > 0 ) {
 175                          approve.trigger( 'click' );
 176                      }
 177                  } else if ( ( 109 === e.keyCode && e.ctrlKey ) || ( 82 === e.keyCode && e.shiftKey && e.ctrlKey ) ) { // Ctrl-- or Ctrl-Shift-R = Reject.
 178                      reject = $( '.editor:visible' ).find( '.reject' );
 179  
 180                      if ( reject.length > 0 ) {
 181                          reject.trigger( 'click' );
 182                      }
 183                  } else if ( ( 192 === e.keyCode && e.ctrlKey ) || ( 192 === e.keyCode && e.shiftKey && e.ctrlKey ) ) { // Ctrl-~ or Ctrl-Shift-~ = Fuzzy.
 184                      reject = $( '.editor:visible' ).find( '.fuzzy' );
 185  
 186                      if ( reject.length > 0 ) {
 187                          reject.trigger( 'click' );
 188                      }
 189                  } else {
 190                      return true;
 191                  }
 192  
 193                  return false;
 194              },
 195              replace_current: function( html ) {
 196                  var old_current;
 197  
 198                  if ( ! $gp.editor.current ) {
 199                      return;
 200                  }
 201                  $gp.editor.current.after( html );
 202                  old_current = $gp.editor.current;
 203                  old_current.attr( 'id', old_current.attr( 'id' ) + '-old' );
 204                  old_current.preview.attr( 'id', old_current.preview.attr( 'id' ) + '-old' );
 205                  $gp.editor.next();
 206                  old_current.preview.remove();
 207                  old_current.remove();
 208              },
 209              save: function( button ) {
 210                  var editor, textareaName,
 211                      data = [],
 212                      translations;
 213  
 214                  if ( ! $gp.editor.current ) {
 215                      return;
 216                  }
 217  
 218                  editor = $gp.editor.current;
 219                  button.prop( 'disabled', true );
 220                  $gp.notices.notice( 'Saving&hellip;' );
 221  
 222                  data = {
 223                      original_id: editor.original_id,
 224                      _gp_route_nonce: button.data( 'nonce' ),
 225                  };
 226  
 227                  textareaName = 'translation[' + editor.original_id + '][]';
 228                  translations = $( 'textarea[name="' + textareaName + '"]', editor ).map( function() {
 229                      return this.value;
 230                  } ).get();
 231  
 232                  data[ textareaName ] = translations;
 233  
 234                  $.ajax( {
 235                      type: 'POST',
 236                      url: $gp_editor_options.url,
 237                      data: data,
 238                      dataType: 'json',
 239                      success: function( response ) {
 240                          var original_id;
 241  
 242                          button.prop( 'disabled', false );
 243                          $gp.notices.success( 'Saved!' );
 244  
 245                          for ( original_id in response ) {
 246                              $gp.editor.replace_current( response[ original_id ] );
 247                          }
 248  
 249                          if ( $gp.editor.current.hasClass( 'no-warnings' ) ) {
 250                              $gp.editor.next();
 251                          }
 252                      },
 253                      error: function( xhr, msg ) {
 254                          button.prop( 'disabled', false );
 255                          msg = xhr.responseText ? 'Error: ' + xhr.responseText : 'Error saving the translation!';
 256                          $gp.notices.error( msg );
 257                      },
 258                  } );
 259              },
 260              set_priority: function( select ) {
 261                  var editor, data;
 262  
 263                  if ( ! $gp.editor.current ) {
 264                      return;
 265                  }
 266  
 267                  editor = $gp.editor.current;
 268                  select.prop( 'disabled', true );
 269                  $gp.notices.notice( 'Setting priority&hellip;' );
 270  
 271                  data = {
 272                      priority: $( 'option:selected', select ).val(),
 273                      _gp_route_nonce: select.data( 'nonce' ),
 274                  };
 275  
 276                  $.ajax( {
 277                      type: 'POST',
 278                      url: $gp_editor_options.set_priority_url.replace( '%original-id%', editor.original_id ),
 279                      data: data,
 280                      success: function() {
 281                          var new_priority_class;
 282  
 283                          select.prop( 'disabled', false );
 284                          $gp.notices.success( 'Priority set!' );
 285                          new_priority_class = 'priority-' + $( 'option:selected', select ).text();
 286                          $gp.editor.current.addClass( new_priority_class );
 287                          $gp.editor.current.preview.addClass( new_priority_class );
 288                      },
 289                      error: function( xhr, msg ) {
 290                          select.prop( 'disabled', false );
 291                          msg = xhr.responseText ? 'Error: ' + xhr.responseText : 'Error setting the priority!';
 292                          $gp.notices.error( msg );
 293                      },
 294                  } );
 295              },
 296              set_status: function( button, status ) {
 297                  var editor, data,
 298                      translationChanged = false;
 299  
 300                  if ( ! $gp.editor.current || ! $gp.editor.current.translation_id ) {
 301                      return;
 302                  }
 303  
 304                  editor = $gp.editor.current;
 305  
 306                  $( '[id*="translation_' + editor.original_id + '_"]' ).each( function() {
 307                      if ( this.value !== this.defaultValue ) {
 308                          translationChanged = true;
 309                      }
 310                  } );
 311  
 312                  if ( translationChanged ) {
 313                      $gp.notices.error( 'Translation has changed! Please add the new translation before changing its status.' );
 314                      return;
 315                  }
 316  
 317                  button.prop( 'disabled', true );
 318                  $gp.notices.notice( 'Setting status to &#8220;' + status + '&#8221;&hellip;' );
 319  
 320                  data = {
 321                      translation_id: editor.translation_id,
 322                      status: status,
 323                      _gp_route_nonce: button.data( 'nonce' ),
 324                  };
 325  
 326                  $.ajax( {
 327                      type: 'POST',
 328                      url: $gp_editor_options.set_status_url,
 329                      data: data,
 330                      success: function( response ) {
 331                          button.prop( 'disabled', false );
 332                          $gp.notices.success( 'Status set!' );
 333                          $gp.editor.replace_current( response );
 334                          $gp.editor.next();
 335                      },
 336                      error: function( xhr, msg ) {
 337                          button.prop( 'disabled', false );
 338                          msg = xhr.responseText ? 'Error: ' + xhr.responseText : 'Error setting the status!';
 339                          $gp.notices.error( msg );
 340                      },
 341                  } );
 342              },
 343              discard_warning: function( link ) {
 344                  var data;
 345                  if ( ! $gp.editor.current ) {
 346                      return;
 347                  }
 348  
 349                  $gp.notices.notice( 'Discarding&hellip;' );
 350  
 351                  data = {
 352                      translation_id: $gp.editor.current.translation_id,
 353                      key: link.data( 'key' ),
 354                      index: link.data( 'index' ),
 355                      _gp_route_nonce: link.data( 'nonce' ),
 356  
 357                  };
 358  
 359                  $.ajax( {
 360                      type: 'POST',
 361                      url: $gp_editor_options.discard_warning_url,
 362                      data: data,
 363                      success: function( response ) {
 364                          $gp.notices.success( 'Saved!' );
 365                          $gp.editor.replace_current( response );
 366                      },
 367                      error: function( xhr, msg ) {
 368                          msg = xhr.responseText ? 'Error: ' + xhr.responseText : 'Error saving the translation!';
 369                          $gp.notices.error( msg );
 370                      },
 371                  } );
 372              },
 373              copy: function( link ) {
 374                  var chunks = link.parents( '.textareas' ).find( 'textarea' ).attr( 'id' ).split( '_' );
 375                  var original_index = Math.min( parseInt( chunks[ chunks.length - 1 ], 10 ), 1 );
 376                  var original_texts = link.parents( '.strings' ).find( '.original_raw' );
 377                  var original_text = original_texts.eq( original_index ).text();
 378  
 379                  link.parents( '.textareas' ).find( 'textarea' ).val( original_text ).focus();
 380              },
 381              tab: function( link ) {
 382                  var text_area = link.parents( '.textareas' ).find( 'textarea' );
 383                  var cursorPos = text_area.prop( 'selectionStart' );
 384                  var v = text_area.val();
 385                  var textBefore = v.substring( 0, cursorPos );
 386                  var textAfter = v.substring( cursorPos, v.length );
 387  
 388                  text_area.val( textBefore + '\t' + textAfter );
 389  
 390                  text_area.focus();
 391                  text_area[ 0 ].selectionEnd = cursorPos + 1;
 392              },
 393              newline: function( link ) {
 394                  var text_area = link.parents( '.textareas' ).find( 'textarea' );
 395                  var cursorPos = text_area.prop( 'selectionStart' );
 396                  var v = text_area.val();
 397                  var textBefore = v.substring( 0, cursorPos );
 398                  var textAfter = v.substring( cursorPos, v.length );
 399  
 400                  text_area.val( textBefore + '\n' + textAfter );
 401  
 402                  text_area.focus();
 403                  text_area[ 0 ].selectionEnd = cursorPos + 1;
 404              },
 405              hooks: {
 406                  show: function() {
 407                      $gp.editor.show( $( this ) );
 408                      return false;
 409                  },
 410                  hide: function() {
 411                      $gp.editor.hide();
 412                      return false;
 413                  },
 414                  ok: function() {
 415                      $gp.editor.save( $( this ) );
 416                      return false;
 417                  },
 418                  cancel: function() {
 419                      var i = 0;
 420  
 421                      for ( i = 0; i < $gp.editor.current.orginal_translations.length; i++ ) {
 422                          $( 'textarea[id="translation_' + $gp.editor.current.original_id + '_' + i + '"]' ).val( $gp.editor.current.orginal_translations[ i ] );
 423                      }
 424  
 425                      $gp.editor.hide();
 426  
 427                      return false;
 428                  },
 429                  keydown: function( e ) {
 430                      return $gp.editor.keydown( e );
 431                  },
 432                  copy: function() {
 433                      $gp.editor.copy( $( this ) );
 434                      return false;
 435                  },
 436                  tab: function() {
 437                      $gp.editor.tab( $( this ) );
 438                      return false;
 439                  },
 440                  newline: function() {
 441                      $gp.editor.newline( $( this ) );
 442                      return false;
 443                  },
 444                  discard_warning: function() {
 445                      $gp.editor.discard_warning( $( this ) );
 446                      return false;
 447                  },
 448                  set_status_current: function() {
 449                      $gp.editor.set_status( $( this ), 'current' );
 450                      return false;
 451                  },
 452                  set_status_rejected: function() {
 453                      $gp.editor.set_status( $( this ), 'rejected' );
 454                      return false;
 455                  },
 456                  set_status_fuzzy: function() {
 457                      $gp.editor.set_status( $( this ), 'fuzzy' );
 458                      return false;
 459                  },
 460                  set_priority: function() {
 461                      $gp.editor.set_priority( $( this ) );
 462                      return false;
 463                  },
 464              },
 465          };
 466      }( jQuery )
 467  );
 468  
 469  jQuery( function( $ ) {
 470      $gp.editor.init( $( '#translations' ) );
 471  } );


Generated: Thu Nov 21 01:01:07 2024 Cross-referenced by PHPXref 0.7.1