blazy-8.x-2.x-dev/modules/blazy_layout/js/blazy-layout.modal.js
modules/blazy_layout/js/blazy-layout.modal.js
/** * @file * Provides Blazy layout utilities. */ (function ($, Drupal, _doc) { 'use strict'; var BASE = 'b-layout'; var ID = BASE + '-form'; var ID_ONCE = ID; var C_MOUNTED = 'is-' + ID_ONCE; var S_BASE = '.form-wrapper--' + BASE; var S_ELEMENT = S_BASE + ':not(.' + C_MOUNTED + ')'; var S_ACTIVE_LAYOUT = '.' + BASE + '.is-layout-builder-highlighted'; var PREFIX_BACKGROUND = 'background_'; var PREFIX_OVERLAY = 'overlay_'; var PREFIX_TEXT = 'text_'; var PREFIX_HEADING = 'heading_'; var PREFIX_LINK = 'link_'; var PREFIX_LINK_HOVER = 'link_hover_'; var TRANSPARENT = 'transparent'; // See https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/addRule // See https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule function addRule(stylesheet, selector, rule) { // This feature is no longer recommended. if (stylesheet.addRule) { stylesheet.addRule(selector, rule); } else if (stylesheet.insertRule) { stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length); } } function getSelector(id, selectors, key) { key = key.replace(/_+$/, ''); if (selectors) { var selector = selectors[key]; if (selector) { id = '.blazy.' + id; selector = id + ' ' + selector; if ($.contains(selector, ',')) { selector = selector.replaceAll(',', ', ' + id); } } return selector; } return ''; } function toRgba(color, alpha) { if (!$.isUnd(alpha)) { if (Math.abs(alpha) === 0) { return TRANSPARENT; } else if (Math.abs(alpha) === 1) { return color === '#000000' || color === '#000' ? TRANSPARENT : color; } return 'rgba(' + parseInt(color.slice(-6, -4), 16) + ',' + parseInt(color.slice(-4, -2), 16) + ',' + parseInt(color.slice(-2), 16) + ',' + alpha + ')'; } return color; } /** * Processes a blazy layout modal form. * * @param {HTMLElement} elm * The container HTML element. */ function process(elm) { var colors = $.findAll(elm, 'input[type="color"]'); var ranges = $.findAll(elm, 'input[type="range"]'); var is = function (el, prefix) { return $.contains(el.name, prefix); }; var updateValue = function (el) { if (el.nextElementSibling) { el.nextElementSibling.textContent = el.value; } }; var makeRgba = function (el) { var cn = el.parentNode; var sibling; var input; var hex; if (el.type === 'range') { sibling = cn.previousElementSibling; input = $.find(sibling, 'input[type="color"]'); if (input) { hex = input.value; return { prop: input.dataset.bProp, value: toRgba(hex, el.value) }; } } else if (el.type === 'color') { sibling = cn.nextElementSibling; input = $.find(sibling, 'input[type="range"]'); if (input) { hex = el.value; return { prop: el.dataset.bProp, value: toRgba(hex, input.value) }; } } return {}; }; var updateStyle = function (id, el, region) { var styleId = id + '-style'; var elSheet = $.find(_doc, '#' + styleId); if (!elSheet) { return; } var sheet = elSheet.sheet; // var rules = sheet.cssRules || sheet.rules; var selectors; var selector; var prop = el.dataset.bProp; var value = el.value; var color = makeRgba(el); var rule; if (region.dataset && region.dataset.bSelector) { selectors = $.parse(region.dataset.bSelector); } if (is(el, PREFIX_BACKGROUND)) { selector = getSelector(id, selectors, PREFIX_BACKGROUND); } else if (is(el, PREFIX_OVERLAY)) { selector = getSelector(id, selectors, PREFIX_OVERLAY); } else if (is(el, PREFIX_TEXT)) { selector = getSelector(id, selectors, PREFIX_TEXT); } else if (is(el, PREFIX_HEADING)) { selector = getSelector(id, selectors, PREFIX_HEADING); } else if (is(el, PREFIX_LINK_HOVER)) { selector = getSelector(id, selectors, PREFIX_LINK_HOVER); } else if (is(el, PREFIX_LINK)) { selector = getSelector(id, selectors, PREFIX_LINK); } if (sheet && selector) { if (color.value) { prop = color.prop; value = color.value; } rule = prop + ':' + value; addRule(sheet, selector, rule); } }; var onChange = function () { var el = this; var region; var rid; var formRegion; var layout; var id; updateValue(el); setTimeout(function () { formRegion = $.closest(el, '[data-b-region]'); layout = $.find(_doc, S_ACTIVE_LAYOUT); if (!layout) { return; } id = layout.id; if (formRegion) { rid = formRegion.dataset.bRegion; region = $.find(layout, '[data-region="' + rid + '"]'); if (region) { updateStyle(id, el, region); } } }); }; var subprocess = function (elms) { $.each(elms, function (el) { updateValue(el); $.on(el, 'change.' + ID, onChange); }); }; subprocess(colors); subprocess(ranges); $.addClass(elm, C_MOUNTED); } /** * Attaches Blazy behavior to HTML element. * * @type {Drupal~behavior} */ Drupal.behaviors.blazyLayoutModal = { attach: function (context) { $.once(process, ID_ONCE, S_ELEMENT, context); }, detach: function (context, setting, trigger) { if (trigger === 'unload') { $.once.removeSafely(ID_ONCE, S_BASE, context); } } }; }(dBlazy, Drupal, this.document));