paragraphs-8.x-1.11/js/paragraphs.admin.js
js/paragraphs.admin.js
(function ($, Drupal, once) { 'use strict'; /** * Set content fields to visible when tabs are created. After an action * being performed, stay on the same perspective. * * @param $parWidget * Paragraphs widget. * @param $parTabs * Paragraphs tabs. * @param $parContent * Paragraphs content tab. * @param $parBehavior * Paragraphs behavior tab. * @param $mainRegion * Main paragraph region. */ var setUpTab = function ($parWidget, $parTabs, $parContent, $parBehavior, $mainRegion) { var $tabContent = $parTabs.find('.paragraphs_content_tab'); var $tabBehavior = $parTabs.find('.paragraphs_behavior_tab'); if ($tabBehavior.hasClass('is-active')) { $parWidget.removeClass('content-active').addClass('behavior-active'); $tabContent.removeClass('is-active'); $tabContent.find('a').removeClass('is-active'); $tabBehavior.addClass('is-active'); $tabBehavior.find('a').addClass('is-active'); } else { // Activate content tab visually if there is no previously // activated tab. if (!($mainRegion.hasClass('content-active')) && !($mainRegion.hasClass('behavior-active'))) { $tabContent.addClass('is-active'); $tabContent.find('a').addClass('is-active'); $parWidget.addClass('content-active'); } $parTabs.removeClass('paragraphs-tabs-hide'); if ($parBehavior.length === 0) { $parTabs.addClass('paragraphs-tabs-hide'); } } }; /** * Switching active class between tabs. * @param $parTabs * Paragraphs tabs. * @param $clickedTab * Clicked tab. * @param $parWidget * Paragraphs widget. */ var switchActiveClass = function ($parTabs, $clickedTab, $parWidget) { var $clickedTabParent = $clickedTab.parent(); $parTabs.find('li').removeClass('is-active'); $parTabs.find('li').find('a').removeClass('is-active'); $clickedTabParent.addClass('is-active'); $clickedTabParent.find('a').addClass('is-active'); $parWidget.removeClass('behavior-active content-active'); if ($clickedTabParent.hasClass('paragraphs_content_tab')) { $parWidget.addClass('content-active'); $parWidget.find('.paragraphs-add-wrapper').parent().removeClass('hidden'); } else { $parWidget.addClass('behavior-active'); $parWidget.find('.paragraphs-add-wrapper').parent().addClass('hidden'); } }; /** * Add class to first paragraph in the viewport. * * In order to have a persistent position when switching tabs, * we add a class to the first paragraph visible in the viewport. */ var markFirstVisibleParagraph = function (totalTopOffset) { var $window = $(window); var bottomOfScreen = $window.scrollTop() + $window.height(); var topOfScreen = $window.scrollTop() + totalTopOffset; var $firstParagraph = false; // @todo Make sure to skip non-Paragraph draggable field widget items here. var $allParagraphs = $('.node-form .draggable'); $allParagraphs.each(function () { var $this = $(this); var topOfElement = $this.offset().top; var bottomOfElement = $this.offset().top + $this.height(); // Search for paragraphs inside the viewport. if ((bottomOfScreen > topOfElement) && (topOfScreen < bottomOfElement)) { if ($firstParagraph) { // Find next best Paragraph in Viewport. if (topOfElement > topOfScreen ) { // Second top in screen or first nested in screen. $firstParagraph = $this; return false; } else if(topOfElement > bottomOfScreen) { // Choose previous element. return false; } } $firstParagraph = $this; if (topOfScreen < topOfElement) { // Choose this element as it starts in viewport. return false; } } }); if ($firstParagraph) { // Remove potential previous marker. $('.first-paragraph').removeClass('first-paragraph'); // Add the class to the first paragraph in the viewport. $firstParagraph.addClass('first-paragraph paragraph-hover'); } return $firstParagraph; }; /** * For body tag, adds tabs for selecting how the content will be displayed. * * @type {Drupal~behavior} */ Drupal.behaviors.bodyTabs = { attach: function (context) { var $topLevelParWidgets = $('.paragraphs-tabs-wrapper', context).filter(function() { return $(this).parents('.paragraphs-nested').length === 0; }); // Initialization. $(once('paragraphs-bodytabs', $topLevelParWidgets)).each(function() { var $parWidget = $(this); var $parTabs = $parWidget.find('.paragraphs-tabs'); // Create click event. $parTabs.find('a').click(function(e) { var toolbarHeight = $('.toolbar-tray-horizontal').outerHeight() || 0; var adminToolbarsOffset = $('#toolbar-bar').outerHeight() + toolbarHeight; var totalTopOffset = adminToolbarsOffset + $('.paragraphs-tabs').outerHeight(); var $firstParagraph; var currentParagraphOffset = 0; var $window = $(window); $firstParagraph = markFirstVisibleParagraph(totalTopOffset); // Set the proper window position for each tab. if ($firstParagraph) { // Maintain vertical offset in addition to the toolbar heights. currentParagraphOffset = $firstParagraph.offset().top - ($window.scrollTop() + totalTopOffset); // Ignore a negative offset. if (currentParagraphOffset < 0) { currentParagraphOffset = 0; } } e.preventDefault(); switchActiveClass($parTabs, $(this), $parWidget); // We need to check to which position to scroll to, whenever we need to scroll. // If the first paragraph is the same, we maintain the scroll position, otherwise scroll to top of the paragraph. if ($firstParagraph) { $('html, body').scrollTop($firstParagraph.offset().top - totalTopOffset - currentParagraphOffset); // Reset the first paragraph class with a delay, in order for the background change to be visible. setTimeout(function() { $('.first-paragraph').removeClass('paragraph-hover'); }, 1000); } }); }); if ($('.paragraphs-tabs-wrapper', context).length > 0) { $topLevelParWidgets.each(function() { var $parWidget = $(this); var $parTabs = $parWidget.find('.paragraphs-tabs'); var $parContent = $parWidget.find('.paragraphs-content'); var $parBehavior = $parWidget.find('.paragraphs-behavior'); var $mainRegion = $parWidget.find('.layout-region-node-main'); setUpTab($parWidget, $parTabs, $parContent, $parBehavior, $mainRegion); }); } } }; })(jQuery, Drupal, once);