-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathmain.js
More file actions
233 lines (209 loc) · 8.05 KB
/
main.js
File metadata and controls
233 lines (209 loc) · 8.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import { configureCompat, createApp } from 'vue';
import { createVuetify } from 'vuetify';
import { md } from 'vuetify/iconsets/md';
import { aliases as defaultAliases, mdi } from 'vuetify/iconsets/mdi';
import 'vuetify/styles';
import { createI18nInstance } from './locales/wgu-i18n';
import '@mdi/font/css/materialdesignicons.css';
import '@material-design-icons/font';
import 'ol/ol.css';
import WguApp from 'APP/WguApp.vue';
import UrlUtil from './util/Url';
import IconUtil from './util/Icon';
import LocaleUtil from './util/Locale';
import ObjectUtil from './util/Object';
import ColorThemeUtil from './util/ColorTheme';
import axios from 'axios';
import './styles/wegue.css';
import 'APP/styles/app.css';
configureCompat({
MODE: 3
})
// Detect an URL parameter for a custom app context
const appCtx = UrlUtil.getQueryParam('appCtx');
let appCtxFile = '';
if (appCtx) {
// simple aproach to avoid path traversal
appCtxFile = '-' + appCtx.replace(/(\.\.[/])+/g, '');
}
/**
* Creates the active vuetify instance.
*
* @param {Object} appConfig Global application context.
* @returns The active vuetify instance.
*/
const createVuetifyInstance = function (appConfig) {
const customIcons = IconUtil.importIcons();
const aliases = { ...defaultAliases, ...customIcons };
const preset = {
theme: ColorThemeUtil.buildTheme(appConfig.colorTheme),
icons: {
defaultSet: 'mdi',
aliases,
sets: {
md,
mdi
}
},
locale: {
locale: LocaleUtil.getPreferredLanguage(appConfig),
fallback: LocaleUtil.getFallbackLanguage(appConfig),
messages: LocaleUtil.importVuetifyLocales()
}
};
return createVuetify(preset);
}
/**
* Creates the VueI18n object used for internationalization.
*
* @param {Object} appConfig Global application context.
* @returns The active I18n instance.
*/
const createVueI18nInstance = function (appConfig) {
return createI18nInstance(appConfig);
}
/**
* Backwards compatibility layer for legacy features in app-conf.json.
*
* @param {Object} appConfig Global application context.
* @returns The migrated application context.
*/
const migrateAppConfig = function (appConfig) {
// Warning for deprecated baseColor
if (appConfig.baseColor) {
console.warn('The configuration path ".baseColor" is deprecated, ' +
'instead declare a path ".colorTheme"');
}
// Migrate boolean values for module.win.
if (appConfig.modules) {
Object.keys(appConfig.modules).forEach(name => {
const module = appConfig.modules[name];
if (typeof module.win === 'boolean') {
module.win = module.win ? 'floating' : undefined;
}
});
}
// Create warnings for text based configuration properties,
// which are no longer supported and have been moved to the language files.
/* eslint-disable @stylistic/quote-props */
const deprecatedTextProps = {
'title': 'app.title',
'browserTitle': 'app.browserTitle',
'footerTextLeft': 'app.footerTextLeft',
'footerTextRight': 'app.footerTextRight',
'mapGeodataDragDrop\\.layerName': 'mapLayers.wgu-drag-drop-layer.name',
'modules.\\.wgu-attributetable\\.selectorLabel': 'wgu-attributetable.selectorLabel',
'modules\\.wgu-geocoder\\.placeHolder': 'wgu-geocoder.placeHolder',
'modules\\.wgu-infoclick\\.mediaInfoLinkText': 'wgu-infoclick.mediaInfoLinkText',
'modules\\.wgu-zoomtomaxextent\\.text': 'wgu-zoomtomaxextent.text',
'modules\\.wgu-helpwin\\.windowTitle': 'wgu-helpwin.title',
'modules\\.wgu-helpwin\\.textTitle': 'wgu-helpwin.textTitle',
'modules\\.wgu-helpwin\\.htmlContent': 'wgu-helpwin.htmlContent',
'modules\\.wgu-helpwin\\.infoLinkUrl': 'wgu-helpwin.infoLinkUrl',
'modules\\.wgu-helpwin\\.infoLinkText': 'wgu-helpwin.infoLinkText',
'modules\\..*\\.title': '<moduleName>.title'
};
/* eslint-enable @stylistic/quote-props */
const configPaths = ObjectUtil.toPaths(appConfig);
for (const path of configPaths) {
const match = Object.keys(deprecatedTextProps).find(pattern => {
const regex = new RegExp('^\\.' + pattern + '$', 'g');
return regex.test(path);
});
if (match) {
console.warn('The configuration path "' + path + '" is deprecated, ' +
'instead declare a path "' + deprecatedTextProps[match] +
'" in all language files in your "/app/locales" folder');
}
};
// Create warnings and migrate settings related to mapLayers configuration:
if (appConfig.mapLayers) {
appConfig.mapLayers.forEach((layer, i) => {
if (!layer.lid) {
console.warn('mapLayers[' + i + '] does not declare a lid property');
}
if (layer.type === 'WMS') {
console.warn('mapLayers[' + i + '] uses the deprecated type WMS. Use TILEWMS instead.');
layer.type = 'TILEWMS';
}
});
}
// Create warnings related to Vuetify color theme configuration,
// which name have changed in Vuetify 3.x:
const deprecatedColorThemeProps = {
'colorTheme\\.themes\\.light\\.onprimary': '.colorTheme.themes.light.on-primary',
'colorTheme\\.themes\\.light\\.onsecondary': '.colorTheme.themes.light.on-secondary',
'colorTheme\\.themes\\.dark\\.onprimary': '.colorTheme.themes.dark.on-primary',
'colorTheme\\.themes\\.dark\\.onsecondary': '.colorTheme.themes.dark.on-secondary'
};
for (const path of configPaths) {
const match = Object.keys(deprecatedColorThemeProps).find(pattern => {
const regex = new RegExp('^\\.' + pattern + '$', 'g');
return regex.test(path);
});
if (match) {
console.warn('The configuration path "' + path + '" is deprecated, ' +
'instead declare a path "' + deprecatedColorThemeProps[match] + '"');
}
};
// Create warnings, if one of the color specific animation properties is declared,
// which are no longer supported due to global view animation configuration.
const deprecatedAnimProps = {
'modules\\.wgu-geolocator\\.zoomAnimation': 'viewAnimation.type',
'modules\\.wgu-geolocator\\.zoomAnimationDuration': 'viewAnimation.options.duration',
'modules\\.wgu-geolocator\\.maxZoom': 'viewAnimation.options.maxZoom',
'modules\\.wgu-geocoder\\.selectZoom': 'viewAnimation.options.zoom'
};
for (const path of configPaths) {
const match = Object.keys(deprecatedAnimProps).find(pattern => {
const regex = new RegExp('^\\.' + pattern + '$', 'g');
return regex.test(path);
});
if (match) {
console.warn('The configuration path "' + path + '" is deprecated, ' +
'instead declare the "viewAnimation" option and configure the "' + deprecatedAnimProps[match] +
'" property');
}
};
// Warning for deprecated mapGeodataDragDop.
if (appConfig.mapGeodataDragDop) {
console.warn('The configuration path ".mapGeodataDragDop" is deprecated, ' +
'instead declare a path ".mapGeodataDragDrop"');
}
return appConfig;
}
/**
* Create the vue application.
*
* @param {Object} appConfig Global application context.
*/
const createAppInstance = function (appConfig) {
const effectiveAppConfig = migrateAppConfig(appConfig);
const vuetify = createVuetifyInstance(effectiveAppConfig);
const i18n = createVueI18nInstance(effectiveAppConfig);
const app = createApp(WguApp);
app.use(vuetify);
app.use(i18n);
// it is recommended to use the provide/inject functionality instead of defining
// global proeprties in Vue3.
// see https://v3-migration.vuejs.org/breaking-changes/global-api#provide-inject
// make app config accessible for all components
app.config.globalProperties.$appConfig = effectiveAppConfig;
// Detect isEmbedded state by attribute embedded and
// make accessible for all components
const appEl = document.querySelector('#app');
app.config.globalProperties.$isEmbedded = appEl.hasAttribute('embedded');
app.mount('#app');
};
// Look in the static dir for an app-specific config file.
const configFile = 'static/app-conf' + appCtxFile + '.json';
const request = {
method: 'GET',
url: configFile
};
axios(request)
.then(response => {
createAppInstance(response.data);
}).catch(function (error) {
console.error(`Cannot load config file ${configFile}, ${error}`);
});