@customviews-js/customviews 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/custom-views.core.cjs.js +173 -172
- package/dist/custom-views.core.cjs.js.map +1 -1
- package/dist/custom-views.core.esm.js +173 -172
- package/dist/custom-views.core.esm.js.map +1 -1
- package/dist/custom-views.esm.js +173 -172
- package/dist/custom-views.esm.js.map +1 -1
- package/dist/custom-views.js +173 -172
- package/dist/custom-views.js.map +1 -1
- package/dist/custom-views.min.js +2 -2
- package/dist/custom-views.min.js.map +1 -1
- package/dist/types/core/custom-elements.d.ts.map +1 -1
- package/dist/types/core/render.d.ts +0 -3
- package/dist/types/core/render.d.ts.map +1 -1
- package/dist/types/core/tab-manager.d.ts +8 -0
- package/dist/types/core/tab-manager.d.ts.map +1 -1
- package/dist/types/core/widget.d.ts.map +1 -1
- package/dist/types/entry/browser-entry.d.ts.map +1 -1
- package/dist/types/styles/tab-styles.d.ts +1 -1
- package/dist/types/styles/tab-styles.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @customviews-js/customviews v1.1.
|
|
2
|
+
* @customviews-js/customviews v1.1.7
|
|
3
3
|
* (c) 2025 Chan Ger Teck
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -267,102 +267,6 @@ class VisibilityManager {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
/** --- Icon utilities --- */
|
|
271
|
-
function ensureFontAwesomeInjected() {
|
|
272
|
-
const isFontAwesomeLoaded = Array.from(document.styleSheets).some(sheet => sheet.href && (sheet.href.includes('font-awesome') || sheet.href.includes('fontawesome')));
|
|
273
|
-
if (isFontAwesomeLoaded)
|
|
274
|
-
return;
|
|
275
|
-
const link = document.createElement('link');
|
|
276
|
-
link.rel = 'stylesheet';
|
|
277
|
-
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css';
|
|
278
|
-
link.setAttribute('data-customviews-fontawesome', 'true');
|
|
279
|
-
document.head.appendChild(link);
|
|
280
|
-
}
|
|
281
|
-
function replaceIconShortcodes(text) {
|
|
282
|
-
// Matches :fa-*, :fas-*, :fab-* etc.
|
|
283
|
-
return text.replace(/:(fa[b|s|r]?)-([\w-]+):/g, (_, style, icon) => {
|
|
284
|
-
// style = fa, fas, fab, far, etc.
|
|
285
|
-
// Default to "fa" if only "fa-" is given
|
|
286
|
-
return `<i class="${style} fa-${icon}"></i>`;
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
/** --- Basic renderers --- */
|
|
290
|
-
function renderImage(el, asset) {
|
|
291
|
-
if (!asset.src)
|
|
292
|
-
return;
|
|
293
|
-
el.innerHTML = '';
|
|
294
|
-
const img = document.createElement('img');
|
|
295
|
-
img.src = asset.src;
|
|
296
|
-
img.alt = asset.alt || '';
|
|
297
|
-
// Apply custom styling if provided
|
|
298
|
-
if (asset.className) {
|
|
299
|
-
img.className = asset.className;
|
|
300
|
-
}
|
|
301
|
-
if (asset.style) {
|
|
302
|
-
img.setAttribute('style', asset.style);
|
|
303
|
-
}
|
|
304
|
-
// Default styles (can be overridden by asset.style)
|
|
305
|
-
img.style.maxWidth = img.style.maxWidth || '100%';
|
|
306
|
-
img.style.height = img.style.height || 'auto';
|
|
307
|
-
img.style.display = img.style.display || 'block';
|
|
308
|
-
el.appendChild(img);
|
|
309
|
-
}
|
|
310
|
-
function renderText(el, asset) {
|
|
311
|
-
if (asset.content != null) {
|
|
312
|
-
el.textContent = asset.content;
|
|
313
|
-
}
|
|
314
|
-
// Apply custom styling if provided
|
|
315
|
-
if (asset.className) {
|
|
316
|
-
el.className = asset.className;
|
|
317
|
-
}
|
|
318
|
-
if (asset.style) {
|
|
319
|
-
el.setAttribute('style', asset.style);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
function renderHtml(el, asset) {
|
|
323
|
-
if (asset.content != null) {
|
|
324
|
-
el.innerHTML = asset.content;
|
|
325
|
-
}
|
|
326
|
-
// Apply custom styling if provided
|
|
327
|
-
if (asset.className) {
|
|
328
|
-
el.className = asset.className;
|
|
329
|
-
}
|
|
330
|
-
if (asset.style) {
|
|
331
|
-
el.setAttribute('style', asset.style);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
/** --- Unified asset renderer --- */
|
|
335
|
-
function detectAssetType(asset) {
|
|
336
|
-
// If src exists, it's an image
|
|
337
|
-
if (asset.src)
|
|
338
|
-
return 'image';
|
|
339
|
-
// If content contains HTML tags, it's HTML
|
|
340
|
-
if (asset.content && /<[^>]+>/.test(asset.content)) {
|
|
341
|
-
return 'html';
|
|
342
|
-
}
|
|
343
|
-
return 'text';
|
|
344
|
-
}
|
|
345
|
-
function renderAssetInto(el, assetId, assetsManager) {
|
|
346
|
-
const asset = assetsManager.get(assetId);
|
|
347
|
-
if (!asset)
|
|
348
|
-
return;
|
|
349
|
-
const type = asset.type || detectAssetType(asset);
|
|
350
|
-
switch (type) {
|
|
351
|
-
case 'image':
|
|
352
|
-
renderImage(el, asset);
|
|
353
|
-
break;
|
|
354
|
-
case 'text':
|
|
355
|
-
renderText(el, asset);
|
|
356
|
-
break;
|
|
357
|
-
case 'html':
|
|
358
|
-
renderHtml(el, asset);
|
|
359
|
-
break;
|
|
360
|
-
default:
|
|
361
|
-
el.innerHTML = asset.content || String(asset);
|
|
362
|
-
console.warn('[CustomViews] Unknown asset type:', type);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
270
|
// Constants for selectors
|
|
367
271
|
const TABGROUP_SELECTOR = 'cv-tabgroup';
|
|
368
272
|
const TAB_SELECTOR = 'cv-tab';
|
|
@@ -449,37 +353,35 @@ class TabManager {
|
|
|
449
353
|
tabEl.classList.remove('cv-visible');
|
|
450
354
|
}
|
|
451
355
|
}
|
|
356
|
+
/**
|
|
357
|
+
* Extract header and body content from header component syntax: <cv-tab-header> and <cv-tab-body>
|
|
358
|
+
* Returns null if using old attribute-based syntax.
|
|
359
|
+
*
|
|
360
|
+
* @param tabEl The <cv-tab> element to inspect
|
|
361
|
+
* @returns Object with extracted content, or null if new syntax not used
|
|
362
|
+
*/
|
|
363
|
+
static extractTabContent(tabEl) {
|
|
364
|
+
// Look for direct children
|
|
365
|
+
let headerEl = tabEl.querySelector(':scope > cv-tab-header');
|
|
366
|
+
if (!headerEl) {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
const headerHTML = headerEl.innerHTML.trim();
|
|
370
|
+
// Find body element
|
|
371
|
+
let bodyEl = tabEl.querySelector(':scope > cv-tab-body');
|
|
372
|
+
// Fallback: try finding both header and body
|
|
373
|
+
// without :scope (in case of DOM manipulation) by iterating through tabEl.children if needed
|
|
374
|
+
return {
|
|
375
|
+
headerHTML,
|
|
376
|
+
bodyEl
|
|
377
|
+
};
|
|
378
|
+
}
|
|
452
379
|
/**
|
|
453
380
|
* Build navigation for tab groups with nav="auto" (one-time setup)
|
|
454
381
|
*/
|
|
455
382
|
static buildNavs(rootEl, cfgGroups, onTabClick, onTabDoubleClick) {
|
|
456
383
|
// Find all cv-tabgroup elements with nav="auto" or no nav attribute
|
|
457
384
|
const tabGroups = rootEl.querySelectorAll(NAV_AUTO_SELECTOR);
|
|
458
|
-
// Check if any tab headers contain Font Awesome shortcodes
|
|
459
|
-
// Inject Font Awesome CSS only if needed
|
|
460
|
-
let hasFontAwesomeShortcodes = false;
|
|
461
|
-
tabGroups.forEach((groupEl) => {
|
|
462
|
-
const groupId = groupEl.getAttribute('id');
|
|
463
|
-
if (!groupId)
|
|
464
|
-
return;
|
|
465
|
-
const tabElements = Array.from(groupEl.children).filter((child) => child.tagName.toLowerCase() === 'cv-tab');
|
|
466
|
-
// Check for Font Awesome shortcodes in tab headers
|
|
467
|
-
tabElements.forEach((tabEl) => {
|
|
468
|
-
const rawTabId = tabEl.getAttribute('id');
|
|
469
|
-
if (!rawTabId)
|
|
470
|
-
return;
|
|
471
|
-
const splitIds = this.splitTabIds(rawTabId);
|
|
472
|
-
const tabId = splitIds[0] || rawTabId;
|
|
473
|
-
const header = tabEl.getAttribute('header') || this.getTabLabel(tabId, groupId, cfgGroups) || tabId || '';
|
|
474
|
-
if (/:fa-[\w-]+:/.test(header)) {
|
|
475
|
-
hasFontAwesomeShortcodes = true;
|
|
476
|
-
}
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
// Inject Font Awesome only if shortcodes are found
|
|
480
|
-
if (hasFontAwesomeShortcodes) {
|
|
481
|
-
ensureFontAwesomeInjected();
|
|
482
|
-
}
|
|
483
385
|
tabGroups.forEach((groupEl) => {
|
|
484
386
|
const groupId = groupEl.getAttribute('id');
|
|
485
387
|
if (!groupId)
|
|
@@ -514,23 +416,30 @@ class TabManager {
|
|
|
514
416
|
const splitIds = this.splitTabIds(rawTabId);
|
|
515
417
|
// If multiple IDs, use the first as primary
|
|
516
418
|
const tabId = splitIds[0] || rawTabId;
|
|
517
|
-
// Get header for this tab
|
|
518
|
-
const
|
|
419
|
+
// Get header for this tab - prefer new syntax over old attribute syntax
|
|
420
|
+
const extractedHeaderAndBody = this.extractTabContent(tabEl);
|
|
519
421
|
let header = '';
|
|
520
|
-
if
|
|
521
|
-
|
|
522
|
-
header =
|
|
422
|
+
// use <cv-tab-header> content if available
|
|
423
|
+
if (extractedHeaderAndBody && extractedHeaderAndBody.headerHTML) {
|
|
424
|
+
header = extractedHeaderAndBody.headerHTML;
|
|
523
425
|
}
|
|
524
426
|
else {
|
|
525
|
-
//
|
|
526
|
-
|
|
427
|
+
// use header attribute if available
|
|
428
|
+
const headerAttr = tabEl.getAttribute('header') || '';
|
|
429
|
+
if (headerAttr) {
|
|
430
|
+
header = headerAttr;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
// Use config label or id as fallback
|
|
434
|
+
header = this.getTabLabel(tabId, groupId, cfgGroups) || tabId || '';
|
|
435
|
+
}
|
|
527
436
|
}
|
|
528
437
|
// Create a single nav link for this tab element
|
|
529
438
|
const listItem = document.createElement('li');
|
|
530
439
|
listItem.className = 'nav-item';
|
|
531
440
|
const navLink = document.createElement('a');
|
|
532
441
|
navLink.className = 'nav-link';
|
|
533
|
-
navLink.innerHTML =
|
|
442
|
+
navLink.innerHTML = header;
|
|
534
443
|
navLink.href = '#';
|
|
535
444
|
navLink.setAttribute('data-tab-id', tabId);
|
|
536
445
|
navLink.setAttribute('data-raw-tab-id', rawTabId);
|
|
@@ -767,6 +676,83 @@ class AssetsManager {
|
|
|
767
676
|
}
|
|
768
677
|
}
|
|
769
678
|
|
|
679
|
+
/** --- Basic renderers --- */
|
|
680
|
+
function renderImage(el, asset) {
|
|
681
|
+
if (!asset.src)
|
|
682
|
+
return;
|
|
683
|
+
el.innerHTML = '';
|
|
684
|
+
const img = document.createElement('img');
|
|
685
|
+
img.src = asset.src;
|
|
686
|
+
img.alt = asset.alt || '';
|
|
687
|
+
// Apply custom styling if provided
|
|
688
|
+
if (asset.className) {
|
|
689
|
+
img.className = asset.className;
|
|
690
|
+
}
|
|
691
|
+
if (asset.style) {
|
|
692
|
+
img.setAttribute('style', asset.style);
|
|
693
|
+
}
|
|
694
|
+
// Default styles (can be overridden by asset.style)
|
|
695
|
+
img.style.maxWidth = img.style.maxWidth || '100%';
|
|
696
|
+
img.style.height = img.style.height || 'auto';
|
|
697
|
+
img.style.display = img.style.display || 'block';
|
|
698
|
+
el.appendChild(img);
|
|
699
|
+
}
|
|
700
|
+
function renderText(el, asset) {
|
|
701
|
+
if (asset.content != null) {
|
|
702
|
+
el.textContent = asset.content;
|
|
703
|
+
}
|
|
704
|
+
// Apply custom styling if provided
|
|
705
|
+
if (asset.className) {
|
|
706
|
+
el.className = asset.className;
|
|
707
|
+
}
|
|
708
|
+
if (asset.style) {
|
|
709
|
+
el.setAttribute('style', asset.style);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function renderHtml(el, asset) {
|
|
713
|
+
if (asset.content != null) {
|
|
714
|
+
el.innerHTML = asset.content;
|
|
715
|
+
}
|
|
716
|
+
// Apply custom styling if provided
|
|
717
|
+
if (asset.className) {
|
|
718
|
+
el.className = asset.className;
|
|
719
|
+
}
|
|
720
|
+
if (asset.style) {
|
|
721
|
+
el.setAttribute('style', asset.style);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/** --- Unified asset renderer --- */
|
|
725
|
+
function detectAssetType(asset) {
|
|
726
|
+
// If src exists, it's an image
|
|
727
|
+
if (asset.src)
|
|
728
|
+
return 'image';
|
|
729
|
+
// If content contains HTML tags, it's HTML
|
|
730
|
+
if (asset.content && /<[^>]+>/.test(asset.content)) {
|
|
731
|
+
return 'html';
|
|
732
|
+
}
|
|
733
|
+
return 'text';
|
|
734
|
+
}
|
|
735
|
+
function renderAssetInto(el, assetId, assetsManager) {
|
|
736
|
+
const asset = assetsManager.get(assetId);
|
|
737
|
+
if (!asset)
|
|
738
|
+
return;
|
|
739
|
+
const type = asset.type || detectAssetType(asset);
|
|
740
|
+
switch (type) {
|
|
741
|
+
case 'image':
|
|
742
|
+
renderImage(el, asset);
|
|
743
|
+
break;
|
|
744
|
+
case 'text':
|
|
745
|
+
renderText(el, asset);
|
|
746
|
+
break;
|
|
747
|
+
case 'html':
|
|
748
|
+
renderHtml(el, asset);
|
|
749
|
+
break;
|
|
750
|
+
default:
|
|
751
|
+
el.innerHTML = asset.content || String(asset);
|
|
752
|
+
console.warn('[CustomViews] Unknown asset type:', type);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
770
756
|
// Constants for selectors
|
|
771
757
|
const TOGGLE_DATA_SELECTOR = "[data-cv-toggle], [data-customviews-toggle]";
|
|
772
758
|
const TOGGLE_ELEMENT_SELECTOR = "cv-toggle";
|
|
@@ -878,16 +864,21 @@ const TAB_STYLES = `
|
|
|
878
864
|
margin-bottom: 1rem;
|
|
879
865
|
list-style: none;
|
|
880
866
|
border-bottom: 1px solid #dee2e6;
|
|
867
|
+
|
|
868
|
+
align-items: stretch;
|
|
881
869
|
}
|
|
882
870
|
|
|
883
871
|
.cv-tabs-nav .nav-item {
|
|
884
872
|
margin-bottom: -1px;
|
|
885
873
|
list-style: none;
|
|
886
|
-
display: inline-block
|
|
874
|
+
display: flex; /* was inline-block → make flex to stretch height */
|
|
875
|
+
align-items: stretch; /* stretch link to full height */
|
|
887
876
|
}
|
|
888
877
|
|
|
889
878
|
.cv-tabs-nav .nav-link {
|
|
890
|
-
display:
|
|
879
|
+
display: flex;
|
|
880
|
+
align-items: center;
|
|
881
|
+
justify-content: center;
|
|
891
882
|
padding: 0.5rem 1rem;
|
|
892
883
|
color: #495057;
|
|
893
884
|
text-decoration: none;
|
|
@@ -897,6 +888,13 @@ const TAB_STYLES = `
|
|
|
897
888
|
border-top-right-radius: 0.25rem;
|
|
898
889
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
|
|
899
890
|
cursor: pointer;
|
|
891
|
+
min-height: 2.5rem;
|
|
892
|
+
box-sizing: border-box;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.cv-tabs-nav .nav-link p {
|
|
896
|
+
margin: 0; /* remove default margins */
|
|
897
|
+
display: inline; /* or inline-block */
|
|
900
898
|
}
|
|
901
899
|
|
|
902
900
|
.cv-tabs-nav .nav-link:hover,
|
|
@@ -949,6 +947,16 @@ cv-tab {
|
|
|
949
947
|
display: block;
|
|
950
948
|
}
|
|
951
949
|
|
|
950
|
+
/* Hide cv-tab-header source element; content is extracted to nav link */
|
|
951
|
+
cv-tab-header {
|
|
952
|
+
display: none !important;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/* Allow cv-tab-body to flow naturally */
|
|
956
|
+
cv-tab-body {
|
|
957
|
+
display: block;
|
|
958
|
+
}
|
|
959
|
+
|
|
952
960
|
/* Override visibility for tab panels - use display instead of collapse animation */
|
|
953
961
|
cv-tab.cv-hidden {
|
|
954
962
|
display: none !important;
|
|
@@ -1311,6 +1319,24 @@ class CVToggle extends HTMLElement {
|
|
|
1311
1319
|
// Element is managed by Core
|
|
1312
1320
|
}
|
|
1313
1321
|
}
|
|
1322
|
+
/**
|
|
1323
|
+
* <cv-tab-header> element - represents tab header with rich HTML formatting
|
|
1324
|
+
* Content is extracted and used in the navigation link
|
|
1325
|
+
*/
|
|
1326
|
+
class CVTabHeader extends HTMLElement {
|
|
1327
|
+
connectedCallback() {
|
|
1328
|
+
// Element is a semantic container; TabManager extracts its content
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
/**
|
|
1332
|
+
* <cv-tab-body> element - represents tab body content
|
|
1333
|
+
* Semantic container for tab panel content
|
|
1334
|
+
*/
|
|
1335
|
+
class CVTabBody extends HTMLElement {
|
|
1336
|
+
connectedCallback() {
|
|
1337
|
+
// Element is a semantic container; visibility managed by TabManager
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1314
1340
|
/**
|
|
1315
1341
|
* Register custom elements
|
|
1316
1342
|
*/
|
|
@@ -1325,6 +1351,12 @@ function registerCustomElements() {
|
|
|
1325
1351
|
if (!customElements.get('cv-toggle')) {
|
|
1326
1352
|
customElements.define('cv-toggle', CVToggle);
|
|
1327
1353
|
}
|
|
1354
|
+
if (!customElements.get('cv-tab-header')) {
|
|
1355
|
+
customElements.define('cv-tab-header', CVTabHeader);
|
|
1356
|
+
}
|
|
1357
|
+
if (!customElements.get('cv-tab-body')) {
|
|
1358
|
+
customElements.define('cv-tab-body', CVTabBody);
|
|
1359
|
+
}
|
|
1328
1360
|
}
|
|
1329
1361
|
|
|
1330
1362
|
/**
|
|
@@ -2545,28 +2577,6 @@ class CustomViewsWidget {
|
|
|
2545
2577
|
// Get tab groups
|
|
2546
2578
|
const tabGroups = this.core.getTabGroups();
|
|
2547
2579
|
let tabGroupControlsHTML = '';
|
|
2548
|
-
// Check if any tab group or tab labels contain Font Awesome shortcodes
|
|
2549
|
-
let hasFontAwesomeShortcodes = false;
|
|
2550
|
-
if (this.options.showTabGroups && tabGroups && tabGroups.length > 0) {
|
|
2551
|
-
for (const group of tabGroups) {
|
|
2552
|
-
if (group.label && /:fa-[\w-]+:/.test(group.label)) {
|
|
2553
|
-
hasFontAwesomeShortcodes = true;
|
|
2554
|
-
break;
|
|
2555
|
-
}
|
|
2556
|
-
for (const tab of group.tabs) {
|
|
2557
|
-
if (tab.label && /:fa-[\w-]+:/.test(tab.label)) {
|
|
2558
|
-
hasFontAwesomeShortcodes = true;
|
|
2559
|
-
break;
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
if (hasFontAwesomeShortcodes)
|
|
2563
|
-
break;
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
// Inject Font Awesome only if shortcodes are found
|
|
2567
|
-
if (hasFontAwesomeShortcodes) {
|
|
2568
|
-
ensureFontAwesomeInjected();
|
|
2569
|
-
}
|
|
2570
2580
|
if (this.options.showTabGroups && tabGroups && tabGroups.length > 0) {
|
|
2571
2581
|
tabGroupControlsHTML = `
|
|
2572
2582
|
<div class="cv-tabgroup-card cv-tabgroup-header">
|
|
@@ -2586,10 +2596,10 @@ class CustomViewsWidget {
|
|
|
2586
2596
|
${tabGroups.map(group => `
|
|
2587
2597
|
<div class="cv-tabgroup-card cv-tabgroup-item">
|
|
2588
2598
|
<label class="cv-tabgroup-label" for="tab-group-${group.id}">
|
|
2589
|
-
${
|
|
2599
|
+
${group.label || group.id}
|
|
2590
2600
|
</label>
|
|
2591
2601
|
<select id="tab-group-${group.id}" class="cv-tabgroup-select" data-group-id="${group.id}">
|
|
2592
|
-
${group.tabs.map(tab => `<option value="${tab.id}">${
|
|
2602
|
+
${group.tabs.map(tab => `<option value="${tab.id}">${tab.label || tab.id}</option>`).join('')}
|
|
2593
2603
|
</select>
|
|
2594
2604
|
</div>
|
|
2595
2605
|
`).join('')}
|
|
@@ -2967,22 +2977,13 @@ function initializeFromScript() {
|
|
|
2967
2977
|
let scriptTag = document.currentScript;
|
|
2968
2978
|
// Fallback if currentScript is not available (executed after page load)
|
|
2969
2979
|
if (!scriptTag) {
|
|
2970
|
-
//
|
|
2971
|
-
const
|
|
2972
|
-
|
|
2973
|
-
//
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
// Look for .min.js or .js at the end, or the package root
|
|
2978
|
-
if (src.match(/@customviews-js\/customviews(\.min)?\.js($|\?)/) || src.includes('@customviews-js/customviews')) {
|
|
2979
|
-
scriptTag = script;
|
|
2980
|
-
break;
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
// If no specific match found, use the first one
|
|
2984
|
-
if (!scriptTag) {
|
|
2985
|
-
scriptTag = scripts[0];
|
|
2980
|
+
// Match the actual CustomViews bundle files (e.g., custom-views.min.js, custom-views.js)
|
|
2981
|
+
for (const script of document.scripts) {
|
|
2982
|
+
const src = script.src || '';
|
|
2983
|
+
// Match filenames like: custom-views.min.js, custom-views.js, custom-views.esm.js
|
|
2984
|
+
if (/custom-views(?:\.min)?\.(?:esm\.)?js($|\?)/i.test(src)) {
|
|
2985
|
+
scriptTag = script;
|
|
2986
|
+
break;
|
|
2986
2987
|
}
|
|
2987
2988
|
}
|
|
2988
2989
|
}
|