PageSourceSearch

https://diariodecuba.net/modules/export-lists/global.js?1738290170

js diariodecuba.net collected 2026-10-03 22:35:47 UTC 11,720 bytes, 387 lines download raw bytes

1// Copyright 1999-2023. Parallels IP Holdings GmbH. All Rights Reserved.
2// ExportList global.js
3
4(() => {
5class ModuleExportLists {
6    constructor() {
7        this.eventList = [];
8    }
9
10    on(event, callback) {
11        if (!this.eventList[event]) {
12            this.eventList[event] = [];
13        }
14
15        this.eventList[event].push(callback);
16        return this;
17    }
18
19    emit(event) {
20        if (!this.eventList[event]) return;
21
22        this.eventList[event].forEach(cb => cb.call(null))
23    }
24}
25
26const elementObserver = selector => {
27    const event = new ModuleExportLists();
28
29    let elementExistBefore = false;
30
31    const observer = new MutationObserver(() => {
32        const el = document.querySelector(selector)
33
34        if (!elementExistBefore && el) {
35            elementExistBefore = true;
36            event.emit('added');
37        } else if (elementExistBefore && !el) {
38            elementExistBefore = false;
39            event.emit('removed');
40        }
41    });
42
43    const container = document.documentElement || document.body;
44    observer.observe(container, {
45        childList: true,
46        subtree: true,
47    });
48
49    return event;
50}
51
52const addListToCsvButton = () => {
53
54    var extName = 'ExportLists';
55
56    Jsw.namespace('PleskExt.' + extName);
57    let ext = PleskExt[extName];
58
59
60    function escapeRegExp(str) {
61        return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
62    }
63
64    function replaceAll(str, find, replace) {
65        return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
66    }
67
68    function lmsg(message, data) {
69        var locale = ext.Config.locale || {};
70        message = locale[message] || message || '';
71        data = data || {};
72        for (var key in data) {
73            if (data.hasOwnProperty(key)) {
74                message = replaceAll(message, '%%' + key + '%%', data[key]);
75            }
76        }
77
78        return message;
79    }
80
81    function displayWarning(message) {
82        Jsw.addStatusMessage('warning', message, {
83            title: lmsg('exportToCsv'),
84            closable: true,
85            onClose: function () {
86                this.up('.msg-box').remove();
87            }
88        });
89    }
90
91    function addCvsExportButton(parentElement) {
92        new Jsw.SmallButton({
93            renderTo: parentElement,
94            renderMode: 'top',
95            cls: 's-btn sb-csv-export btn-icon-only',
96            title: lmsg('exportToCsv'),
97            description: lmsg('exportToCsvDescription'),
98            href: ext.Config.link,
99            handler: exportListToCsv
100        });
101    }
102
103    var listElementSelector = 'div:has(> div > div.list), div.pul-list';
104
105    ext.init = function() {
106        function addCsvExportButtons(list) {
107            list._componentElement.select('div.paging .paging-view').forEach(addCvsExportButton);
108        }
109
110        var listElements = $$(listElementSelector);
111        listElements.forEach(function (listElement) {
112            var listComponent = Jsw.getComponent(listElement.id);
113            if (listComponent) {
114                addCsvExportButtons(listComponent);
115
116                var oldRedrawHandler = listComponent._onRedraw;
117                listComponent._onRedraw = function () {
118                    if (oldRedrawHandler) {
119                        oldRedrawHandler.apply(this,  Array.prototype.slice.call(arguments));
120                    }
121                    addCsvExportButtons(listComponent);
122                }
123            } else {
124                addJswButtonToPleskUiList(listElement);
125            }
126        });
127    };
128
129    function addJswButtonToPleskUiList(listElement) {
130        const exportListContainer = 'export-lists-container';
131
132        function createButtonContainer(targetElement) {
133            const buttonContainer = document.createElement('span');
134            buttonContainer.classList.add(exportListContainer);
135            buttonContainer.style.marginRight = '10px';
136            targetElement.prepend(buttonContainer);
137
138            return buttonContainer;
139        }
140
141        const targetElement = listElement.querySelector('div.pul-list div.pul-list__header > span');
142
143        if (!targetElement) {
144            return;
145        }
146        addCvsExportButton(createButtonContainer(targetElement));
147
148        const observer = new MutationObserver(() => {
149            if (targetElement && !targetElement.querySelector('span.' + exp
149ortListContainer)) {
150                addCvsExportButton(createButtonContainer(targetElement));
151            }
152        });
153
154        observer.observe(document.body, { childList: true, subtree: true });
155    }
156
157    function getUpDownElement(element, upSelector, downSelector) {
158        var sucessorElement;
159
160        var ancestorElement = element.up(upSelector);
161        if (ancestorElement) {
162            sucessorElement = ancestorElement.down(downSelector);
163        }
164
165        return sucessorElement;
166    }
167
168    function getElementText(element) {
169        var rejectedElementClasses = [
170            'r-visible',
171            'hint',
172            'hint-info',
173            'tooltipData'
174        ];
175        var rejectedElementNames = [
176            'svg'
177        ];
178        var treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, {
179            acceptNode: function (node) {
180                let result;
181
182                if (rejectedElementNames.includes(node.nodeName.toLowerCase())) {
183                    return NodeFilter.FILTER_REJECT;
184                }
185
186                switch(node.nodeType){
187                    case Node.ELEMENT_NODE:
188                        result = rejectedElementClasses.some(node.hasClassName.bind(node)) ?
189                            NodeFilter.FILTER_REJECT :
190                            NodeFilter.FILTER_ACCEPT;
191                        break;
192
193                    case Node.TEXT_NODE:
194                        result = NodeFilter.FILTER_ACCEPT;
195                        break;
196
197                    default:
198                        result = NodeFilter.FILTER_REJECT;
199                }
200
201                return result;
202            }
203        }, false);
204
205        var textData = [];
206        while(treeWalker.nextNode()) {
207            var node = treeWalker.currentNode;
208
209            switch(node.nodeType){
210                case Node.ELEMENT_NODE:
211                    switch (node.nodeName.toLowerCase()) {
212                        case 'br':
213                            textData.push('\n');
214                            break;
215
216                        case 'img':
217                            var text =
218                                (node.readAttribute('alt') || '').trim() ||
219                                (node.readAttribute('title') || '').trim();
220                            if (text) {
221                                textData.push(text);
222                            }
223                            break;
224
225                        default:
226                            break;
227                    }
228                    break;
229
230                case Node.TEXT_NODE:
231                    textData.push(node.nodeValue);
232                    break;
233
234                default:
235                    break;
236            }
237        }
238
239        return textData.join('')
240            .replace(/\u00A0/g, ' ') // non-breaking space
241            .replace(/[\u200B\u00AD]/g, '') // zero-width space, soft hyphen
242        ;
243    }
244
245    function getRowData(tableDataElement, selector) {
246        var result = [];
247        while (tableDataElement) {
248            result.push(getElementText(tableDataElement));
249            tableDataElement = tableDataElement.next(selector);
250        }
251
252        return result;
253    }
254
255    function getTableHeaders(tableElement) {
256        return getRowData(tableElement.down('thead > tr > th'), 'th');
257    }
258
259    function getTableData(tableElement, selected) {
260        var result = [];
261        var rowsFilter  = selected ? 'tbody > tr.selected, tbody > tr.is-selected' : 'tbody > tr';
262        var rowFilter = selected ? 'tr.selected, tr.is-selected' : 'tr';
263        var trElement = tableElement.down(rowsFilter);
264        while (trElement) {
265            result.push(getRowData(trElement.down('td'), 'td'));
266            trElement = trElement.next(rowFilter);
267        }
268
269        return result;
270    }
271
272    function indexFilter(data, index) {
273        return this[index];
274    }
275
276    function getHeadingName() {
277        var headings = $$('#page .heading-area h2');
278
279        return (headings.length > 0) ? getElementText(headings[0]).trim() : null;
280    }
281
282    function getActiveTabNames(element) {
283        var tabNames = [];
284
285        var prevTabElement = null;
286        var tabedElement;
287        while (tabedElement = (element.up('div.tabed') || element.up('div.b-content')) ) {
288            var activeTabElement = tabedElement.down('div.tabs-area ul > li.active');
289            if (activeTabElement && activeTabElement !== prevTabElement) {
290                tabNames.push(getElementText(activeTabElement).trim());
291                prevTabElement = activeTabElement;
292            }
293            element = tabedElement;
294        }
295
296        return tabNames.reverse();
297    }
298
299    function exportListToCsv(event) {
300        event.stop();
301
302        var tableElement = getUpDownElement(this, listElementSelector, 'div.list > table, table.pul-list__table');
303        if (!tableElement) {
304            displayWarning(lmsg('unableToFetchData'));
305
306            return;
307        }
308
309        var headers = getTableHeaders(tableElement);
310
311        var headersIndexFilter = headers.map(function (header) {
312            return header.length > 0;
313        });
314
315        var headersFiltered = headers.filter(indexFilter, headersIndexFilter);
316        if (headersFiltered.length === 0) {
317            displayWarning(lmsg('noContent'));
318
319            return;
320        }
321
322        var rows = getTableData(tableElement, true);
323        if (rows.length === 0) {
324            rows = getTableData(tableElement);
325        }
326        if (rows.length === 0) {
327            displayWarning(lmsg('noContent'));
328
329            return;
330        }
331
332        var rowsFiltered = rows.map(function (row) {
333            return row.filter(indexFilter, headersIndexFilter);
334        });
335
336        var tabNames = getActiveTabNames(this);
337        tabNames.unshift(getHeadingName());
338
339        var postData = {
340            exportHeaders: JSON.stringify(headersFiltered),
341            exportData: JSON.stringify(rowsFiltered),
342            exportDataTitles: tabNames
343        };
344
345        Jsw.redirectPost(this.href, postData);
346    }
347};
348
349addListToCsvButton();
350[
351    '.domain-list table.pul-list__table',
352    '#subscriptions-list-table',
353    '#customer-service-plan-list-table',
354    '#customers-list-table',
355    '#resellers-list-table',
356    '#backup-list-table',
357    '#statistics-list',
358    '#email-addresses-list-table table.pul-list__table',
359    '#mail-settings-list-table',
360    '#database-list-table',
361    '#database-users-list-table',
362    '#admin-alias-list-table',
363    '#active-plesk-sessions-list-table',
364    '#admin-control-panel-access-list-table',
365    '#restricted-domains-list-table',
366    '#configurations-list-table',
367    'div[data-type="ip-address-list"] table.pul-list__table',
368    '#scheduler-tasks-table',
369    '#admin-event-handlers-list-table',
370    '#ssl-certificate-list-table',
371    '#dns-template-acl-records-table',
372    '#php-handler-list-table',
373    '#performance-booster table.pul-list__table',
374    '#webmails-list-table',
375    '#admin-app-usage-list-table',
376    '#admin-app-uploaded-list-table',
377    '#languages-list-table',
378    '#custom-buttons-list-table',
379    '#users-list-table',
380    '#roles-list-table',
381    '#modules-exportlists-list-demo-table'
382].forEach(selector => {
383    elementObserver(selector)
384        .on('added', PleskExt.ExportLists.init);
385});
386
387})();

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.