[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/ -> customize-models.js (source)

   1  /**
   2   * @output wp-includes/js/customize-models.js
   3   */
   4  
   5  /* global _wpCustomizeHeader */
   6  
   7  /**
   8   * @param {JQueryStatic} $  The jQuery object.
   9   * @param {Object}       wp The WordPress global object.
  10   */
  11  (function( $, wp ) {
  12      var api = wp.customize;
  13      /** @namespace wp.customize.HeaderTool */
  14      api.HeaderTool = {};
  15  
  16  
  17      /**
  18       * wp.customize.HeaderTool.ImageModel
  19       *
  20       * A header image. This is where saves via the Customizer API are
  21       * abstracted away, plus our own Ajax calls to add images to and remove
  22       * images from the user's recently uploaded images setting on the server.
  23       * These calls are made regardless of whether the user actually saves new
  24       * Customizer settings.
  25       *
  26       * @memberOf wp.customize.HeaderTool
  27       * @alias wp.customize.HeaderTool.ImageModel
  28       *
  29       * @class
  30       * @augments Backbone.Model
  31       */
  32      api.HeaderTool.ImageModel = Backbone.Model.extend(/** @lends wp.customize.HeaderTool.ImageModel.prototype */{
  33          /**
  34           * Returns the default attributes for a header image.
  35           *
  36           * @return {Object} Default attributes.
  37           */
  38          defaults: function() {
  39              return {
  40                  header: {
  41                      attachment_id: 0,
  42                      url: '',
  43                      timestamp: _.now(),
  44                      thumbnail_url: ''
  45                  },
  46                  choice: '',
  47                  selected: false,
  48                  random: false
  49              };
  50          },
  51  
  52          /**
  53           * Initializes the model, hiding the header when asked to.
  54           */
  55          initialize: function() {
  56              this.on('hide', this.hide, this);
  57          },
  58  
  59          /**
  60           * Hides the header image, removing it from the site.
  61           */
  62          hide: function() {
  63              this.set('choice', '');
  64              api('header_image').set('remove-header');
  65              api('header_image_data').set('remove-header');
  66          },
  67  
  68          /**
  69           * Removes the image, hiding the header first if it is the current one.
  70           */
  71          destroy: function() {
  72              var data = this.get('header'),
  73                  curr = api.HeaderTool.currentHeader.get('header').attachment_id;
  74  
  75              // If the image we're removing is also the current header,
  76              // unset the latter.
  77              if (curr && data.attachment_id === curr) {
  78                  api.HeaderTool.currentHeader.trigger('hide');
  79              }
  80  
  81              wp.ajax.post( 'custom-header-remove', {
  82                  nonce: _wpCustomizeHeader.nonces.remove,
  83                  wp_customize: 'on',
  84                  theme: api.settings.theme.stylesheet,
  85                  attachment_id: data.attachment_id
  86              });
  87  
  88              this.trigger('destroy', this, this.collection);
  89          },
  90  
  91          /**
  92           * Makes this image the current header image.
  93           */
  94          save: function() {
  95              if (this.get('random')) {
  96                  api('header_image').set(this.get('header').random);
  97                  api('header_image_data').set(this.get('header').random);
  98              } else {
  99                  if (this.get('header').defaultName) {
 100                      api('header_image').set(this.get('header').url);
 101                      api('header_image_data').set(this.get('header').defaultName);
 102                  } else {
 103                      api('header_image').set(this.get('header').url);
 104                      api('header_image_data').set(this.get('header'));
 105                  }
 106              }
 107  
 108              api.HeaderTool.combinedList.trigger('control:setImage', this);
 109          },
 110  
 111          /**
 112           * Adds the image to the theme's uploaded headers.
 113           */
 114          importImage: function() {
 115              var data = this.get('header');
 116              if (data.attachment_id === undefined) {
 117                  return;
 118              }
 119  
 120              wp.ajax.post( 'custom-header-add', {
 121                  nonce: _wpCustomizeHeader.nonces.add,
 122                  wp_customize: 'on',
 123                  theme: api.settings.theme.stylesheet,
 124                  attachment_id: data.attachment_id
 125              } );
 126          },
 127  
 128          /**
 129           * Returns whether the image needs cropping for this theme.
 130           *
 131           * @return {boolean} Whether the image should be cropped.
 132           */
 133          shouldBeCropped: function() {
 134              if (this.get('themeFlexWidth') === true &&
 135                          this.get('themeFlexHeight') === true) {
 136                  return false;
 137              }
 138  
 139              if (this.get('themeFlexWidth') === true &&
 140                  this.get('themeHeight') === this.get('imageHeight')) {
 141                  return false;
 142              }
 143  
 144              if (this.get('themeFlexHeight') === true &&
 145                  this.get('themeWidth') === this.get('imageWidth')) {
 146                  return false;
 147              }
 148  
 149              if (this.get('themeWidth') === this.get('imageWidth') &&
 150                  this.get('themeHeight') === this.get('imageHeight')) {
 151                  return false;
 152              }
 153  
 154              if (this.get('imageWidth') <= this.get('themeWidth')) {
 155                  return false;
 156              }
 157  
 158              return true;
 159          }
 160      });
 161  
 162  
 163      /**
 164       * wp.customize.HeaderTool.ChoiceList
 165       *
 166       * @memberOf wp.customize.HeaderTool
 167       * @alias wp.customize.HeaderTool.ChoiceList
 168       *
 169       * @class
 170       * @augments Backbone.Collection
 171       */
 172      api.HeaderTool.ChoiceList = Backbone.Collection.extend({
 173          model: api.HeaderTool.ImageModel,
 174  
 175          /**
 176           * Orders the collection from most recently used to least.
 177           *
 178           * @param {Backbone.Model} model The model to sort.
 179           * @return {number} The sort order.
 180           */
 181          comparator: function(model) {
 182              return -model.get('header').timestamp;
 183          },
 184  
 185          /**
 186           * Initializes the collection from the uploaded header images.
 187           */
 188          initialize: function() {
 189              var current = api.HeaderTool.currentHeader.get('choice').replace(/^https?:\/\//, ''),
 190                  isRandom = this.isRandomChoice(api.get().header_image);
 191  
 192              // Overridable by an extending class.
 193              if (!this.type) {
 194                  this.type = 'uploaded';
 195              }
 196  
 197              // Overridable by an extending class.
 198              if (typeof this.data === 'undefined') {
 199                  this.data = _wpCustomizeHeader.uploads;
 200              }
 201  
 202              if (isRandom) {
 203                  // So that when adding data we don't hide regular images.
 204                  current = api.get().header_image;
 205              }
 206  
 207              this.on('control:setImage', this.setImage, this);
 208              this.on('control:removeImage', this.removeImage, this);
 209              this.on('add', this.maybeRemoveOldCrop, this);
 210              this.on('add', this.maybeAddRandomChoice, this);
 211  
 212              _.each(this.data, function(elt, index) {
 213                  if (!elt.attachment_id) {
 214                      elt.defaultName = index;
 215                  }
 216  
 217                  if (typeof elt.timestamp === 'undefined') {
 218                      elt.timestamp = 0;
 219                  }
 220  
 221                  this.add({
 222                      header: elt,
 223                      choice: elt.url.split('/').pop(),
 224                      selected: current === elt.url.replace(/^https?:\/\//, '')
 225                  }, { silent: true });
 226              }, this);
 227  
 228              if (this.size() > 0) {
 229                  this.addRandomChoice(current);
 230              }
 231          },
 232  
 233          /**
 234           * Removes an image's previous crop once it has been replaced.
 235           *
 236           * @param {Backbone.Model} model Model.
 237           */
 238          maybeRemoveOldCrop: function( model ) {
 239              var newID = model.get( 'header' ).attachment_id || false,
 240                   oldCrop;
 241  
 242              // Bail early if we don't have a new attachment ID.
 243              if ( ! newID ) {
 244                  return;
 245              }
 246  
 247              oldCrop = this.find( function( item ) {
 248                  return ( item.cid !== model.cid && item.get( 'header' ).attachment_id === newID );
 249              } );
 250  
 251              // If we found an old crop, remove it from the collection.
 252              if ( oldCrop ) {
 253                  this.remove( oldCrop );
 254              }
 255          },
 256  
 257          /**
 258           * Adds the random choice once a single image is left.
 259           */
 260          maybeAddRandomChoice: function() {
 261              if (this.size() === 1) {
 262                  this.addRandomChoice();
 263              }
 264          },
 265  
 266          /**
 267           * Adds the random image choice to the collection.
 268           *
 269           * @param {string} initialChoice Initial choice.
 270           */
 271          addRandomChoice: function(initialChoice) {
 272              var isRandomSameType = RegExp(this.type).test(initialChoice),
 273                  randomChoice = 'random-' + this.type + '-image';
 274  
 275              this.add({
 276                  header: {
 277                      timestamp: 0,
 278                      random: randomChoice,
 279                      width: 245,
 280                      height: 41
 281                  },
 282                  choice: randomChoice,
 283                  random: true,
 284                  selected: isRandomSameType
 285              });
 286          },
 287  
 288          /**
 289           * Returns whether a choice is one of the random image choices.
 290           *
 291           * @param {string} choice Choice.
 292           * @return {boolean} Whether the choice is random.
 293           */
 294          isRandomChoice: function(choice) {
 295              return (/^random-(uploaded|default)-image$/).test(choice);
 296          },
 297  
 298          /**
 299           * Returns whether the list title should be hidden.
 300           *
 301           * @return {boolean} Whether the title should be hidden.
 302           */
 303          shouldHideTitle: function() {
 304              return this.size() < 2;
 305          },
 306  
 307          /**
 308           * Marks a single image as the selected one.
 309           *
 310           * @param {Backbone.Model} model Model.
 311           */
 312          setImage: function(model) {
 313              this.each(function(m) {
 314                  m.set('selected', false);
 315              });
 316  
 317              if (model) {
 318                  model.set('selected', true);
 319              }
 320          },
 321  
 322          /**
 323           * Clears the selection.
 324           */
 325          removeImage: function() {
 326              this.each(function(m) {
 327                  m.set('selected', false);
 328              });
 329          }
 330      });
 331  
 332  
 333      /**
 334       * wp.customize.HeaderTool.DefaultsList
 335       *
 336       * @memberOf wp.customize.HeaderTool
 337       * @alias wp.customize.HeaderTool.DefaultsList
 338       *
 339       * @class
 340       * @augments wp.customize.HeaderTool.ChoiceList
 341       * @augments Backbone.Collection
 342       */
 343      api.HeaderTool.DefaultsList = api.HeaderTool.ChoiceList.extend({
 344          /**
 345           * Initializes the collection from the theme's default header images.
 346           */
 347          initialize: function() {
 348              this.type = 'default';
 349              this.data = _wpCustomizeHeader.defaults;
 350              api.HeaderTool.ChoiceList.prototype.initialize.apply(this);
 351          }
 352      });
 353  
 354  })( jQuery, window.wp );


Generated : Fri Sep 4 08:20:24 2026 Cross-referenced by PHPXref