PageSourceSearch

https://www.eldebate.com/bundles/appcms/javascripts/app/ads-numbering.js?1782465702

js eldebate.com collected 2026-09-24 08:39:17 UTC 6,582 bytes, 151 lines download raw bytes

1/*
2 * ads-numbering.js
3 * ----------------
4 * Utility to assign sequential numeric IDs to ad slots inserted in the DOM.
5 *
6 * Purpose:
7 *  - Keep numbering logic outside of templates so it can be included via
8 *    configuration and reused across pages.
9 *  - Default target types: ['banner','roba','boton'] but extensible.
10 *
11 * Usage (recommended): include this file in your global assets and invoke
12 * window.assignAdNumbersFromConfig(...) after the page has created/inserted
13 * the ad slots (e.g. after web.html.twig has run or on DOMContentLoaded).
14 *
15 * The script is intentionally conservative:
16 *  - It detects existing numbered IDs like 'roba1' and avoids collisions.
17 *  - By default it scopes to a rootSelector (you can pass '.c-detail__body')
18 *    to avoid numbering sidebar ads.
19 *  - If you want a full renumbering ignoring existing numbers, pass
20 *    { bumpExisting: true }.
21 *
22 * Author: generated by automation for ED-1344 tasks
23 * Date: 2026-05-28
24 */
25
26(function (global) {
27    'use strict';
28
29    // Helper to escape a string for RegExp
30    function escapeRegExp(str) {
31        return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
32    }
33
34    /**
35     * Assign sequential numeric suffixes to ad slots in DOM.
36     *
37     * Behavior:
38     * - Targets elements that either have attribute attr_type="{type}" OR have id equal to "{type}".
39     * - Preserves/considers existing numbered IDs of the form `${type}<number>` to avoid collisions.
40     * - Processes elements in DOM order (visual order).
41     *
42     * @param {Array<string>} types Array of ad types to number, e.g. ['banner','roba','boton']
43     * @param {Object} opts Optional:
44     *    - rootSelector: CSS selector to scope the operation (default: document)
45     *    - idAttr: attribute used to hold type on created elements (default: 'attr_type')
46     *    - bumpExisting: if true, will renumber existing numbered elements as well (default: false)
47     *
48     * @returns {Object} counters map { banner: 2, roba: 3, ... }
49     */
50    function assignAdNumbersFromConfig(types, opts) {
51        types = Array.isArray(types) && types.length ? types : ['banner', 'roba', 'boton'];
52        opts = opts || {};
53        var root = (opts.rootSelector && document.querySelector(opts.rootSelector)) || document;
54        var typeAttr = opts.idAttr || 'attr_type';
55        var bumpExisting = !!opts.bumpExisting;
56
57        // Prepare counters and detect existing numbered ids
58        var counters = {};
59        var maxExisting = {};
60
61        types.forEach(function (t) {
62            counters[t] = 0;
63            maxExisting[t] = 0;
64        });
65
66        // 1) Scan for existing ids matching type + digits and set maxExisting
67        types.forEach(function (t) {
68            var nodes = document.querySelectorAll('[id^="' + t + '"]');
69            for (var i = 0; i < nodes.length; i++) {
70                var id = nodes[i].getAttribute('id');
71                if (!id) continue;
72                var m = id.match(new RegExp('^' + escapeRegExp(t) + '(\\d+)$'));
73                if (m && m[1]) {
74                    var n = parseInt(m[1], 10);
75                    if (!isNaN(n) && n > maxExisting[t]) maxExisting[t] = n;
76                }
77            }
78            counters[t] = maxExisting[t] || 0;
79        });
80
81        // 2) Build selector for attr_type / bare-id elements within rootSelector scope
82        var selectors = types.map(function (t) {
83            return '[' + typeAttr + '="' + t + '"], [id="' + t + '"]';
84        }).join(', ');
85
86        // querySelectorAll returns nodes in document order
87        var scopedNodes = root.querySelectorAll(selectors);
88
89        // 3) Also collect [data-revenuemaker-ads] elements in the FULL document that
90        //    match one of the types by id — these are static desktop slots (e.g. in
91        //    <aside class="free-html">) which may live outside rootSelector.
92        var rmSelectors = types.map(function (t) {
93            return '[data-revenuemaker-ads][id="' + t + '"]';
94        }).join(', ');
95        var globalRmNodes = document.querySelectorAll(rmSelectors);
96
97        // 4) Merge both lists preserving document order, deduplicating by reference.
98        var seen = [];
99        var adNodes = [];
100        function addNode(n) {
101            if (seen.indexOf(n) === -1) { seen.push(n); adNodes.push(n); }
102        }
103
104        // Walk the document in order: compare positions to merge correctly.
105        // Simple approach: collect all, sort by document position.
106        for (var s = 0; s < scopedNodes.length; s++) { addNode(scopedNodes[s]); }
107        for (var g = 0; g < globalRmNodes.length; g++) { addNode(globalRmNodes[g]); }
108
109        // Sort in document order using compareDocumentPosition
110        adNodes.sort(function (a, b) {
111            if (a === b) return 0;
112            var pos = a.compareDocumentPosition(b);
113            return (pos & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1;
114        });
115
116        // Numbering grouped by the order of `types` provided.
117        // Esto asegura que las numeraciones se ciñan exclusivamente a los tipos
118        // que se han pasado en la llamada (p.ej. ['roba','banner','boton']),
119        // procesando primero todos los elementos del primer tipo, luego del
120        // segundo, etc., independientemente de su posición en el DOM.
121        types.forEach(function (t) {
122            for (var k = 0; k < adNodes.length; k++) {
123                var node = adNodes[k];
124                // Determine node's logical type: prefer attr_type if present, else id
125                var ttype = node.getAttribute(typeAttr) || node.getAttribute('id');
126                if (!ttype || ttype !== t) continue;
127
128                // If node already has id like 'type123' and not bumpExisting: skip
129                var existingId = node.getAttribute('id') || '';
130                var numericMatch = existingId.match(new RegExp('^' + escapeRegExp(ttype) + '(\\d+)$'));
131                if (numericMatch && numericMatch[1] && !bumpExisting) {
132                    var exNum = parseInt(numericMatch[1], 10);
133                    if (!isNaN(exNum) && exNum > counters[ttype]) counters[ttype] = exNum;
134                    continue;
135                }
136
137                // Assign next number for this type
138                counters[ttype] = (counters[ttype] || 0) + 1;
139                var newId = ttype + counters[ttype];
140                node.setAttribute('id', newId);
141            }
142        });
143
144        return counters;
145    }
146
147    // Expose to global for configuration to call
148    global.assignAdNumbersFromConfig = assignAdNumbersFromConfig;
149
150})(window);
151

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.