Forked from
project / mercury_editor
50 commits behind, 1 commit ahead of the upstream repository.
-
Justin Toupin authoredJustin Toupin authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
mercury_editor.module 27.42 KiB
<?php
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\mercury_editor\EntityTypeInfo;
use Laminas\Diactoros\Response\RedirectResponse;
/**
* @file
* Mercury editor module.
*/
/**
* Implements hook_library_info_alter().
*
* Attaches our mercury_editor dialog libraries where needed.
*/
function mercury_editor_library_info_alter(&$libraries, $extension) {
if ($extension == 'core' && isset($libraries['drupal.dialog'])) {
$libraries['drupal.dialog']['dependencies'][] = 'mercury_editor/dialog.drupal';
}
if ($extension == 'entity_browser' && isset($libraries['modal_selection'])) {
$libraries['modal_selection']['dependencies'][] = 'mercury_editor/entity_browser.modal_selection';
}
if ($extension == 'layout_paragraphs' && isset($libraries['builder'])) {
$libraries['builder']['dependencies'][] = 'mercury_editor/dialog.ajax';
}
if ($extension == 'image_radios' && isset($libraries['image_radios'])) {
$libraries['image_radios']['dependencies'][] = 'mercury_editor/image_radios';
}
if ($extension == 'claro' && isset($libraries['media_library.theme'])) {
$libraries['media_library.theme']['dependencies'][] = 'mercury_editor/claro.media_library.theme';
}
if ($extension == 'gin' && isset($libraries['media_library'])) {
// When using the gin_toolbar module, we need to add the gin_base and
// gin_accent libraries as dependencies to the media_library library as
// they contain CSS custom property definitions that the media library
// styles rely on. This should probably be fixed in Gin itself.
if (\Drupal::moduleHandler()->moduleExists('gin_toolbar')) {
$libraries['media_library']['dependencies'][] = 'gin/gin_base';
$libraries['media_library']['dependencies'][] = 'gin/gin_accent';
}
}
}
/**
* Implements hook_ajax_render_alter().
*
* Replaces Drupal's ajax Dialog commands with MercuryDialog commands.
*/
function mercury_editor_ajax_render_alter(array &$data): void {
$current_route_name = \Drupal::routeMatch()->getRouteName();
if (
isset($current_route_name)
&& str_starts_with($current_route_name, 'mercury_editor')
) {
foreach ($data as &$command) {
if ($command['command'] == 'openDialog') {
$command['command'] = 'openMercuryDialog';
}
if ($command['command'] == 'closeDialog') {
$command['command'] = 'closeMercuryDialog';
}
}
Drupal::service('mercury_editor.ajax_adapter')->ajaxRenderAlter($data);
}
}
/**
* Implements hook_preprocess().
*
* @see https://www.drupal.org/project/mercury_editor/issues/3379180
* @see contextual_preprocess()
*/
function mercury_editor_preprocess(array &$variables, $hook, $info) {
// Set a css class if the entity is being edited with mercury.
if (isset($variables['elements']['#is_mercury_edit_mode'])) {
$route_match = \Drupal::routeMatch();
$route_name = $route_match->getRouteName();
if ($route_name == 'mercury_editor.preview' || $route_name == 'mercury_editor.editor') {
$variables['page'] = TRUE;
}
$variables['attributes']['class'][] = 'is-mercury-edit-mode';
}
// Determine the primary theme function argument.
if (!empty($info['variables'])) {
$keys = array_keys($info['variables']);
$key = $keys[0];
}
elseif (!empty($info['render element'])) {
$key = $info['render element'];
}
if (!empty($key) && isset($variables[$key])) {
$element = $variables[$key];
}
if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) {
// Disable contextual links on the preview route.
$variables['title_suffix']['#cache']['contexts'][] = 'route.name.is_mercury_editor_preview';
if (\Drupal::routeMatch()->getRouteName() === 'mercury_editor.preview') {
unset($variables['title_suffix']['contextual_links']);
}
}
}
/**
* Implements hook_preprocess_layout_paragraphs_builder_controls().
*
* Set width on component delete modals.
*/
function mercury_editor_preprocess_layout_paragraphs_builder_controls(&$variables) {
/** @var \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout */
$layout = $variables['layout_paragraphs_layout'];
$is_mercury_editor_context = $layout->getSetting('mercury_editor_context') ?? FALSE;
$component = $layout->getComponentByUuid($variables['uuid']);
$paragraph = $component->getEntity();
$paragraph_type = $paragraph->bundle();
if ($is_mercury_editor_context) {
$uuid = $variables['uuid'];
$layout = $variables['layout_paragraphs_layout'];
$component = $layout->getComponentByUuid($uuid);
$type = $component->getEntity()->getParagraphType();
$edit_dialog_options = json_decode($variables['controls']['edit_link']['#attributes']['data-dialog-options']);
$edit_dialog_options->height = 'max-content';
$edit_dialog_options->resizable = TRUE;
$edit_dialog_options = Drupal::service('mercury_editor.dialog')->dialogSettings(['layout' => $layout, 'dialog' => $paragraph_type . '_form']);
$variables['controls']['edit_link']['#attributes']['data-dialog-options'] = json_encode($edit_dialog_options);
$variables['controls']['edit_link']['#attributes']['title'] = t('Edit :type', [':type' => $type->label()]);
_mercury_editor_replace_ajax_class($variables['controls']['edit_link']['#attributes']['class']);
_mercury_editor_replace_layout_paragraphs_routes($variables['controls']['edit_link']['#url']);
$delete_dialog_options = Drupal::service('mercury_editor.dialog')->dialogSettings(['layout' => $layout, 'dialog' => 'delete_form']);
$variables['controls']['delete_link']['#attributes']['data-dialog-options'] = json_encode($delete_dialog_options);
$variables['controls']['delete_link']['#attributes']['title'] = t('Delete :type', [':type' => $type->label()]);
_mercury_editor_replace_ajax_class($variables['controls']['delete_link']['#attributes']['class']);
_mercury_editor_replace_layout_paragraphs_routes($variables['controls']['delete_link']['#url']);
}
}
/**
* Implements hook_preprocess_layout_paragraphs_insert_component_btn().
*
* Alters the "insert component" buttons to use window.postMessage instead
* of directly invoking an Ajax action.
*/
function mercury_editor_preprocess_layout_paragraphs_insert_component_btn(&$variables) {
/** @var \Drupal\Core\Url $variables['url'] */
$parameters = $variables['url']->getRouteParameters();
$layout_id = $parameters['layout_paragraphs_layout'];
$layout = \Drupal::service('layout_paragraphs.tempstore_repository')->getWithStorageKey($layout_id);
$is_mercury_editor_context = $layout->getSetting('mercury_editor_context') ?? FALSE;
if (!$is_mercury_editor_context) {
return;
}
_mercury_editor_replace_ajax_class($variables['attributes']['class']);
_mercury_editor_replace_layout_paragraphs_routes($variables['url']);
$old_options = json_decode($variables['attributes']['data-dialog-options'], TRUE);
$dialog_options = ['target' => $old_options['target']] + Drupal::service('mercury_editor.dialog')->dialogSettings(['dialog' => 'component_menu']);
$variables['attributes']['data-dialog-options'] = json_encode($dialog_options);
}
/**
* Helper function to replace use-ajax classes with use-postmessage.
*
* @param array $classes
* An array of classes.
*/
function _mercury_editor_replace_ajax_class(&$classes) {
if (($key = array_search('use-ajax', $classes)) !== FALSE) {
unset($classes[$key]);
$classes[] = 'use-postmessage';
}
}
/**
* Helper function to replace layout paragraph routes with mercury editor ones.
*
* @param \Drupal\Core\Url $url
* The url object.
*/
function _mercury_editor_replace_layout_paragraphs_routes(Url &$url) {
$route_name = $url->getRouteName();
$parameters = $url->getRouteParameters();
$options = $url->getOptions();
$route_name = str_replace('layout_paragraphs.', 'mercury_editor.', $route_name);
$url = Url::fromRoute($route_name, $parameters, $options);
}
/**
* Implements hook_theme_suggestions_page_alter().
*
* Adds page__mercury_editor as a suggestion for applicable content types.
*/
function mercury_editor_theme_suggestions_page_alter(array &$suggestions, array $variables) {
$name = \Drupal::routeMatch()->getRouteName();
if ($name === 'mercury_editor.preview') {
$mercury_editor_entity = \Drupal::routeMatch()->getParameter('mercury_editor_entity');
$suggestions[] = 'page__' . $mercury_editor_entity->bundle();
}
if ($name == 'mercury_editor.editor') {
$suggestions[] = 'page__mercury_editor';
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*
* Use the mercury_editor theme suggestion for the component menu.
*/
function mercury_editor_theme_suggestions_layout_paragraphs_builder_component_menu_alter(array &$suggestions, array $variables) {
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name === 'mercury_editor.builder.choose_component') {
$suggestions[] = 'layout_paragraphs_builder_component_menu__mercury_editor';
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*
* Since node forms are set to use a specialized template in the node module,
* we need to set the template suggestion here.
*/
function mercury_editor_theme_suggestions_node_edit_form_alter(array &$suggestions, array $variables) {
if (strpos($variables['form']['#form_id'], '_mercury_editor_form') !== FALSE) {
$suggestions[] = 'mercury_editor_entity_form';
}
}
/**
* Implements hook_entity_build_defaults_alter().
*
* Add cache context for mercury editor preview screen.
*/
function mercury_editor_entity_build_defaults_alter(array &$build, EntityInterface $entity, $view_mode) {
$me_entity_types = \Drupal::config('mercury_editor.settings')->get('bundles');
if (!empty($me_entity_types[$entity->getEntityTypeId()])) {
$build['#cache']['contexts'][] = 'route.name.is_mercury_editor_preview';
}
}
/**
* Implements hook_build_alter().
*/
function mercury_editor_entity_display_build_alter(&$build, $context) {
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name !== 'mercury_editor.preview' && $route_name !== 'mercury_editor.editor') {
return;
}
/** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
$entity = Drupal::service('mercury_editor.tempstore_repository')->get($context['entity']->uuid());
if (!$entity) {
return;
}
$build['#is_mercury_edit_mode'] = TRUE;
// Turns on Layout Paragraphs builder for Mercury Editor LP fields.
if (isset($entity->lp_storage_keys)) {
foreach ($entity->lp_storage_keys as $field_name => $lp_key) {
if (isset($build[$field_name])) {
$layout = \Drupal::service('layout_paragraphs.tempstore_repository')->getWithStorageKey($lp_key);
$build[$field_name] = [
'#type' => 'layout_paragraphs_builder',
'#layout_paragraphs_layout' => $layout,
];
}
}
}
}
/**
* Implements hook_theme().
*/
function mercury_editor_theme() {
return [
'page__mercury_editor' => [
'base hook' => 'page',
],
'mercury_editor_entity_form' => [
'render element' => 'form',
],
'layout_paragraphs_builder_component_menu__mercury_editor' => [
'base hook' => 'layout_paragraphs_builder_component_menu',
],
];
}
/**
* Implements hook_preprocess_html().
*
* Removes admin toolbar for Mercury Editor edit screens.
*/
function mercury_editor_preprocess_html(&$variables) {
if (\Drupal::routeMatch()->getRouteObject()->getOption('_hide_admin_toolbar')) {
// Check if toolbar is enabled.
// Remove toolbar from the page.
unset($variables['page_top']['toolbar']);
// Remove toolbar classes from the body.
$variables['attributes']['class'] = array_filter($variables['attributes']['class'] ?? [], function ($value) {
return strpos($value, 'toolbar-') !== 0;
});
// Check if gin_toolbar is enabled.
if (\Drupal::moduleHandler()->moduleExists('gin_toolbar')) {
// Remove toolbar classes from the body.
$variables['attributes']['class'] = array_filter($variables['attributes']['class'] ?? [], function ($value) {
return strpos($value, 'gin--') !== 0;
});
// Remove toolbar attributes from the body.
$variables['attributes'] = array_filter($variables['attributes'] ?? [], function ($value) {
return strpos($value, 'data-gin') !== 0;
}, ARRAY_FILTER_USE_KEY);
}
// Check if adminimal_admin_toolbar is enabled.
if (\Drupal::moduleHandler()->moduleExists('adminimal_admin_toolbar')) {
// Remove toolbar classes from the body.
$variables['attributes']['class'] = array_filter($variables['attributes']['class'] ?? [], function ($value) {
return strpos($value, 'adminimal-admin-toolbar') !== 0;
});
}
}
}
/**
* Implements hook_preprocess_page().
*
* Adds a select list to the page for choosing from a list of mobile presets.
*/
function mercury_editor_preprocess_page__mercury_editor(&$variables) {
// Get mobile presets from the Mercury Editor settings.
$mobile_presets = \Drupal::config('mercury_editor.settings')->get('mobile_presets') ?? [];
if ($mobile_presets) {
// Parse mobile presets into an array.
$mobile_presets_names = array_map(function ($preset) {
return $preset['width'] . 'x' . $preset['height'];
}, $mobile_presets);
$mobile_presets_values = array_map(function ($preset) {
return $preset['name'] . ' (' . $preset['width'] . 'x' . $preset['height'] . ')';
}, $mobile_presets);
$mobile_presets_options = array_combine($mobile_presets_names, $mobile_presets_values);
$variables['mobile_presets'] = [
'#type' => 'select',
'#options' => $mobile_presets_options,
'#attributes' => [
'class' => ['me-mobile-presets'],
'style' => 'display: none',
],
];
}
// Get uuid from the route.
$mercury_editor_entity = \Drupal::routeMatch()->getParameter('mercury_editor_entity');
$variables['uuid'] = $mercury_editor_entity->uuid();
$variables['entity_type'] = $mercury_editor_entity->getEntityTypeId();
}
/**
* Implements hook_theme_registry_alter().
*
* Make sure this module's hook_preprocess_html implementation runs last.
*/
function mercury_editor_theme_registry_alter(&$theme_registry) {
$index = array_search('mercury_editor_preprocess_html', $theme_registry['html']['preprocess functions']);;
unset($theme_registry['html']['preprocess functions'][$index]);
$theme_registry['html']['preprocess functions'][50] = 'mercury_editor_preprocess_html';
}
/**
* Implements hook_page_attachments().
*/
function mercury_editor_page_attachments(&$attachments) {
if (\Drupal::routeMatch()->getRouteName() == 'mercury_editor.preview') {
$attachments['#attached']['library'][] = 'mercury_editor/preview_screen';
}
}
/**
* Implements hook_page_attachments_alter().
*/
function mercury_editor_page_attachments_alter(array &$attachments) {
if (
\Drupal::routeMatch()->getRouteName() == 'mercury_editor.preview' ||
\Drupal::routeMatch()->getRouteObject()->getOption('_mercury_editor_route')
) {
$theme = \Drupal::theme()->getActiveTheme()->getName();
if ($theme !== 'gin') {
// Remove all gin assets.
$attachments['#attached']['library'] = array_filter($attachments['#attached']['library'], function ($library) {
return strpos($library, 'gin/') !== 0;
});
}
// Remove Gin Toolbar assets.
if (in_array('gin/gin_toolbar', $attachments['#attached']['library'])) {
$index = array_search('gin/gin_toolbar', $attachments['#attached']['library']);
unset($attachments['#attached']['library'][$index]);
}
}
}
/**
* Implements hook_element_info_alter().
*/
function mercury_editor_element_info_alter(array &$types) {
// Attach layout_select overrides.
if (isset($types['layout_select'])) {
$types['layout_select']['#attached']['library'][] = 'mercury_editor/layout_select';
}
}
/**
* Implements hook_preprocess_layout_paragraphs_component_menu().
*/
function mercury_editor_preprocess_layout_paragraphs_builder_component_menu(&$variables) {
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name !== 'mercury_editor.builder.choose_component') {
return;
}
foreach (['layout', 'content'] as $category) {
if (isset($variables['types'][$category])) {
foreach ($variables['types'][$category] as $key => $type) {
if (!empty($variables['types'][$category][$key]['url_object'])) {
_mercury_editor_replace_layout_paragraphs_routes($variables['types'][$category][$key]['url_object']);
$variables['types'][$category][$key]['url'] = $variables['types'][$category][$key]['url_object']->toString();
}
}
}
}
$groups = Drupal::config('mercury_editor.menu.settings')->get('groups');
$groups_array = !empty($groups)
? Yaml::decode($groups)
: [
'default' => [
'label' => 'Default',
'components' => [],
]
];
$types = $variables['types']['content'];
$variables['groups'] = [];
foreach ($groups_array as $name => &$group) {
$variables['groups'][$name] = [
'items' => array_filter(array_map(function ($component) use ($types) {
return $types[$component] ?? FALSE;
}, array_combine($group['components'], $group['components']))),
'label' => $group['label'],
];
}
$default_group = key(array_filter($groups_array, function($group) {
return !empty($group['default']);
})) ?? 'default';
$variables['groups'] = array_filter($variables['groups'], function($group, $id) use ($default_group) {
return count($group['items']) || $id == $default_group;
}, ARRAY_FILTER_USE_BOTH);
$orphaned_types = array_filter(array_keys($types), function($type) use ($variables) {
foreach ($variables['groups'] as $group) {
if (!empty($group['items'][$type])) {
return FALSE;
}
}
return TRUE;
});
foreach ($orphaned_types as $type) {
$variables['groups'][$default_group]['items'][$type] = $types[$type];
}
$variables['#attached']['library'][] = 'mercury_editor/menu';
$variables['#attached']['library'][] = 'mercury_editor/lpb_component_list';
}
/**
* Implenents hook_preprocess_HOOK().
* Implements hook_preprocess_layout_paragraphs_builder().
*/
function mercury_editor_preprocess_layout_paragraphs_builder(&$variables) {
$entity = $variables['layout_paragraphs_layout']->getEntity();
$field_name = $variables['layout_paragraphs_layout']->getFieldName();
$field_ref = [
$entity->getEntityTypeId(),
$entity->id(),
$field_name,
];
$variables['attributes']['data-lp-field-ref'] = implode('/', $field_ref);
$variables['#attached']['library'][] = 'mercury_editor/mercury_editor';
}
/**
* Implements hook_toolbar_alter().
*/
function mercury_editor_toolbar_alter(&$items) {
if (isset($items['primary_tasks'])) {
$items['primary_tasks']['#weight'] = -1000;
$classes =& $items['primary_tasks']['tray']['toolbar_actions']['#attributes']['class'];
$classes[] = 'toolbar-menu';
if (($key = array_search('toolbar-menu-administration', $classes)) !== false) {
unset($classes[$key]);
}
}
}
/**
* Implements hook_preproces_field().
*/
function mercury_editor_preprocess_field(&$variables) {
// If in the mercury editor preview route.
if (\Drupal::routeMatch()->getRouteName() !== 'mercury_editor.preview') {
return;
}
if (isset($variables['entity_type']) && isset($variables['element']['#object'])) {
$variables['attributes']['data-sync-changes'] = $variables['entity_type'] . '/' . $variables['element']['#object']->uuid() . '/' . $variables['field_name'];
}
}
/**
* Implements hook_entity_type_build().
*/
function mercury_editor_entity_type_build(array &$entity_types) {
$entity_types['node']->setFormClass('mercury_editor', 'Drupal\mercury_editor\Entity\MercuryEditorNodeForm');
$entity_types['taxonomy_term']->setFormClass('mercury_editor', 'Drupal\mercury_editor\Entity\MercuryEditorTermForm');
}
/**
* Implements hook_entity_prepare_form().
*/
function mercury_editor_entity_prepare_form(EntityInterface $entity, $operation, FormStateInterface $form_state) {
// If content moderation module is enabled.
if (\Drupal::moduleHandler()->moduleExists('content_moderation')) {
\Drupal::service('class_resolver')
->getInstanceFromDefinition(EntityTypeInfo::class)
->entityPrepareForm($entity, $operation, $form_state);
}
}
/**
* Implements hook_form_alter().
*/
function mercury_editor_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (\Drupal::moduleHandler()->moduleExists('content_moderation')) {
\Drupal::service('class_resolver')
->getInstanceFromDefinition(EntityTypeInfo::class)
->formAlter($form, $form_state, $form_id);
}
}
/**
* Implements hook_module_implements_alter().
*
* Removes hook_form_alter and hook_entity_prepare_form implementations
* from content_moderation module.
*
* @see content_moderation_form_alter().
* @see content_moderation_entity_prepare_form().
*/
function mercury_editor_module_implements_alter(&$implementations, $hook) {
if ($hook == 'form_alter' || $hook == 'entity_prepare_form') {
if (isset($implementations['content_moderation'])) {
unset($implementations['content_moderation']);
}
}
}
/**
* Implements hook_preprocess_toolbar().
*
* Replaces the edit link with the Mercury Editor edit link.
*/
function mercury_editor_preprocess_toolbar(&$variables) {
if (!empty($variables['entity_edit_url'])) {
$entity = $variables['entity_edit_url']->getOption('entity');
$content_type = $entity->bundle();
if (_mercury_editor_applies_to_content_type($content_type)) {
$options = $variables['entity_edit_url']->getOptions();
$parameters = $variables['entity_edit_url']->getRouteParameters();
$parameters['mercury_editor_entity'] = $entity->uuid();
$parameters['entity_type'] = $entity->getEntityTypeId();
$variables['entity_edit_url'] = Url::fromRoute('mercury_editor.editor', $parameters, $options);
}
}
}
/**
* Implements hook_entity_view().
*/
function mercury_editor_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
// @todo Need a better way to define when this gets added.
$me_entity_types = \Drupal::config('mercury_editor.settings')->get('bundles');
if ($view_mode == 'full' && isset($me_entity_types[$entity->getEntityTypeId()])) {
$build['#attributes']['data-me-edit-screen-key'] = $entity->uuid();
$id = $entity->id();
if ($id) {
$build['#attributes']['data-me-edit-screen-entity-id'] = $entity->id();
}
}
}
/**
* Impelements hook_preprocess_layout_paragraphs_builder_formatter().
*/
function mercury_editor_preprocess_layout_paragraphs_builder_formatter(&$variables) {
$variables['#attached']['library'][] = 'mercury_editor/mercury_editor';
$variables['#attached']['library'][] = 'mercury_editor/field_formatter';
}
/**
* Implements hook_entity_view_alter().
*/
function mercury_editor_entity_view_alter(&$build, $entity, $display) {
$build['#attached']['library'][] = 'mercury_editor/me_dialog';
}
/**
* Implements hook_form_FORM_ID_alter().
* Implements hook_form_layout_paragraphs_builder_form_alter().
*/
function mercury_editor_form_layout_paragraphs_builder_form_alter(&$form, $form_state) {
if (empty($form['#attached']['library'])) {
$form['#attached']['library'] = [];
}
$form['#attached']['library'][] = 'mercury_editor/mercury_editor';
}
/**
* Implements hook_form_FORM_ID_alter().
* Implements hook_layout_paragraphs_component_form_alter().
*/
function mercury_editor_form_layout_paragraphs_component_form_alter(&$form, $form_state) {
$form['uuid'] = [
'#type' => 'hidden',
'#value' => $form['#paragraph']->uuid(),
];
$form['actions']['#attributes']['class'][] = 'me-form-actions';
$form['#attached']['library'][] = 'mercury_editor/mercury_editor';
$form['tabs'] = [
'#type' => 'radios',
'#options' => [],
'#weight' => -1000,
'#wrapper_attributes' => [
'class' => ['me-horizontal-tab-radios', 'me-tabs'],
],
'#after_build' => ['mercury_editor_after_build_radios'],
];
if (isset($form['layout_paragraphs'])) {
$form['layout_paragraphs']['#process'][] = 'mercury_editor_layout_paragraphs_form_process';
}
$form['#after_build'][] = 'mercury_editor_after_build_form';
$field_keys = array_filter(
Element::children($form),
function ($key) use ($form) {
return strpos($key, 'field_') === 0 && Element::isVisibleElement($form[$key]);
});
if (count($field_keys)) {
$form['tabs']['#options']['content'] = t('Content');
$form['tabs']['#default_value'] = 'content';
foreach ($field_keys as $key) {
$form[$key]['#attributes']['class'][] = 'me-tab-group';
$form[$key]['#attributes']['class'][] = 'me-tab-group--content';
}
}
// @todo Make this work for all behaviors, not just styles.
if (isset($form['behavior_plugins'])) {
$form['tabs']['#options']['styles'] = t('Styles');
$form['behavior_plugins']['#type'] = 'container';
$form['behavior_plugins']['#attributes']['class'][] = 'me-tab-group';
$form['behavior_plugins']['#attributes']['class'][] = 'me-tab-group--styles';
}
}
/**
* Processes the layout paragraphs form element.
*
* @param array $element
* The form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The processed element.
*/
function mercury_editor_layout_paragraphs_form_process(array $element, FormStateInterface $form_state, &$form) {
if (!empty($element['layout'])) {
$form['tabs']['#options']['layout'] = t('Layout');
$form['tabs']['#default_value'] = 'layout';
$element['layout']['#prefix'] = '<div class="me-tab-group me-tab-group--layout">';
$element['layout']['#suffix'] = '</div>';
}
if (!empty($element['config'])) {
// @todo See if there is a better way to update the weight of this element
// to come after the layout tab, rather than unsetting and re-adding it.
unset($form['tabs']['#options']['styles']);
$form['tabs']['#options']['styles'] = t('Styles');
$element['config']['#type'] = 'container';
$element['config']['#prefix'] = '<div class="me-tab-group me-tab-group--styles ">';
$element['config']['#suffix'] = '</div>';
}
return $element;
}
/**
* After build callback for adding classes to radio tabs.
*/
function mercury_editor_after_build_radios($element, $form_state) {
foreach (Element::children($element) as $key) {
$element[$key]['#wrapper_attributes']['class'][] = 'horizontal-tab--' . $key;
}
return $element;
}
function mercury_editor_after_build_form($form, $form_state) {
if (isset($form['tabs']) && count($form['tabs']['#options']) < 2) {
$form['tabs']['#access'] = FALSE;
}
else {
$form['#attached']['library'][] = 'mercury_editor/horizontal_tabs';
}
return $form;
}
/**
* Implements hook_form_FORM_ID_alter().
* Implements hook_layout_paragraphs_delete_component_form_alter().
*/
function mercury_editor_form_layout_paragraphs_delete_component_form_alter(&$form, $form_state) {
$form['actions']['#attributes']['class'][] = 'me-form-actions';
$form['#attached']['library'][] = 'mercury_editor/lpb_component_delete_form';
}
/**
* Returns TRUE if $type uses Mercury Editor.
*
* @param string $type
* The content type.
*
* @return bool
* TRUE if applies to content type.
*/
function _mercury_editor_applies_to_content_type($type) {
$content_types = \Drupal::configFactory()->get('mercury_editor.settings')->get('content_types');
if (empty($content_types[$type])) {
return FALSE;
}
return TRUE;
}