/** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, _, Backbone, Drupal, drupalSettings, JSON, storage) { var options = $.extend(drupalSettings.quickedit, { strings: { quickEdit: Drupal.t('Quick edit') } }); var fieldsMetadataQueue = []; var fieldsAvailableQueue = []; var contextualLinksQueue = []; var entityInstancesTracker = {}; Drupal.behaviors.quickedit = { attach: function attach(context) { $('body').once('quickedit-init').each(initQuickEdit); var $fields = $(context).find('[data-quickedit-field-id]').once('quickedit'); if ($fields.length === 0) { return; } $(context).find('[data-quickedit-entity-id]').once('quickedit').each(function (index, entityElement) { processEntity(entityElement); }); $fields.each(function (index, fieldElement) { processField(fieldElement); }); contextualLinksQueue = _.filter(contextualLinksQueue, function (contextualLink) { return !initializeEntityContextualLink(contextualLink); }); fetchMissingMetadata(function (fieldElementsWithFreshMetadata) { _.each(fieldElementsWithFreshMetadata, processField); contextualLinksQueue = _.filter(contextualLinksQueue, function (contextualLink) { return !initializeEntityContextualLink(contextualLink); }); }); }, detach: function detach(context, settings, trigger) { if (trigger === 'unload') { deleteContainedModelsAndQueues($(context)); } } }; Drupal.quickedit = { app: null, collections: { entities: null, fields: null }, editors: {}, metadata: { has: function has(fieldID) { return storage.getItem(this._prefixFieldID(fieldID)) !== null; }, add: function add(fieldID, metadata) { storage.setItem(this._prefixFieldID(fieldID), JSON.stringify(metadata)); }, get: function get(fieldID, key) { var metadata = JSON.parse(storage.getItem(this._prefixFieldID(fieldID))); return typeof key === 'undefined' ? metadata : metadata[key]; }, _prefixFieldID: function _prefixFieldID(fieldID) { return 'Drupal.quickedit.metadata.' + fieldID; }, _unprefixFieldID: function _unprefixFieldID(fieldID) { return fieldID.substring(26); }, intersection: function intersection(fieldIDs) { var prefixedFieldIDs = _.map(fieldIDs, this._prefixFieldID); var intersection = _.intersection(prefixedFieldIDs, _.keys(sessionStorage)); return _.map(intersection, this._unprefixFieldID); } } }; var permissionsHashKey = Drupal.quickedit.metadata._prefixFieldID('permissionsHash'); var permissionsHashValue = storage.getItem(permissionsHashKey); var permissionsHash = drupalSettings.user.permissionsHash; if (permissionsHashValue !== permissionsHash) { if (typeof permissionsHash === 'string') { _.chain(storage).keys().each(function (key) { if (key.substring(0, 26) === 'Drupal.quickedit.metadata.') { storage.removeItem(key); } }); } storage.setItem(permissionsHashKey, permissionsHash); } $(document).on('drupalContextualLinkAdded', function (event, data) { if (data.$region.is('[data-quickedit-entity-id]')) { if (!data.$region.is('[data-quickedit-entity-instance-id]')) { data.$region.once('quickedit'); processEntity(data.$region.get(0)); } var contextualLink = { entityID: data.$region.attr('data-quickedit-entity-id'), entityInstanceID: data.$region.attr('data-quickedit-entity-instance-id'), el: data.$el[0], region: data.$region[0] }; if (!initializeEntityContextualLink(contextualLink)) { contextualLinksQueue.push(contextualLink); } } }); function extractEntityID(fieldID) { return fieldID.split('/').slice(0, 2).join('/'); } function initQuickEdit(bodyElement) { Drupal.quickedit.collections.entities = new Drupal.quickedit.EntityCollection(); Drupal.quickedit.collections.fields = new Drupal.quickedit.FieldCollection(); Drupal.quickedit.app = new Drupal.quickedit.AppView({ el: bodyElement, model: new Drupal.quickedit.AppModel(), entitiesCollection: Drupal.quickedit.collections.entities, fieldsCollection: Drupal.quickedit.collections.fields }); } function processEntity(entityElement) { var entityID = entityElement.getAttribute('data-quickedit-entity-id'); if (!entityInstancesTracker.hasOwnProperty(entityID)) { entityInstancesTracker[entityID] = 0; } else { entityInstancesTracker[entityID]++; } var entityInstanceID = entityInstancesTracker[entityID]; entityElement.setAttribute('data-quickedit-entity-instance-id', entityInstanceID); } function processField(fieldElement) { var metadata = Drupal.quickedit.metadata; var fieldID = fieldElement.getAttribute('data-quickedit-field-id'); var entityID = extractEntityID(fieldID); var entityElementSelector = '[data-quickedit-entity-id="' + entityID + '"]'; var $entityElement = $(entityElementSelector); if (!$entityElement.length) { throw new Error('Quick Edit could not associate the rendered entity field markup (with [data-quickedit-field-id="' + fieldID + '"]) with the corresponding rendered entity markup: no parent DOM node found with [data-quickedit-entity-id="' + entityID + '"]. This is typically caused by the theme\'s template for this entity type forgetting to print the attributes.'); } var entityElement = $(fieldElement).closest($entityElement); if (entityElement.length === 0) { var $lowestCommonParent = $entityElement.parents().has(fieldElement).first(); entityElement = $lowestCommonParent.find($entityElement); } var entityInstanceID = entityElement.get(0).getAttribute('data-quickedit-entity-instance-id'); if (!metadata.has(fieldID)) { fieldsMetadataQueue.push({ el: fieldElement, fieldID: fieldID, entityID: entityID, entityInstanceID: entityInstanceID }); return; } if (metadata.get(fieldID, 'access') !== true) { return; } if (Drupal.quickedit.collections.entities.findWhere({ entityID: entityID, entityInstanceID: entityInstanceID })) { initializeField(fieldElement, fieldID, entityID, entityInstanceID); } else { fieldsAvailableQueue.push({ el: fieldElement, fieldID: fieldID, entityID: entityID, entityInstanceID: entityInstanceID }); } } function initializeField(fieldElement, fieldID, entityID, entityInstanceID) { var entity = Drupal.quickedit.collections.entities.findWhere({ entityID: entityID, entityInstanceID: entityInstanceID }); $(fieldElement).addClass('quickedit-field'); var field = new Drupal.quickedit.FieldModel({ el: fieldElement, fieldID: fieldID, id: fieldID + '[' + entity.get('entityInstanceID') + ']', entity: entity, metadata: Drupal.quickedit.metadata.get(fieldID), acceptStateChange: _.bind(Drupal.quickedit.app.acceptEditorStateChange, Drupal.quickedit.app) }); Drupal.quickedit.collections.fields.add(field); } function fetchMissingMetadata(callback) { if (fieldsMetadataQueue.length) { var fieldIDs = _.pluck(fieldsMetadataQueue, 'fieldID'); var fieldElementsWithoutMetadata = _.pluck(fieldsMetadataQueue, 'el'); var entityIDs = _.uniq(_.pluck(fieldsMetadataQueue, 'entityID'), true); entityIDs = _.difference(entityIDs, Drupal.quickedit.metadata.intersection(entityIDs)); fieldsMetadataQueue = []; $.ajax({ url: Drupal.url('quickedit/metadata'), type: 'POST', data: { 'fields[]': fieldIDs, 'entities[]': entityIDs }, dataType: 'json', success: function success(results) { _.each(results, function (fieldMetadata, fieldID) { Drupal.quickedit.metadata.add(fieldID, fieldMetadata); }); callback(fieldElementsWithoutMetadata); } }); } } function loadMissingEditors(callback) { var loadedEditors = _.keys(Drupal.quickedit.editors); var missingEditors = []; Drupal.quickedit.collections.fields.each(function (fieldModel) { var metadata = Drupal.quickedit.metadata.get(fieldModel.get('fieldID')); if (metadata.access && _.indexOf(loadedEditors, metadata.editor) === -1) { missingEditors.push(metadata.editor); Drupal.quickedit.editors[metadata.editor] = false; } }); missingEditors = _.uniq(missingEditors); if (missingEditors.length === 0) { callback(); return; } var loadEditorsAjax = Drupal.ajax({ url: Drupal.url('quickedit/attachments'), submit: { 'editors[]': missingEditors } }); var realInsert = Drupal.AjaxCommands.prototype.insert; loadEditorsAjax.commands.insert = function (ajax, response, status) { _.defer(callback); realInsert(ajax, response, status); }; loadEditorsAjax.execute(); } function initializeEntityContextualLink(contextualLink) { var metadata = Drupal.quickedit.metadata; function hasFieldWithPermission(fieldIDs) { for (var i = 0; i < fieldIDs.length; i++) { var fieldID = fieldIDs[i]; if (metadata.get(fieldID, 'access') === true) { return true; } } return false; } function allMetadataExists(fieldIDs) { return fieldIDs.length === metadata.intersection(fieldIDs).length; } var fields = _.where(fieldsAvailableQueue, { entityID: contextualLink.entityID, entityInstanceID: contextualLink.entityInstanceID }); var fieldIDs = _.pluck(fields, 'fieldID'); if (fieldIDs.length === 0) { return false; } else if (hasFieldWithPermission(fieldIDs)) { var entityModel = new Drupal.quickedit.EntityModel({ el: contextualLink.region, entityID: contextualLink.entityID, entityInstanceID: contextualLink.entityInstanceID, id: contextualLink.entityID + '[' + contextualLink.entityInstanceID + ']', label: Drupal.quickedit.metadata.get(contextualLink.entityID, 'label') }); Drupal.quickedit.collections.entities.add(entityModel); var entityDecorationView = new Drupal.quickedit.EntityDecorationView({ el: contextualLink.region, model: entityModel }); entityModel.set('entityDecorationView', entityDecorationView); _.each(fields, function (field) { initializeField(field.el, field.fieldID, contextualLink.entityID, contextualLink.entityInstanceID); }); fieldsAvailableQueue = _.difference(fieldsAvailableQueue, fields); var initContextualLink = _.once(function () { var $links = $(contextualLink.el).find('.contextual-links'); var contextualLinkView = new Drupal.quickedit.ContextualLinkView($.extend({ el: $('
  • ').prependTo($links), model: entityModel, appModel: Drupal.quickedit.app.model }, options)); entityModel.set('contextualLinkView', contextualLinkView); }); loadMissingEditors(initContextualLink); return true; } else if (allMetadataExists(fieldIDs)) { return true; } return false; } function deleteContainedModelsAndQueues($context) { $context.find('[data-quickedit-entity-id]').addBack('[data-quickedit-entity-id]').each(function (index, entityElement) { var entityModel = Drupal.quickedit.collections.entities.findWhere({ el: entityElement }); if (entityModel) { var contextualLinkView = entityModel.get('contextualLinkView'); contextualLinkView.undelegateEvents(); contextualLinkView.remove(); entityModel.get('entityDecorationView').remove(); entityModel.destroy(); } function hasOtherRegion(contextualLink) { return contextualLink.region !== entityElement; } contextualLinksQueue = _.filter(contextualLinksQueue, hasOtherRegion); }); $context.find('[data-quickedit-field-id]').addBack('[data-quickedit-field-id]').each(function (index, fieldElement) { Drupal.quickedit.collections.fields.chain().filter(function (fieldModel) { return fieldModel.get('el') === fieldElement; }).invoke('destroy'); function hasOtherFieldElement(field) { return field.el !== fieldElement; } fieldsMetadataQueue = _.filter(fieldsMetadataQueue, hasOtherFieldElement); fieldsAvailableQueue = _.filter(fieldsAvailableQueue, hasOtherFieldElement); }); } })(jQuery, _, Backbone, Drupal, drupalSettings, window.JSON, window.sessionStorage);