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


Generated : Sun Sep 13 08:20:28 2026 Cross-referenced by PHPXref