compose-8.x-1.x-dev/js/compose-entity-widget.js
js/compose-entity-widget.js
(function ($, Drupal, drupalSettings, Sortable) {
'use strict';
Drupal.behaviors.composeEntityWidgetRender = {
attach: function (context, settings) {
$('[data-compose-entity-widget]', context).once('composeEntityWidget').each(function () {
var formBuildId = document.querySelector(`input[name="form_build_id"]`).value;
var entityReference = this.querySelectorAll(`[data-compose-delta][data-compose-field-name]`);
entityReference.forEach(function (entity) {
// Get values from data attributes.
var delta = entity.dataset.composeDelta;
var fieldName = entity.dataset.composeFieldName;
var entityId = entity.dataset.composeEntityId;
var entityType = entity.dataset.composeEntityType;
// Use the entity ID in the route if present.
var path = (entityId) ? `compose/preview/${formBuildId}/${fieldName}/${delta}/${entityType}/${entityId}` : `compose/preview/${formBuildId}/${fieldName}/${delta}/${entityType}`;
var endpoint = Drupal.url(path);
$.get(endpoint, function (responseData) {
// With each entity reference, create a shadowDOM under the div(s)
// we created above and insert the markup, styles and scripts
// returned in the AJAX call to these shadowDOM(s).
var entityPlaceholder = $(`[data-compose-delta="${delta}"][data-compose-field-name="${fieldName}"]`);
entityPlaceholder.html('');
entityPlaceholder.css({ "display": "block" });
var shadow = entityPlaceholder.get(0).attachShadow({ mode: 'open' });
shadow.innerHTML = "<style>:host { all: initial; height: auto !important;} .entity-preview-content-wrapper {overflow: hidden;}</style>";
var $shadow = $(shadow);
// Watch for changes to the DOM so we can handle the height
// var timeoout = null;
var callback = function(mutationList, observer) {
var $content = $shadow.find('.entity-preview-content-wrapper');
var $parent = entityPlaceholder.parent();
(function($shadow, $content, $parent, entityPlaceholder) {
window.setTimeout(function() {
var height = $content.outerHeight() + parseFloat(entityPlaceholder.css('padding-top')) + parseFloat(entityPlaceholder.css('padding-bottom'));
var parentHeight = $parent.height();
if (height * 0.7 > parentHeight) {
$parent.append(Drupal.theme('composePreviewReveal'))
.find('.compose-preview-reveal').click(function() {
var isRevealed = $parent.hasClass('revealed');
$parent.toggleClass('revealed');
if (isRevealed) {
$parent.css({'max-height': ''});
$(this).text("Reveal");
}
else {
$parent.css({'max-height': $parent.get(0).style.height});
$(this).text("Hide");
}
})
$parent.css({ "height": (height * 0.7) + 'px' });
}
}, 500);
})($shadow, $content, $parent, entityPlaceholder);
}
var config = { attributes: true, childList: true, subtree: true };
var observer = new MutationObserver(callback);
observer.observe(shadow, config);
$.each(responseData.css, function (index, value) {
$shadow.append('<link rel="stylesheet" href="' + value + '">');
});
// Disabling scripts because they work inconsistently if at all.
// $.each(responseData.js_header, function (index, value) {
// var s = document.createElement('script');
// s.setAttribute('src', value);
// shadow.appendChild(s);
// });
var $content = $('<div class=\"entity-preview-content-wrapper\"></div>');
$shadow.append($content);
$content.append(responseData.content);
// Open links in a new tab/window to avoid loss of data.
$shadow.find('a').each(function() {
$(this).attr('target', '_blank').click(function(e) {
if (!confirm('Links open in a new window or tab to avoid data loss. Do you want to open this link?')) {
e.preventDefault();
return false;
};
});
});
// Disabling scripts because they work inconsistently if at all.
// $.each(responseData.js_footer, function (index, value) {
// var s = document.createElement('script');
// s.setAttribute('src', value);
// shadow.appendChild(s);
// });
entityPlaceholder.parent().addClass('loaded');
});
});
$('.compose-entity-item', context).each(function() {
// Add tabledrag for sortable
$(this).find('.compose-delta-wrapper').each(function() {
var $this = $(this);
$(Drupal.theme('composeSortHandle'))
.attr('title', Drupal.t('Drag to re-order'))
.prependTo($this);
$this.find('.form-item').addClass('visually-hidden');
});
});
// Sortable
Sortable.create(this, {
animation: 150,
scrollSensitivity: 150,
handle: '.tabledrag-handle',
onUpdate: function(evt) {
var i = 0;
$(evt.to).find(':input[name$="[delta]"]').each(function() {
$(this).val(i);
i++;
});
}
})
});
}
};
Drupal.theme.composeSortHandle = function() {
return '<a href="#" class="tabledrag-handle"><div class="handle"> </div></a>';
}
Drupal.theme.composePreviewReveal = function() {
return '<a class="compose-preview-reveal">Reveal</a>';
}
Drupal.behaviors.composePager = {
attach: function(context, settings) {
function getPageFromUrl(url) {
var matches = url.match(/page=([^&]*)/);
return matches[1].replace('%2C0', '') || 0;
}
$('[data-compose-pager]', context).once('composePager').each(function() {
var ief_id = $(this).data('compose-ief-id');
var $submit = $('[data-compose-pager-submit][data-compose-ief-id="' + ief_id + '"]');
var $update = $('[data-compose-pager-update][data-compose-ief-id="' + ief_id + '"]');
$(this).find('a').click(function(evt) {
evt.preventDefault();
evt.stopPropagation();
var $this = $(this);
$update.val(getPageFromUrl($this.attr('href')));
$submit.mousedown();
return false;
})
});
}
}
Drupal.behaviors.composeEntityWidgetFilter = {
attach: function (context, settings) {
$('[data-drupal-selector*="compose-add-options"] .add-new-row').each(function(){
$(this).addClass('assembly-type-row');
var type_name = $(this).find('[data-drupal-selector*="text-title"]').html();
$(this).attr('data-assembly-type', type_name.toLowerCase());
});
$('input[name*="[compose_add_options][type_filter]"]').once().keyup(function() {
var value = $(this).val().toLowerCase();
if (value.length == 0) {
$('.assembly-type-row').show();
}
else {
$('.assembly-type-row').not('[data-assembly-type*="' + value + '"]').hide();
}
});
}
}
}(jQuery, Drupal, drupalSettings, Sortable));
