Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate copy/paste JavaScript #2814

Open
HitmanInWis opened this issue Jul 11, 2024 · 0 comments
Open

Consolidate copy/paste JavaScript #2814

HitmanInWis opened this issue Jul 11, 2024 · 0 comments

Comments

@HitmanInWis
Copy link

There's a ton of duplicated javascript that can be consolidated - see below for all functions that could be created in a centralized util to replace multiple (3-5 instances of each).

Logic for checking if data layer is enabled and getting a reference to it

        var dataLayerEnabled;
        var dataLayer;

        var isDataLayerEnabled = function() {
            if (dataLayerEnabled == null) {
                dataLayerEnabled = document.body.hasAttribute('data-cmp-data-layer-enabled');
            }
            return dataLayerEnabled;
        }

        var getDataLayer = function() {
            if (isDataLayerEnabled() && dataLayer == null) {
                var dataLayerName = document.body.getAttribute('data-cmp-data-layer-name') || 'adobeDataLayer';
                dataLayer = window[dataLayerName] = window[dataLayerName] || [];
            }
            return dataLayer;
        }

Logic for constructing component JS objects

        var constructComponents = function (selector, is, clazz) {
            var elements = document.querySelectorAll(selector);
            for (var i = 0; i < elements.length; i++) {
                new clazz({ element: elements[i], options: readData(elements[i], is) });
            }

            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
            var body = document.querySelector('body');
            var observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    // needed for IE
                    var nodesArray = [].slice.call(mutation.addedNodes);
                    if (nodesArray.length > 0) {
                        nodesArray.forEach(function (addedNode) {
                            if (addedNode.querySelectorAll) {
                                var elementsArray = [].slice.call(addedNode.querySelectorAll(selector));
                                elementsArray.forEach(function (element) {
                                    new clazz({ element: element, options: readData(element, is) });
                                });
                            }
                        });
                    }
                });
            });

            observer.observe(body, {
                subtree: true,
                childList: true,
                characterData: true,
            });
        };

        var readData = function (element, is) {
            var data = element.dataset;
            var options = [];
            var capitalized = is;
            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
            var reserved = ['is', 'hook' + capitalized];

            for (var key in data) {
                if (Object.prototype.hasOwnProperty.call(data, key)) {
                    var value = data[key];

                    if (key.indexOf(NS) === 0) {
                        key = key.slice(NS.length);
                        key = key.charAt(0).toLowerCase() + key.substring(1);

                        if (reserved.indexOf(key) === -1) {
                            options[key] = value;
                        }
                    }
                }
            }
            return options;
        };

        var setupProperties = function (options, properties) {
            var transformedProperties = {};

            for (var key in properties) {
                if (Object.prototype.hasOwnProperty.call(properties, key)) {
                    var property = properties[key];
                    var value = null;

                    if (options && options[key] != null) {
                        if (property && typeof property.transform === 'function') {
                            value = property.transform(options[key]);
                        } else {
                            value = options[key];
                        }
                    }

                    if (value === null) {
                        // value still null, take the property default
                        value = properties[key]['default'];
                    }

                    transformedProperties[key] = value;
                }
            }
            return transformedProperties;
        };

Logic for grabbing a components hookable children elements

        var getCacheElements = function(wrapper, is, is_dash = is) {
            var elements = {};
            elements.self = wrapper;
            var hooks = elements.self.querySelectorAll('[data-' + NS + '-hook-' + is_dash + ']');

            for (var i = 0; i < hooks.length; i++) {
                var hook = hooks[i];
                if (hook.closest('.' + NS + '-' + is_dash) === elements.self) {
                    // only process own elements
                    var capitalized = is;
                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
                    var key = hook.dataset[NS + 'Hook' + capitalized];
                    if (elements[key]) {
                        if (!Array.isArray(elements[key])) {
                            var tmp = elements[key];
                            elements[key] = [tmp];
                        }
                        elements[key].push(hook);
                    } else {
                        elements[key] = hook;
                    }
                }
            }
            return elements;
        };

Logic for getting a component's datalayer ID

        var getDataLayerId = function(item) {
            if (item) {
                if (item.dataset.cmpDataLayer) {
                    return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
                } else {
                    return item.id;
                }
            }
            return null;
        };

Logic for panel containers (Accordion, Carousel, Tabs) listening for panel selection events from author

        var subscribeToAuthorPanelSelect = function(panelContainer, type, navigate) {
            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
                /*
                 * Editor message handling:
                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
                 * - check that the message data panel container type is correct and that the id (path) matches this specific component
                 * - if so, route the "navigate" operation to enact a navigation of the component based on index data
                 */
                window.CQ = window.CQ || {};
                window.CQ.CoreComponents = window.CQ.CoreComponents || {};
                window.CQ.CoreComponents.MESSAGE_CHANNEL =
                    window.CQ.CoreComponents.MESSAGE_CHANNEL ||
                    new window.Granite.author.MessageChannel('cqauthor', window);
                window.CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage(
                    'cmp.panelcontainer',
                    function (message) {
                        if (
                            message.data &&
                            message.data.type === type &&
                            message.data.id === panelContainer.dataset['cmpPanelcontainerId']
                        ) {
                            if (message.data.operation === 'navigate') {
                                navigate(message.data.index);
                            }
                        }
                    },
                );
            }
        };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant