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