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