@countriesdb/widget 0.1.24 → 0.1.26
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/README.md +0 -1
- package/dist/index.esm.js +105 -41
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +105 -41
- package/dist/index.js.map +1 -1
- package/dist/initialization.js +39 -9
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -506,27 +506,47 @@ async function setupSubdivisionSelection(apiKey, backendUrl, state, config) {
|
|
|
506
506
|
select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
|
+
// Remove old event handlers if they exist (for re-initialization)
|
|
510
|
+
const oldHandlers = state.eventHandlers.get(select);
|
|
511
|
+
if (oldHandlers) {
|
|
512
|
+
if (oldHandlers.update) {
|
|
513
|
+
select.removeEventListener('change', oldHandlers.update);
|
|
514
|
+
}
|
|
515
|
+
if (oldHandlers.followRelated) {
|
|
516
|
+
select.removeEventListener('change', oldHandlers.followRelated);
|
|
517
|
+
}
|
|
518
|
+
if (oldHandlers.followUpward) {
|
|
519
|
+
select.removeEventListener('change', oldHandlers.followUpward);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
// Create new event handlers
|
|
523
|
+
const handlers = {};
|
|
509
524
|
// Always dispatch an update event for user-initiated subdivision changes
|
|
510
|
-
|
|
525
|
+
handlers.update = (event) => {
|
|
511
526
|
if (isWidgetInitiatedEvent(event)) {
|
|
512
527
|
return;
|
|
513
528
|
}
|
|
514
529
|
dispatchUpdateEvent(select, { type: 'subdivision', reason: 'regular' });
|
|
515
|
-
}
|
|
530
|
+
};
|
|
531
|
+
select.addEventListener('change', handlers.update);
|
|
516
532
|
// --- follow_related (forward direction) ---
|
|
517
|
-
|
|
533
|
+
handlers.followRelated = async (event) => {
|
|
518
534
|
if (isWidgetInitiatedEvent(event)) {
|
|
519
535
|
return;
|
|
520
536
|
}
|
|
521
537
|
await handleFollowRelatedFromSubdivision(select, apiKey, backendUrl, state, config.followRelated, (s, key, code) => updateSubdivisionSelect(s, key, backendUrl, state, config, code));
|
|
522
|
-
}
|
|
538
|
+
};
|
|
539
|
+
select.addEventListener('change', handlers.followRelated);
|
|
523
540
|
// --- follow_upward (reverse direction) ---
|
|
524
|
-
|
|
541
|
+
handlers.followUpward = async (event) => {
|
|
525
542
|
if (isWidgetInitiatedEvent(event)) {
|
|
526
543
|
return;
|
|
527
544
|
}
|
|
528
545
|
await handleFollowUpwardFromSubdivision(select, apiKey, backendUrl, state, config.followUpward, (s, key, code) => updateSubdivisionSelect(s, key, backendUrl, state, config, code));
|
|
529
|
-
}
|
|
546
|
+
};
|
|
547
|
+
select.addEventListener('change', handlers.followUpward);
|
|
548
|
+
// Store handlers for future cleanup
|
|
549
|
+
state.eventHandlers.set(select, handlers);
|
|
530
550
|
}
|
|
531
551
|
}
|
|
532
552
|
/**
|
|
@@ -745,8 +765,13 @@ async function setupCountrySelection(apiKey, backendUrl, state, config, subdivis
|
|
|
745
765
|
// Subdivisions will be loaded by event handler
|
|
746
766
|
loadedInitialSubdivisions = true;
|
|
747
767
|
}
|
|
748
|
-
//
|
|
749
|
-
|
|
768
|
+
// Remove old event handlers if they exist (for re-initialization)
|
|
769
|
+
const oldCountryHandlers = state.eventHandlers.get(select);
|
|
770
|
+
if (oldCountryHandlers?.countryChange) {
|
|
771
|
+
select.removeEventListener('change', oldCountryHandlers.countryChange);
|
|
772
|
+
}
|
|
773
|
+
// Create new country change handler
|
|
774
|
+
const countryChangeHandler = async (event) => {
|
|
750
775
|
if (isWidgetInitiatedEvent(event)) {
|
|
751
776
|
return;
|
|
752
777
|
}
|
|
@@ -768,7 +793,12 @@ async function setupCountrySelection(apiKey, backendUrl, state, config, subdivis
|
|
|
768
793
|
if (config.followUpward && !select.multiple && picked.is_subdivision_of) {
|
|
769
794
|
await handleFollowUpwardFromCountry(select, apiKey, backendUrl, state, config.followUpward, (s, key, code) => updateSubdivisionSelect(s, key, backendUrl, state, subdivisionConfig, code));
|
|
770
795
|
}
|
|
771
|
-
}
|
|
796
|
+
};
|
|
797
|
+
// Store and attach the handler
|
|
798
|
+
const countryHandlers = state.eventHandlers.get(select) || {};
|
|
799
|
+
countryHandlers.countryChange = countryChangeHandler;
|
|
800
|
+
state.eventHandlers.set(select, countryHandlers);
|
|
801
|
+
select.addEventListener('change', countryChangeHandler);
|
|
772
802
|
}
|
|
773
803
|
catch (error) {
|
|
774
804
|
console.error('Failed to fetch countries:', error);
|
|
@@ -843,6 +873,7 @@ async function CountriesWidgetLoad(options = {}) {
|
|
|
843
873
|
subdivisionsMap: new WeakMap(),
|
|
844
874
|
subdivisionsLanguageMap: new WeakMap(),
|
|
845
875
|
isInitializing: new Set(),
|
|
876
|
+
eventHandlers: new WeakMap(),
|
|
846
877
|
};
|
|
847
878
|
// Use empty string if publicKey is missing (will show error when API calls fail)
|
|
848
879
|
const apiKey = config.publicKey || '';
|
|
@@ -895,23 +926,27 @@ async function CountriesWidgetLoad(options = {}) {
|
|
|
895
926
|
* Get configuration from options or script URL parameters
|
|
896
927
|
*/
|
|
897
928
|
function getConfigFromOptionsOrScript(options) {
|
|
929
|
+
// Check for global config first (for bundled widgets that need config before auto-init)
|
|
930
|
+
const globalConfig = typeof window !== 'undefined' && window.CountriesDBConfig
|
|
931
|
+
? window.CountriesDBConfig
|
|
932
|
+
: null;
|
|
898
933
|
// Try to get config from script URL (for backward compatibility with widget.blade.php)
|
|
899
934
|
let scriptUrl = null;
|
|
900
935
|
try {
|
|
901
936
|
let loaderScript = null;
|
|
902
937
|
// First try document.currentScript (works during script execution)
|
|
938
|
+
// But only if it matches the widget pattern (not a bundled file)
|
|
903
939
|
if (document.currentScript && document.currentScript instanceof HTMLScriptElement) {
|
|
904
|
-
|
|
940
|
+
const src = document.currentScript.src;
|
|
941
|
+
if (src && (src.includes('@countriesdb/widget') || src.includes('widget/dist/index.js'))) {
|
|
942
|
+
loaderScript = document.currentScript;
|
|
943
|
+
}
|
|
905
944
|
}
|
|
906
|
-
|
|
907
|
-
|
|
945
|
+
// If currentScript didn't match, search for widget script
|
|
946
|
+
if (!loaderScript) {
|
|
908
947
|
const scripts = Array.from(document.getElementsByTagName('script'));
|
|
909
948
|
loaderScript = scripts.find((s) => s.src && (s.src.includes('@countriesdb/widget') ||
|
|
910
949
|
s.src.includes('widget/dist/index.js'))) || null;
|
|
911
|
-
// If still not found, try the last script with src
|
|
912
|
-
if (!loaderScript) {
|
|
913
|
-
loaderScript = scripts.filter((s) => s.src).pop() || null;
|
|
914
|
-
}
|
|
915
950
|
}
|
|
916
951
|
if (loaderScript && loaderScript.src) {
|
|
917
952
|
scriptUrl = new URL(loaderScript.src);
|
|
@@ -921,39 +956,57 @@ function getConfigFromOptionsOrScript(options) {
|
|
|
921
956
|
// Ignore errors
|
|
922
957
|
}
|
|
923
958
|
const config = {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
959
|
+
// Priority: options > globalConfig > scriptUrl params > defaults
|
|
960
|
+
publicKey: options.publicKey ?? globalConfig?.publicKey ?? scriptUrl?.searchParams.get('public_key') ?? '',
|
|
961
|
+
backendUrl: options.backendUrl ?? globalConfig?.backendUrl ?? scriptUrl?.searchParams.get('backend_url') ?? getBackendUrlFromScript(),
|
|
962
|
+
defaultLanguage: options.defaultLanguage ?? globalConfig?.defaultLanguage ?? scriptUrl?.searchParams.get('default_language') ?? undefined,
|
|
963
|
+
forcedLanguage: options.forcedLanguage ?? globalConfig?.forcedLanguage ?? scriptUrl?.searchParams.get('forced_language') ?? undefined,
|
|
928
964
|
showSubdivisionType: options.showSubdivisionType !== undefined
|
|
929
965
|
? options.showSubdivisionType
|
|
930
|
-
:
|
|
966
|
+
: globalConfig?.showSubdivisionType !== undefined
|
|
967
|
+
? globalConfig.showSubdivisionType
|
|
968
|
+
: parseBoolean(scriptUrl?.searchParams.get('show_subdivision_type') ?? '1'),
|
|
931
969
|
followRelated: options.followRelated !== undefined
|
|
932
970
|
? options.followRelated
|
|
933
|
-
:
|
|
971
|
+
: globalConfig?.followRelated !== undefined
|
|
972
|
+
? globalConfig.followRelated
|
|
973
|
+
: parseBoolean(scriptUrl?.searchParams.get('follow_related') ?? 'false'),
|
|
934
974
|
followUpward: options.followUpward !== undefined
|
|
935
975
|
? options.followUpward
|
|
936
|
-
:
|
|
976
|
+
: globalConfig?.followUpward !== undefined
|
|
977
|
+
? globalConfig.followUpward
|
|
978
|
+
: parseBoolean(scriptUrl?.searchParams.get('follow_upward') ?? 'false'),
|
|
937
979
|
allowParentSelection: options.allowParentSelection !== undefined
|
|
938
980
|
? options.allowParentSelection
|
|
939
|
-
:
|
|
981
|
+
: globalConfig?.allowParentSelection !== undefined
|
|
982
|
+
? globalConfig.allowParentSelection
|
|
983
|
+
: parseBoolean(scriptUrl?.searchParams.get('allow_parent_selection') ?? 'false'),
|
|
940
984
|
isoCountryNames: options.isoCountryNames !== undefined
|
|
941
985
|
? options.isoCountryNames
|
|
942
|
-
:
|
|
986
|
+
: globalConfig?.isoCountryNames !== undefined
|
|
987
|
+
? globalConfig.isoCountryNames
|
|
988
|
+
: parseBoolean(scriptUrl?.searchParams.get('iso_country_names') ?? 'false'),
|
|
943
989
|
subdivisionRomanizationPreference: options.subdivisionRomanizationPreference ||
|
|
990
|
+
globalConfig?.subdivisionRomanizationPreference ||
|
|
944
991
|
scriptUrl?.searchParams.get('subdivision_romanization_preference') ||
|
|
945
992
|
undefined,
|
|
946
993
|
preferLocalVariant: options.preferLocalVariant !== undefined
|
|
947
994
|
? options.preferLocalVariant
|
|
948
|
-
:
|
|
995
|
+
: globalConfig?.preferLocalVariant !== undefined
|
|
996
|
+
? globalConfig.preferLocalVariant
|
|
997
|
+
: parseBoolean(scriptUrl?.searchParams.get('prefer_local_variant') ?? 'false'),
|
|
949
998
|
preferOfficialSubdivisions: options.preferOfficialSubdivisions !== undefined
|
|
950
999
|
? options.preferOfficialSubdivisions
|
|
951
|
-
:
|
|
952
|
-
|
|
953
|
-
|
|
1000
|
+
: globalConfig?.preferOfficialSubdivisions !== undefined
|
|
1001
|
+
? globalConfig.preferOfficialSubdivisions
|
|
1002
|
+
: parseBoolean(scriptUrl?.searchParams.get('prefer_official') ?? 'false'),
|
|
1003
|
+
countryNameFilter: options.countryNameFilter ?? globalConfig?.countryNameFilter,
|
|
1004
|
+
subdivisionNameFilter: options.subdivisionNameFilter ?? globalConfig?.subdivisionNameFilter,
|
|
954
1005
|
autoInit: options.autoInit !== undefined
|
|
955
1006
|
? options.autoInit
|
|
956
|
-
:
|
|
1007
|
+
: globalConfig?.autoInit !== undefined
|
|
1008
|
+
? globalConfig.autoInit
|
|
1009
|
+
: parseBoolean(scriptUrl?.searchParams.get('auto_init') ?? 'true'),
|
|
957
1010
|
};
|
|
958
1011
|
// Resolve filter functions from global scope if specified by name
|
|
959
1012
|
if (scriptUrl) {
|
|
@@ -981,18 +1034,19 @@ function getBackendUrlFromScript() {
|
|
|
981
1034
|
try {
|
|
982
1035
|
let loaderScript = null;
|
|
983
1036
|
// First try document.currentScript (works during script execution)
|
|
1037
|
+
// But only if it matches the widget pattern (not a bundled file)
|
|
984
1038
|
if (document.currentScript && document.currentScript instanceof HTMLScriptElement) {
|
|
985
|
-
|
|
1039
|
+
const src = document.currentScript.src;
|
|
1040
|
+
if (src && (src.includes('@countriesdb/widget') || src.includes('widget/dist/index.js'))) {
|
|
1041
|
+
loaderScript = document.currentScript;
|
|
1042
|
+
}
|
|
986
1043
|
}
|
|
987
|
-
|
|
988
|
-
|
|
1044
|
+
// If currentScript didn't match, search for widget script
|
|
1045
|
+
if (!loaderScript) {
|
|
1046
|
+
// Only consider script tags that loaded the widget bundle
|
|
989
1047
|
const scripts = Array.from(document.getElementsByTagName('script'));
|
|
990
1048
|
loaderScript = scripts.find((s) => s.src && (s.src.includes('@countriesdb/widget') ||
|
|
991
1049
|
s.src.includes('widget/dist/index.js'))) || null;
|
|
992
|
-
// If still not found, try the last script with src
|
|
993
|
-
if (!loaderScript) {
|
|
994
|
-
loaderScript = scripts.filter((s) => s.src).pop() || null;
|
|
995
|
-
}
|
|
996
1050
|
}
|
|
997
1051
|
if (loaderScript && loaderScript.src) {
|
|
998
1052
|
const scriptUrl = new URL(loaderScript.src);
|
|
@@ -1075,18 +1129,28 @@ if (typeof window !== 'undefined') {
|
|
|
1075
1129
|
// Find the script tag that loaded this widget
|
|
1076
1130
|
let loaderScript = null;
|
|
1077
1131
|
// First try document.currentScript (works during script execution)
|
|
1132
|
+
// But only if it matches the widget pattern (not a bundled file)
|
|
1078
1133
|
if (document.currentScript && document.currentScript instanceof HTMLScriptElement) {
|
|
1079
|
-
|
|
1134
|
+
const src = document.currentScript.src;
|
|
1135
|
+
if (src && (src.includes('@countriesdb/widget') || src.includes('widget/dist/index.js'))) {
|
|
1136
|
+
loaderScript = document.currentScript;
|
|
1137
|
+
}
|
|
1080
1138
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1139
|
+
// If currentScript didn't match, search for widget script
|
|
1140
|
+
if (!loaderScript) {
|
|
1083
1141
|
const scripts = Array.from(document.getElementsByTagName('script'));
|
|
1084
1142
|
loaderScript = scripts.find((s) => s.src && (s.src.includes('@countriesdb/widget') ||
|
|
1085
1143
|
s.src.includes('widget/dist/index.js'))) || null;
|
|
1086
1144
|
}
|
|
1087
1145
|
// Default to auto-init = true (only disable if explicitly set to false)
|
|
1088
1146
|
let shouldAutoInit = true;
|
|
1089
|
-
|
|
1147
|
+
const globalConfig = typeof window !== 'undefined'
|
|
1148
|
+
? window.CountriesDBConfig || null
|
|
1149
|
+
: null;
|
|
1150
|
+
if (globalConfig && typeof globalConfig.autoInit !== 'undefined') {
|
|
1151
|
+
shouldAutoInit = !!globalConfig.autoInit;
|
|
1152
|
+
}
|
|
1153
|
+
else if (loaderScript && loaderScript.src) {
|
|
1090
1154
|
try {
|
|
1091
1155
|
const scriptUrl = new URL(loaderScript.src);
|
|
1092
1156
|
const autoInit = scriptUrl.searchParams.get('auto_init');
|