[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/js/ -> press-this.js (source)

   1  /**
   2   * PressThis App
   3   *
   4   */
   5  ( function( $, window ) {
   6      var PressThis = function() {
   7          var editor, $mediaList, $mediaThumbWrap,
   8              $window               = $( window ),
   9              $document             = $( document ),
  10              saveAlert             = false,
  11              sidebarIsOpen         = false,
  12              settings              = window.wpPressThisConfig || {},
  13              data                  = window.wpPressThisData || {},
  14              smallestWidth         = 128,
  15              hasSetFocus           = false,
  16              catsCache             = [],
  17              isOffScreen           = 'is-off-screen',
  18              isHidden              = 'is-hidden',
  19              offscreenHidden       = isOffScreen + ' ' + isHidden,
  20              iOS                   = /iPad|iPod|iPhone/.test( window.navigator.userAgent ),
  21              $textEditor           = $( '#pressthis' ),
  22              textEditor            = $textEditor[0],
  23              textEditorMinHeight   = 600,
  24              textLength            = 0,
  25              transitionEndEvent    = ( function() {
  26                  var style = document.documentElement.style;
  27  
  28                  if ( typeof style.transition !== 'undefined' ) {
  29                      return 'transitionend';
  30                  }
  31  
  32                  if ( typeof style.WebkitTransition !== 'undefined' ) {
  33                      return 'webkitTransitionEnd';
  34                  }
  35  
  36                  return false;
  37              }() );
  38  
  39          /* ***************************************************************
  40           * HELPER FUNCTIONS
  41           *************************************************************** */
  42  
  43          /**
  44           * Emulates our PHP __() gettext function, powered by the strings exported in pressThisL10n.
  45           *
  46           * @param key string Key of the string to be translated, as found in pressThisL10n.
  47           * @returns string Original or translated string, or empty string if no key.
  48           */
  49          function __( key ) {
  50              if ( key && window.pressThisL10n ) {
  51                  return window.pressThisL10n[key] || key;
  52              }
  53  
  54              return key || '';
  55          }
  56  
  57          /**
  58           * Allow only HTTP or protocol relative URLs.
  59           *
  60           * @param url string The URL.
  61           * @returns string Processed URL.
  62           */
  63  		function checkUrl( url ) {
  64              url = $.trim( url || '' );
  65  
  66              if ( /^(?:https?:)?\/\//.test( url ) ) {
  67                  url = wp.sanitize.stripTags( url );
  68                  return url.replace( /["\\]+/g, '' );
  69              }
  70  
  71              return '';
  72          }
  73  
  74          /**
  75           * Show UX spinner
  76           */
  77  		function showSpinner() {
  78              $( '.spinner' ).addClass( 'is-active' );
  79              $( '.post-actions button' ).attr( 'disabled', 'disabled' );
  80          }
  81  
  82          /**
  83           * Hide UX spinner
  84           */
  85  		function hideSpinner() {
  86              $( '.spinner' ).removeClass( 'is-active' );
  87              $( '.post-actions button' ).removeAttr( 'disabled' );
  88          }
  89  
  90  		function textEditorResize( reset ) {
  91              var pageYOffset, height;
  92  
  93              if ( editor && ! editor.isHidden() ) {
  94                   return;
  95               }
  96  
  97              reset = ( reset === 'reset' ) || ( textLength && textLength > textEditor.value.length );
  98              height = textEditor.style.height;
  99  
 100              if ( reset ) {
 101                  pageYOffset = window.pageYOffset;
 102  
 103                  textEditor.style.height = 'auto';
 104                  textEditor.style.height = Math.max( textEditor.scrollHeight, textEditorMinHeight ) + 'px';
 105                  window.scrollTo( window.pageXOffset, pageYOffset );
 106              } else if ( parseInt( textEditor.style.height, 10 ) < textEditor.scrollHeight ) {
 107                  textEditor.style.height = textEditor.scrollHeight + 'px';
 108               }
 109  
 110               textLength = textEditor.value.length;
 111           }
 112  
 113   		function mceGetCursorOffset() {
 114              if ( ! editor ) {
 115                  return false;
 116              }
 117  
 118              var node = editor.selection.getNode(),
 119                  range, view, offset;
 120  
 121              if ( editor.wp && editor.wp.getView && ( view = editor.wp.getView( node ) ) ) {
 122                  offset = view.getBoundingClientRect();
 123              } else {
 124                  range = editor.selection.getRng();
 125  
 126                  try {
 127                      offset = range.getClientRects()[0];
 128                  } catch( er ) {}
 129  
 130                  if ( ! offset ) {
 131                      offset = node.getBoundingClientRect();
 132                  }
 133              }
 134  
 135              return offset.height ? offset : false;
 136          }
 137  
 138          // Make sure the caret is always visible.
 139  		function mceKeyup( event ) {
 140              var VK = window.tinymce.util.VK,
 141                  key = event.keyCode;
 142  
 143              // Bail on special keys.
 144              if ( key <= 47 && ! ( key === VK.SPACEBAR || key === VK.ENTER || key === VK.DELETE || key === VK.BACKSPACE || key === VK.UP || key === VK.LEFT || key === VK.DOWN || key === VK.UP ) ) {
 145                  return;
 146              // OS keys, function keys, num lock, scroll lock
 147              } else if ( ( key >= 91 && key <= 93 ) || ( key >= 112 && key <= 123 ) || key === 144 || key === 145 ) {
 148                  return;
 149              }
 150  
 151              mceScroll( key );
 152          }
 153  
 154  		function mceScroll( key ) {
 155              var cursorTop, cursorBottom, editorBottom,
 156                  offset = mceGetCursorOffset(),
 157                  bufferTop = 50,
 158                  bufferBottom = 65,
 159                  VK = window.tinymce.util.VK;
 160  
 161              if ( ! offset ) {
 162                  return;
 163              }
 164  
 165              cursorTop = offset.top + editor.iframeElement.getBoundingClientRect().top;
 166              cursorBottom = cursorTop + offset.height;
 167              cursorTop = cursorTop - bufferTop;
 168              cursorBottom = cursorBottom + bufferBottom;
 169              editorBottom = $window.height();
 170  
 171              // Don't scroll if the node is taller than the visible part of the editor
 172              if ( editorBottom < offset.height ) {
 173                  return;
 174              }
 175  
 176              if ( cursorTop < 0 && ( key === VK.UP || key === VK.LEFT || key === VK.BACKSPACE ) ) {
 177                  window.scrollTo( window.pageXOffset, cursorTop + window.pageYOffset );
 178              } else if ( cursorBottom > editorBottom ) {
 179                  window.scrollTo( window.pageXOffset, cursorBottom + window.pageYOffset - editorBottom );
 180              }
 181          }
 182  
 183          /**
 184           * Replace emoji images with chars and sanitize the text content.
 185           */
 186  		function getTitleText() {
 187              var $element = $( '#title-container' );
 188  
 189              $element.find( 'img.emoji' ).each( function() {
 190                  var $image = $( this );
 191                  $image.replaceWith( $( '<span>' ).text( $image.attr( 'alt' ) ) );
 192              });
 193  
 194              return wp.sanitize.sanitizeText( $element.text() );
 195          }
 196  
 197          /**
 198           * Prepare the form data for saving.
 199           */
 200  		function prepareFormData() {
 201              var $form = $( '#pressthis-form' ),
 202                  $input = $( '<input type="hidden" name="post_category[]" value="">' );
 203  
 204              editor && editor.save();
 205  
 206              $( '#post_title' ).val( getTitleText() );
 207  
 208              // Make sure to flush out the tags with tagBox before saving
 209              if ( window.tagBox ) {
 210                  $( 'div.tagsdiv' ).each( function() {
 211                      window.tagBox.flushTags( this, false, 1 );
 212                  } );
 213              }
 214  
 215              // Get selected categories
 216              $( '.categories-select .category' ).each( function( i, element ) {
 217                  var $cat = $( element );
 218  
 219                  if ( $cat.hasClass( 'selected' ) ) {
 220                      // Have to append a node as we submit the actual form on preview
 221                      $form.append( $input.clone().val( $cat.attr( 'data-term-id' ) || '' ) );
 222                  }
 223              });
 224          }
 225  
 226          /**
 227           * Submit the post form via AJAX, and redirect to the proper screen if published vs saved as a draft.
 228           *
 229           * @param action string publish|draft
 230           */
 231  		function submitPost( action ) {
 232              var data;
 233  
 234              saveAlert = false;
 235              showSpinner();
 236  
 237              if ( 'publish' === action ) {
 238                  $( '#post_status' ).val( 'publish' );
 239              }
 240  
 241              prepareFormData();
 242              data = $( '#pressthis-form' ).serialize();
 243  
 244              $.ajax( {
 245                  type: 'post',
 246                  url: window.ajaxurl,
 247                  data: data
 248              }).always( function() {
 249                  hideSpinner();
 250                  clearNotices();
 251                  $( '.publish-button' ).removeClass( 'is-saving' );
 252              }).done( function( response ) {
 253                  if ( ! response.success ) {
 254                      renderError( response.data.errorMessage );
 255                  } else if ( response.data.redirect ) {
 256                      if ( window.opener && ( settings.redirInParent || response.data.force ) ) {
 257                          try {
 258                              window.opener.location.href = response.data.redirect;
 259  
 260                              window.setTimeout( function() {
 261                                  window.self.close();
 262                              }, 200 );
 263                          } catch( er ) {
 264                              window.location.href = response.data.redirect;
 265                          }
 266                      } else {
 267                          window.location.href = response.data.redirect;
 268                      }
 269                  }
 270              }).fail( function() {
 271                  renderError( __( 'serverError' ) );
 272              });
 273          }
 274  
 275          /**
 276           * Inserts the media a user has selected from the presented list inside the editor, as an image or embed, based on type
 277           *
 278           * @param type string img|embed
 279           * @param src string Source URL
 280           * @param link string Optional destination link, for images (defaults to src)
 281           */
 282  		function insertSelectedMedia( $element ) {
 283              var src, link, newContent = '';
 284  
 285              src = checkUrl( $element.attr( 'data-wp-src' ) || '' );
 286              link = checkUrl( data.u );
 287  
 288              if ( $element.hasClass( 'is-image' ) ) {
 289                  if ( ! link ) {
 290                      link = src;
 291                  }
 292  
 293                  newContent = '<a href="' + link + '"><img class="alignnone size-full" src="' + src + '" alt="" /></a>';
 294              } else {
 295                  newContent = '[embed]' + src + '[/embed]';
 296              }
 297  
 298              if ( editor && ! editor.isHidden() ) {
 299                  if ( ! hasSetFocus ) {
 300                      editor.setContent( '<p>' + newContent + '</p>' + editor.getContent() );
 301                  } else {
 302                      editor.execCommand( 'mceInsertContent', false, newContent );
 303                  }
 304              } else if ( window.QTags ) {
 305                  window.QTags.insertContent( newContent );
 306              }
 307          }
 308  
 309          /**
 310           * Save a new user-generated category via AJAX
 311           */
 312  		function saveNewCategory() {
 313              var data,
 314                  name = $( '#new-category' ).val();
 315  
 316              if ( ! name ) {
 317                  return;
 318              }
 319  
 320              data = {
 321                  action: 'press-this-add-category',
 322                  post_id: $( '#post_ID' ).val() || 0,
 323                  name: name,
 324                  new_cat_nonce: $( '#_ajax_nonce-add-category' ).val() || '',
 325                  parent: $( '#new-category-parent' ).val() || 0
 326              };
 327  
 328              $.post( window.ajaxurl, data, function( response ) {
 329                  if ( ! response.success ) {
 330                      renderError( response.data.errorMessage );
 331                  } else {
 332                      var $parent, $ul,
 333                          $wrap = $( 'ul.categories-select' );
 334  
 335                      $.each( response.data, function( i, newCat ) {
 336                          var $node = $( '<li>' ).append( $( '<div class="category selected" tabindex="0" role="checkbox" aria-checked="true">' )
 337                              .attr( 'data-term-id', newCat.term_id )
 338                              .text( newCat.name ) );
 339  
 340                          if ( newCat.parent ) {
 341                              if ( ! $ul || ! $ul.length ) {
 342                                  $parent = $wrap.find( 'div[data-term-id="' + newCat.parent + '"]' ).parent();
 343                                  $ul = $parent.find( 'ul.children:first' );
 344  
 345                                  if ( ! $ul.length ) {
 346                                      $ul = $( '<ul class="children">' ).appendTo( $parent );
 347                                  }
 348                              }
 349  
 350                              $ul.prepend( $node );
 351                          } else {
 352                              $wrap.prepend( $node );
 353                          }
 354  
 355                          $node.focus();
 356                      } );
 357  
 358                      refreshCatsCache();
 359                  }
 360              } );
 361          }
 362  
 363          /* ***************************************************************
 364           * RENDERING FUNCTIONS
 365           *************************************************************** */
 366  
 367          /**
 368           * Hide the form letting users enter a URL to be scanned, if a URL was already passed.
 369           */
 370  		function renderToolsVisibility() {
 371              if ( data.hasData ) {
 372                  $( '#scanbar' ).hide();
 373              }
 374          }
 375  
 376          /**
 377           * Render error notice
 378           *
 379           * @param msg string Notice/error message
 380           * @param error string error|notice CSS class for display
 381           */
 382  		function renderNotice( msg, error ) {
 383              var $alerts = $( '.editor-wrapper div.alerts' ),
 384                  className = error ? 'is-error' : 'is-notice';
 385  
 386              $alerts.append( $( '<p class="alert ' + className + '">' ).text( msg ) );
 387          }
 388  
 389          /**
 390           * Render error notice
 391           *
 392           * @param msg string Error message
 393           */
 394  		function renderError( msg ) {
 395              renderNotice( msg, true );
 396          }
 397  
 398  		function clearNotices() {
 399              $( 'div.alerts' ).empty();
 400          }
 401  
 402          /**
 403           * Render notices on page load, if any already
 404           */
 405  		function renderStartupNotices() {
 406              // Render errors sent in the data, if any
 407              if ( data.errors ) {
 408                  $.each( data.errors, function( i, msg ) {
 409                      renderError( msg );
 410                  } );
 411              }
 412          }
 413  
 414          /**
 415           * Add an image to the list of found images.
 416           */
 417  		function addImg( src, displaySrc, i ) {
 418              var $element = $mediaThumbWrap.clone().addClass( 'is-image' );
 419  
 420              $element.attr( 'data-wp-src', src ).css( 'background-image', 'url(' + displaySrc + ')' )
 421                  .find( 'span' ).text( __( 'suggestedImgAlt' ).replace( '%d', i + 1 ) );
 422  
 423              $mediaList.append( $element );
 424          }
 425  
 426          /**
 427           * Render the detected images and embed for selection, if any
 428           */
 429  		function renderDetectedMedia() {
 430              var found = 0;
 431  
 432              $mediaList = $( 'ul.media-list' );
 433              $mediaThumbWrap = $( '<li class="suggested-media-thumbnail" tabindex="0"><span class="screen-reader-text"></span></li>' );
 434  
 435              if ( data._embeds ) {
 436                  $.each( data._embeds, function ( i, src ) {
 437                      var displaySrc = '',
 438                          cssClass = '',
 439                          $element = $mediaThumbWrap.clone().addClass( 'is-embed' );
 440  
 441                      src = checkUrl( src );
 442  
 443                      if ( src.indexOf( 'youtube.com/' ) > -1 ) {
 444                          displaySrc = 'https://i.ytimg.com/vi/' + src.replace( /.+v=([^&]+).*/, '$1' ) + '/hqdefault.jpg';
 445                          cssClass += ' is-video';
 446                      } else if ( src.indexOf( 'youtu.be/' ) > -1 ) {
 447                          displaySrc = 'https://i.ytimg.com/vi/' + src.replace( /\/([^\/])$/, '$1' ) + '/hqdefault.jpg';
 448                          cssClass += ' is-video';
 449                      } else if ( src.indexOf( 'dailymotion.com' ) > -1 ) {
 450                          displaySrc = src.replace( '/video/', '/thumbnail/video/' );
 451                          cssClass += ' is-video';
 452                      } else if ( src.indexOf( 'soundcloud.com' ) > -1 ) {
 453                          cssClass += ' is-audio';
 454                      } else if ( src.indexOf( 'twitter.com' ) > -1 ) {
 455                          cssClass += ' is-tweet';
 456                      } else {
 457                          cssClass += ' is-video';
 458                      }
 459  
 460                      $element.attr( 'data-wp-src', src ).find( 'span' ).text( __( 'suggestedEmbedAlt' ).replace( '%d', i + 1 ) );
 461  
 462                      if ( displaySrc ) {
 463                          $element.css( 'background-image', 'url(' + displaySrc + ')' );
 464                      }
 465  
 466                      $mediaList.append( $element );
 467                      found++;
 468                  } );
 469              }
 470  
 471              if ( data._images ) {
 472                  $.each( data._images, function( i, src ) {
 473                      var displaySrc, img = new Image();
 474  
 475                      src = checkUrl( src );
 476                      displaySrc = src.replace( /^(http[^\?]+)(\?.*)?$/, '$1' );
 477  
 478                      if ( src.indexOf( 'files.wordpress.com/' ) > -1 ) {
 479                          displaySrc = displaySrc.replace( /\?.*$/, '' ) + '?w=' + smallestWidth;
 480                      } else if ( src.indexOf( 'gravatar.com/' ) > -1 ) {
 481                          displaySrc = displaySrc.replace( /\?.*$/, '' ) + '?s=' + smallestWidth;
 482                      } else {
 483                          displaySrc = src;
 484                      }
 485  
 486                      img.onload = function() {
 487                          if ( ( img.width && img.width < 256 ) ||
 488                              ( img.height && img.height < 128 ) ) {
 489  
 490                              return;
 491                          }
 492  
 493                          addImg( src, displaySrc, i );
 494                      };
 495  
 496                      img.src = src;
 497                      found++;
 498                  } );
 499              }
 500  
 501              if ( found ) {
 502                  $( '.media-list-container' ).addClass( 'has-media' );
 503              }
 504          }
 505  
 506          /* ***************************************************************
 507           * MONITORING FUNCTIONS
 508           *************************************************************** */
 509  
 510          /**
 511           * Interactive navigation behavior for the options modal (post format, tags, categories)
 512           */
 513  		function monitorOptionsModal() {
 514              var $postOptions  = $( '.post-options' ),
 515                  $postOption   = $( '.post-option' ),
 516                  $settingModal = $( '.setting-modal' ),
 517                  $modalClose   = $( '.modal-close' );
 518  
 519              $postOption.on( 'click', function() {
 520                  var index = $( this ).index(),
 521                      $targetSettingModal = $settingModal.eq( index );
 522  
 523                  $postOptions.addClass( isOffScreen )
 524                      .one( transitionEndEvent, function() {
 525                          $( this ).addClass( isHidden );
 526                      } );
 527  
 528                  $targetSettingModal.removeClass( offscreenHidden )
 529                      .one( transitionEndEvent, function() {
 530                          $( this ).find( '.modal-close' ).focus();
 531                      } );
 532              } );
 533  
 534              $modalClose.on( 'click', function() {
 535                  var $targetSettingModal = $( this ).parent(),
 536                      index = $targetSettingModal.index();
 537  
 538                  $postOptions.removeClass( offscreenHidden );
 539                  $targetSettingModal.addClass( isOffScreen );
 540  
 541                  if ( transitionEndEvent ) {
 542                      $targetSettingModal.one( transitionEndEvent, function() {
 543                          $( this ).addClass( isHidden );
 544                          $postOption.eq( index - 1 ).focus();
 545                      } );
 546                  } else {
 547                      setTimeout( function() {
 548                          $targetSettingModal.addClass( isHidden );
 549                          $postOption.eq( index - 1 ).focus();
 550                      }, 350 );
 551                  }
 552              } );
 553          }
 554  
 555          /**
 556           * Interactive behavior for the sidebar toggle, to show the options modals
 557           */
 558  		function openSidebar() {
 559              sidebarIsOpen = true;
 560  
 561              $( '.options' ).removeClass( 'closed' ).addClass( 'open' );
 562              $( '.press-this-actions, #scanbar' ).addClass( isHidden );
 563              $( '.options-panel-back' ).removeClass( isHidden );
 564  
 565              $( '.options-panel' ).removeClass( offscreenHidden )
 566                  .one( transitionEndEvent, function() {
 567                      $( '.post-option:first' ).focus();
 568                  } );
 569          }
 570  
 571  		function closeSidebar() {
 572              sidebarIsOpen = false;
 573  
 574              $( '.options' ).removeClass( 'open' ).addClass( 'closed' );
 575              $( '.options-panel-back' ).addClass( isHidden );
 576              $( '.press-this-actions, #scanbar' ).removeClass( isHidden );
 577  
 578              $( '.options-panel' ).addClass( isOffScreen )
 579                  .one( transitionEndEvent, function() {
 580                      $( this ).addClass( isHidden );
 581                      // Reset to options list
 582                      $( '.post-options' ).removeClass( offscreenHidden );
 583                      $( '.setting-modal').addClass( offscreenHidden );
 584                  });
 585          }
 586  
 587          /**
 588           * Interactive behavior for the post title's field placeholder
 589           */
 590  		function monitorPlaceholder() {
 591              var $titleField = $( '#title-container' ),
 592                  $placeholder = $( '.post-title-placeholder' );
 593  
 594              $titleField.on( 'focus', function() {
 595                  $placeholder.addClass( 'is-hidden' );
 596              }).on( 'blur', function() {
 597                  if ( ! $titleField.text() && ! $titleField.html() ) {
 598                      $placeholder.removeClass( 'is-hidden' );
 599                  }
 600              }).on( 'keyup', function() {
 601                  saveAlert = true;
 602              }).on( 'paste', function( event ) {
 603                  var text, range,
 604                      clipboard = event.originalEvent.clipboardData || window.clipboardData;
 605  
 606                  if ( clipboard ) {
 607                      try{
 608                          text = clipboard.getData( 'Text' ) || clipboard.getData( 'text/plain' );
 609  
 610                          if ( text ) {
 611                              text = $.trim( text.replace( /\s+/g, ' ' ) );
 612  
 613                              if ( window.getSelection ) {
 614                                  range = window.getSelection().getRangeAt(0);
 615  
 616                                  if ( range ) {
 617                                      if ( ! range.collapsed ) {
 618                                          range.deleteContents();
 619                                      }
 620  
 621                                      range.insertNode( document.createTextNode( text ) );
 622                                  }
 623                              } else if ( document.selection ) {
 624                                  range = document.selection.createRange();
 625  
 626                                  if ( range ) {
 627                                      range.text = text;
 628                                  }
 629                              }
 630                          }
 631                      } catch ( er ) {}
 632  
 633                      event.preventDefault();
 634                  }
 635  
 636                  saveAlert = true;
 637  
 638                  setTimeout( function() {
 639                      $titleField.text( getTitleText() );
 640                  }, 50 );
 641              });
 642  
 643              if ( $titleField.text() || $titleField.html() ) {
 644                  $placeholder.addClass('is-hidden');
 645              }
 646          }
 647  
 648  		function toggleCatItem( $element ) {
 649              if ( $element.hasClass( 'selected' ) ) {
 650                  $element.removeClass( 'selected' ).attr( 'aria-checked', 'false' );
 651              } else {
 652                  $element.addClass( 'selected' ).attr( 'aria-checked', 'true' );
 653              }
 654          }
 655  
 656  		function monitorCatList() {
 657              $( '.categories-select' ).on( 'click.press-this keydown.press-this', function( event ) {
 658                  var $element = $( event.target );
 659  
 660                  if ( $element.is( 'div.category' ) ) {
 661                      if ( event.type === 'keydown' && event.keyCode !== 32 ) {
 662                          return;
 663                      }
 664  
 665                      toggleCatItem( $element );
 666                      event.preventDefault();
 667                  }
 668              });
 669          }
 670  
 671  		function splitButtonClose() {
 672              $( '.split-button' ).removeClass( 'is-open' );
 673              $( '.split-button-toggle' ).attr( 'aria-expanded', 'false' );
 674          }
 675  
 676          /* ***************************************************************
 677           * PROCESSING FUNCTIONS
 678           *************************************************************** */
 679  
 680          /**
 681           * Calls all the rendring related functions to happen on page load
 682           */
 683  		function render(){
 684              // We're on!
 685              renderToolsVisibility();
 686              renderDetectedMedia();
 687              renderStartupNotices();
 688  
 689              if ( window.tagBox ) {
 690                  window.tagBox.init();
 691              }
 692  
 693              // iOS doesn't fire click events on "standard" elements without this...
 694              if ( iOS ) {
 695                  $( document.body ).css( 'cursor', 'pointer' );
 696              }
 697          }
 698  
 699          /**
 700           * Set app events and other state monitoring related code.
 701           */
 702  		function monitor() {
 703              var $splitButton = $( '.split-button' );
 704  
 705              $document.on( 'tinymce-editor-init', function( event, ed ) {
 706                  editor = ed;
 707  
 708                  editor.on( 'nodechange', function() {
 709                      hasSetFocus = true;
 710                  });
 711  
 712                  editor.on( 'focus', function() {
 713                      splitButtonClose();
 714                  });
 715  
 716                  editor.on( 'show', function() {
 717                      setTimeout( function() {
 718                          editor.execCommand( 'wpAutoResize' );
 719                      }, 300 );
 720                  });
 721  
 722                  editor.on( 'hide', function() {
 723                      setTimeout( function() {
 724                          textEditorResize( 'reset' );
 725                      }, 100 );
 726                  });
 727  
 728                  editor.on( 'keyup', mceKeyup );
 729                  editor.on( 'undo redo', mceScroll );
 730  
 731              }).on( 'click.press-this keypress.press-this', '.suggested-media-thumbnail', function( event ) {
 732                  if ( event.type === 'click' || event.keyCode === 13 ) {
 733                      insertSelectedMedia( $( this ) );
 734                  }
 735              }).on( 'click.press-this', function( event ) {
 736                  if ( ! $( event.target ).closest( 'button' ).hasClass( 'split-button-toggle' ) ) {
 737                      splitButtonClose();
 738                  }
 739              });
 740  
 741              // Publish, Draft and Preview buttons
 742              $( '.post-actions' ).on( 'click.press-this', function( event ) {
 743                  var location,
 744                      $target = $( event.target ),
 745                      $button = $target.closest( 'button' );
 746  
 747                  if ( $button.length ) {
 748                      if ( $button.hasClass( 'draft-button' ) ) {
 749                          $( '.publish-button' ).addClass( 'is-saving' );
 750                          submitPost( 'draft' );
 751                      } else if ( $button.hasClass( 'publish-button' ) ) {
 752                          $button.addClass( 'is-saving' );
 753  
 754                          if ( window.history.replaceState ) {
 755                              location = window.location.href;
 756                              location += ( location.indexOf( '?' ) !== -1 ) ? '&' : '?';
 757                              location += 'wp-press-this-reload=true';
 758  
 759                              window.history.replaceState( null, null, location );
 760                          }
 761  
 762                          submitPost( 'publish' );
 763                      } else if ( $button.hasClass( 'preview-button' ) ) {
 764                          prepareFormData();
 765                          window.opener && window.opener.focus();
 766  
 767                          $( '#wp-preview' ).val( 'dopreview' );
 768                          $( '#pressthis-form' ).attr( 'target', '_blank' ).submit().attr( 'target', '' );
 769                          $( '#wp-preview' ).val( '' );
 770                      } else if ( $button.hasClass( 'standard-editor-button' ) ) {
 771                          $( '.publish-button' ).addClass( 'is-saving' );
 772                          $( '#pt-force-redirect' ).val( 'true' );
 773                          submitPost( 'draft' );
 774                      } else if ( $button.hasClass( 'split-button-toggle' ) ) {
 775                          if ( $splitButton.hasClass( 'is-open' ) ) {
 776                              $splitButton.removeClass( 'is-open' );
 777                              $button.attr( 'aria-expanded', 'false' );
 778                          } else {
 779                              $splitButton.addClass( 'is-open' );
 780                              $button.attr( 'aria-expanded', 'true' );
 781                          }
 782                      }
 783                  }
 784              });
 785  
 786              monitorOptionsModal();
 787              monitorPlaceholder();
 788              monitorCatList();
 789  
 790              $( '.options' ).on( 'click.press-this', function() {
 791                  if ( $( this ).hasClass( 'open' ) ) {
 792                      closeSidebar();
 793                  } else {
 794                      openSidebar();
 795                  }
 796              });
 797  
 798              // Close the sidebar when focus moves outside of it.
 799              $( '.options-panel, .options-panel-back' ).on( 'focusout.press-this', function() {
 800                  setTimeout( function() {
 801                      var node = document.activeElement,
 802                          $node = $( node );
 803  
 804                      if ( sidebarIsOpen && node && ! $node.hasClass( 'options-panel-back' ) &&
 805                          ( node.nodeName === 'BODY' ||
 806                              ( ! $node.closest( '.options-panel' ).length &&
 807                              ! $node.closest( '.options' ).length ) ) ) {
 808  
 809                          closeSidebar();
 810                      }
 811                  }, 50 );
 812              });
 813  
 814              $( '#post-formats-select input' ).on( 'change', function() {
 815                  var $this = $( this );
 816  
 817                  if ( $this.is( ':checked' ) ) {
 818                      $( '#post-option-post-format' ).text( $( 'label[for="' + $this.attr( 'id' ) + '"]' ).text() || '' );
 819                  }
 820              } );
 821  
 822              $window.on( 'beforeunload.press-this', function() {
 823                  if ( saveAlert || ( editor && editor.isDirty() ) ) {
 824                      return __( 'saveAlert' );
 825                  }
 826              } ).on( 'resize.press-this', function() {
 827                  if ( ! editor || editor.isHidden() ) {
 828                      textEditorResize( 'reset' );
 829                  }
 830              });
 831  
 832              $( 'button.add-cat-toggle' ).on( 'click.press-this', function() {
 833                  var $this = $( this );
 834  
 835                  $this.toggleClass( 'is-toggled' );
 836                  $this.attr( 'aria-expanded', 'false' === $this.attr( 'aria-expanded' ) ? 'true' : 'false' );
 837                  $( '.setting-modal .add-category, .categories-search-wrapper' ).toggleClass( 'is-hidden' );
 838              } );
 839  
 840              $( 'button.add-cat-submit' ).on( 'click.press-this', saveNewCategory );
 841  
 842              $( '.categories-search' ).on( 'keyup.press-this', function() {
 843                  var search = $( this ).val().toLowerCase() || '';
 844  
 845                  // Don't search when less thasn 3 extended ASCII chars
 846                  if ( /[\x20-\xFF]+/.test( search ) && search.length < 2 ) {
 847                      return;
 848                  }
 849  
 850                  $.each( catsCache, function( i, cat ) {
 851                      cat.node.removeClass( 'is-hidden searched-parent' );
 852                  } );
 853  
 854                  if ( search ) {
 855                      $.each( catsCache, function( i, cat ) {
 856                          if ( cat.text.indexOf( search ) === -1 ) {
 857                              cat.node.addClass( 'is-hidden' );
 858                          } else {
 859                              cat.parents.addClass( 'searched-parent' );
 860                          }
 861                      } );
 862                  }
 863              } );
 864  
 865              $textEditor.on( 'focus.press-this input.press-this propertychange.press-this', textEditorResize );
 866  
 867              return true;
 868          }
 869  
 870  		function refreshCatsCache() {
 871              $( '.categories-select' ).find( 'li' ).each( function() {
 872                  var $this = $( this );
 873  
 874                  catsCache.push( {
 875                      node: $this,
 876                      parents: $this.parents( 'li' ),
 877                      text: $this.children( '.category' ).text().toLowerCase()
 878                  } );
 879              } );
 880          }
 881  
 882          // Let's go!
 883          $document.ready( function() {
 884              render();
 885              monitor();
 886              refreshCatsCache();
 887          });
 888  
 889          // Expose public methods?
 890          return {
 891              renderNotice: renderNotice,
 892              renderError: renderError
 893          };
 894      };
 895  
 896      window.wp = window.wp || {};
 897      window.wp.pressThis = new PressThis();
 898  
 899  }( jQuery, window ));


Generated: Sun Sep 24 01:00:03 2017 Cross-referenced by PHPXref 0.7.1