qwc2 2026.2.13 → 2026.2.17

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.
@@ -1180,6 +1180,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1180
1180
  _this2.state.sceneContext.getSceneIntersection = _this2.getSceneIntersection;
1181
1181
  _this2.state.sceneContext.getSetting = _this2.getSetting;
1182
1182
  _this2.state.sceneContext.setSetting = _this2.setSetting;
1183
+ _this2.state.sceneContext.settings.fov = props.defaultFov;
1183
1184
  _this2.state.sceneContext.settings.sceneQuality = props.defaultSceneQuality;
1184
1185
  registerPermalinkDataStoreHook("map3d", _this2.store3dState);
1185
1186
  return _this2;
@@ -1249,6 +1250,10 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1249
1250
  };
1250
1251
  });
1251
1252
  }
1253
+ if (this.state.sceneContext.settings.fov !== prevState.sceneContext.settings.fov) {
1254
+ this.instance.view.camera.fov = this.state.sceneContext.settings.fov;
1255
+ this.instance.notifyChange(this.instance.view.camera);
1256
+ }
1252
1257
  if (this.state.sceneContext.settings.sceneQuality !== prevState.sceneContext.settings.sceneQuality) {
1253
1258
  var quality = Math.max(20, this.state.sceneContext.settings.sceneQuality);
1254
1259
  this.map.segments = Math.pow(2, Math.floor(quality / 20));
@@ -1294,6 +1299,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1294
1299
  _defineProperty(Map3D, "contextType", MapContainerPortalContext);
1295
1300
  _defineProperty(Map3D, "propTypes", {
1296
1301
  controlsPosition: PropTypes.string,
1302
+ defaultFov: PropTypes.number,
1297
1303
  defaultSceneQuality: PropTypes.number,
1298
1304
  innerRef: PropTypes.func,
1299
1305
  layers: PropTypes.array,
@@ -1326,6 +1332,7 @@ _defineProperty(Map3D, "defaultSceneState", {
1326
1332
  sceneObjects: {},
1327
1333
  collisionObjects: [],
1328
1334
  settings: {
1335
+ fov: 30,
1329
1336
  sceneQuality: 100
1330
1337
  },
1331
1338
  sceneId: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.02.13",
3
+ "version": "2026.02.17",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -57,7 +57,7 @@
57
57
  "mousetrap": "^1.6.5",
58
58
  "nearley": "^2.20.1",
59
59
  "object-path": "^0.11.8",
60
- "ol": "^10.7.0",
60
+ "ol": "^10.8.0",
61
61
  "ol-ext": "^4.0.37",
62
62
  "ol-mapbox-style": "^13.2.0",
63
63
  "painterro": "^1.2.92",
package/plugins/API.js CHANGED
@@ -1,12 +1,8 @@
1
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
4
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
9
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
10
6
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
11
7
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
12
8
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -17,9 +13,17 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
17
13
  function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
18
14
  function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
19
15
  function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
16
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
17
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
20
18
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
21
19
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
22
20
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
21
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
22
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
23
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
24
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
25
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
26
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
23
27
  /**
24
28
  * Copyright 2020-2024 Sourcepole AG
25
29
  * All rights reserved.
@@ -116,12 +120,66 @@ import PluginStore from '../utils/PluginStore';
116
120
  import { SearchResultType } from '../utils/SearchProviders';
117
121
  import ServiceLayerUtils from '../utils/ServiceLayerUtils';
118
122
  import VectorLayerUtils from '../utils/VectorLayerUtils';
123
+ function extractFunctions(obj) {
124
+ return Object.entries(obj).reduce(function (result, _ref) {
125
+ var _ref2 = _slicedToArray(_ref, 2),
126
+ key = _ref2[0],
127
+ value = _ref2[1];
128
+ if (typeof value === "function") {
129
+ result[key] = value;
130
+ }
131
+ return result;
132
+ }, {});
133
+ }
134
+ var actionFunctions = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, extractFunctions(displayActions)), extractFunctions(editingActions)), extractFunctions(layerActions)), extractFunctions(localeActions)), extractFunctions(locateActions)), extractFunctions(mapActions)), extractFunctions(taskActions)), extractFunctions(themeActions)), extractFunctions(windowsActions));
119
135
 
120
136
  /**
121
- * Exposes an API for interacting with QWC2 via `window.qwc2`.
137
+ * Exposes an API for interacting with QWC.
122
138
  *
123
139
  * You can interact with the API as soon as the `QWC2ApiReady` event is dispatched.
124
140
  *
141
+ * ### `postMessage` interface
142
+ *
143
+ * You can interact with a QWC instance from a parent application either via the `window.qwc2`
144
+ * interface (see below), if the embedded QWC runs under the same origin as the parent application,
145
+ * or via [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
146
+ * if the origins differ. When using `postMessage`, you must register the allowed parent origins
147
+ * via the `allowedMessageOrigins` config prop. For a QWC embedded in an iframe, a sample call could
148
+ * then be
149
+ *
150
+ * ```
151
+ * qwcframe = document.getElementById("qwciframe");
152
+ * qwcframe.contentWindow.postMessage({
153
+ * "method": "zoomToPoint",
154
+ * "params": [[2684764, 1247841], 18, "EPSG:2056"]
155
+ * }, "http://<qwc_hostname>:<port>")
156
+ * ```
157
+ * If you call a method which returns a value, pass a `requestId` and listen to response messages:
158
+ *
159
+ * ```
160
+ * window.addEventListener("message", (ev) => {
161
+ * console.log(ev.data.requestId);
162
+ * console.log(ev.data.result);
163
+ * });
164
+ * qwcframe.contentWindow.postMessage(
165
+ * {"method": "getState", "requestId": "<arbitrary_id_string>"},
166
+ * "http://<qwc_hostname>:<port>"
167
+ * )
168
+ * ```
169
+ *
170
+ * A list of supported methods will be printed to the console if you run
171
+ *
172
+ * ```
173
+ * qwcframe.contentWindow.postMessage("help", "http://<qwc_hostname>:<port>")
174
+ * ```
175
+ *
176
+ * To check the full signature of a method (including default param values), check
177
+ * the respective action function definitions as referenced in the *`window.qwc2` API*
178
+ * section below. Note that you can only pass values which can be serialized via
179
+ * structured clone in the message params.
180
+ *
181
+ * ### Custom plugins
182
+ *
125
183
  * Here is an example of a custom plugin:
126
184
  *
127
185
  * ```
@@ -170,6 +228,8 @@ import VectorLayerUtils from '../utils/VectorLayerUtils';
170
228
  * "name": "CurrentTheme"
171
229
  * }
172
230
  *
231
+ * ### `window.qwc2` API
232
+ *
173
233
  * The following action functions are exposed in the API:
174
234
  *
175
235
  * - [display](https://github.com/qgis/qwc2/blob/master/actions/display.js)
@@ -202,10 +262,56 @@ var API = /*#__PURE__*/function (_React$Component) {
202
262
  function API() {
203
263
  var _this;
204
264
  _classCallCheck(this, API);
205
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
206
- args[_key] = arguments[_key];
265
+ for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
266
+ _args[_key] = arguments[_key];
207
267
  }
208
- _this = _callSuper(this, API, [].concat(args));
268
+ _this = _callSuper(this, API, [].concat(_args));
269
+ _defineProperty(_this, "handleMessage", function (ev) {
270
+ var _ev$data;
271
+ if (!_this.props.allowedMessageOrigins.includes(ev.origin)) {
272
+ /* eslint-disable-next-line */
273
+ console.warn("Discarding message from not-allowed origin " + ev.origin);
274
+ return;
275
+ }
276
+ var allowedMemberFunctions = ["addExternalLayer", "getState"];
277
+ if (ev.data === "help") {
278
+ var signatures = Object.fromEntries(Object.entries(actionFunctions).map(function (_ref3) {
279
+ var _val$toString$match$, _val$toString$match;
280
+ var _ref4 = _slicedToArray(_ref3, 2),
281
+ key = _ref4[0],
282
+ val = _ref4[1];
283
+ return [key, (_val$toString$match$ = (_val$toString$match = val.toString().match(/^function\s+\w+\s*(\([^)]+\))/)) === null || _val$toString$match === void 0 ? void 0 : _val$toString$match[1]) !== null && _val$toString$match$ !== void 0 ? _val$toString$match$ : "()"];
284
+ }));
285
+ allowedMemberFunctions.forEach(function (name) {
286
+ var _this$name$toString$m, _this$name$toString$m2;
287
+ signatures[name] = (_this$name$toString$m = (_this$name$toString$m2 = _this[name].toString().match(/^function\s+(\([^)]+\))/)) === null || _this$name$toString$m2 === void 0 ? void 0 : _this$name$toString$m2[1]) !== null && _this$name$toString$m !== void 0 ? _this$name$toString$m : "()";
288
+ });
289
+ /* eslint-disable-next-line */
290
+ console.log(signatures);
291
+ }
292
+ if ((_ev$data = ev.data) !== null && _ev$data !== void 0 && _ev$data.method) {
293
+ var _ev$data$params;
294
+ var func = ev.data.method;
295
+ var args = (_ev$data$params = ev.data.params) !== null && _ev$data$params !== void 0 ? _ev$data$params : [];
296
+ var result = null;
297
+ if (func in actionFunctions) {
298
+ var _this$props;
299
+ result = (_this$props = _this.props)[func].apply(_this$props, _toConsumableArray(args));
300
+ } else if (allowedMemberFunctions.includes(func)) {
301
+ var _this2;
302
+ result = (_this2 = _this)[func].apply(_this2, _toConsumableArray(args));
303
+ } else {
304
+ /* eslint-disable-next-line */
305
+ console.warn("Unhandeled message: " + JSON.stringify(ev.data));
306
+ }
307
+ if (ev.data.requestId) {
308
+ ev.source.postMessage({
309
+ requestId: ev.data.requestId,
310
+ result: result
311
+ }, ev.origin);
312
+ }
313
+ }
314
+ });
209
315
  /**
210
316
  * Add custom plugin
211
317
  *
@@ -373,7 +479,9 @@ var API = /*#__PURE__*/function (_React$Component) {
373
479
  // Auto-binded functions
374
480
  for (var _i = 0, _Object$keys = Object.keys(this.props); _i < _Object$keys.length; _i++) {
375
481
  var prop = _Object$keys[_i];
376
- window.qwc2[prop] = this.props[prop];
482
+ if (typeof this.props[prop] === "function") {
483
+ window.qwc2[prop] = this.props[prop];
484
+ }
377
485
  }
378
486
  // Additional exports
379
487
  window.qwc2.LayerRole = LayerRole;
@@ -464,6 +572,9 @@ var API = /*#__PURE__*/function (_React$Component) {
464
572
  window.qwc2.components.TextInput = TextInput;
465
573
  window.qwc2.components.ToggleSwitch = ToggleSwitch;
466
574
  window.qwc2.components.VectorLayerPicker = VectorLayerPicker;
575
+
576
+ // Add message event listener
577
+ window.addEventListener("message", this.handleMessage);
467
578
  window.dispatchEvent(new Event("QWC2ApiReady"));
468
579
  }
469
580
  }, {
@@ -475,29 +586,23 @@ var API = /*#__PURE__*/function (_React$Component) {
475
586
  }(React.Component);
476
587
  _defineProperty(API, "propTypes", {
477
588
  addLayer: PropTypes.func,
589
+ /* List of origins which are allowed to post messages via `qwcIframe.postMessage`. */
590
+ allowedMessageOrigins: PropTypes.arrayOf(PropTypes.string),
478
591
  mapCrs: PropTypes.string,
479
592
  registerCustomPlugin: PropTypes.func,
480
593
  setCurrentTask: PropTypes.func,
481
594
  state: PropTypes.object,
482
595
  unregisterCustomPlugin: PropTypes.func
483
596
  });
484
- function extractFunctions(obj) {
485
- return Object.entries(obj).reduce(function (result, _ref) {
486
- var _ref2 = _slicedToArray(_ref, 2),
487
- key = _ref2[0],
488
- value = _ref2[1];
489
- if (typeof value === "function") {
490
- result[key] = value;
491
- }
492
- return result;
493
- }, {});
494
- }
597
+ _defineProperty(API, "defaultProps", {
598
+ allowedMessageOrigins: []
599
+ });
495
600
  export default connect(function (state) {
496
601
  return {
497
602
  mapCrs: state.map.projection,
498
603
  state: state
499
604
  };
500
- }, _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
605
+ }, _objectSpread({
501
606
  registerCustomPlugin: registerCustomPlugin,
502
607
  unregisterCustomPlugin: unregisterCustomPlugin
503
- }, extractFunctions(displayActions)), extractFunctions(editingActions)), extractFunctions(layerActions)), extractFunctions(localeActions)), extractFunctions(locateActions)), extractFunctions(mapActions)), extractFunctions(taskActions)), extractFunctions(themeActions)), extractFunctions(windowsActions)))(API);
608
+ }, actionFunctions))(API);
@@ -966,7 +966,7 @@ var LayerTree = /*#__PURE__*/function (_React$Component) {
966
966
  _defineProperty(_this, "getLayerStyles", function (layer) {
967
967
  var _layer$sublayers;
968
968
  return layer === null || layer === void 0 || (_layer$sublayers = layer.sublayers) === null || _layer$sublayers === void 0 ? void 0 : _layer$sublayers.reduce(function (styleList, sublayer) {
969
- Object.assign(styleList, _this.getLayerStyles(sublayer.sublayers));
969
+ Object.assign(styleList, _this.getLayerStyles(sublayer));
970
970
  return Object.assign(styleList, sublayer.styles);
971
971
  }, {});
972
972
  });
@@ -79,7 +79,9 @@ var Settings = /*#__PURE__*/function (_React$Component) {
79
79
  }, /*#__PURE__*/React.createElement("tbody", null, _this.renderLanguageSelector(), _this.renderColorSchemeSelector(), _this.renderDefaultThemeSelector())));
80
80
  });
81
81
  _defineProperty(_this, "renderLanguageSelector", function () {
82
- if (isEmpty(_this.props.languages)) {
82
+ var _this$props$languages;
83
+ var languages = (_this$props$languages = _this.props.languages) !== null && _this$props$languages !== void 0 ? _this$props$languages : ConfigUtils.getConfigProp("availableLocales");
84
+ if (isEmpty(languages)) {
83
85
  return null;
84
86
  }
85
87
  var lang = LocaleUtils.lang();
@@ -89,7 +91,7 @@ var Settings = /*#__PURE__*/function (_React$Component) {
89
91
  }, /*#__PURE__*/React.createElement("option", {
90
92
  key: "syslang",
91
93
  value: ""
92
- }, LocaleUtils.tr("settings.systemlang")), _this.props.languages.map(function (entry) {
94
+ }, LocaleUtils.tr("settings.systemlang")), languages.map(function (entry) {
93
95
  var _entry$title;
94
96
  return /*#__PURE__*/React.createElement("option", {
95
97
  key: entry.value,
@@ -216,7 +218,7 @@ _defineProperty(Settings, "propTypes", {
216
218
  value: PropTypes.string
217
219
  })),
218
220
  defaultUrlParams: PropTypes.string,
219
- /** List of available languages. Value is the lang code, title/titleMsgId the display name. */
221
+ /** List of available languages. Value is the lang code, title/titleMsgId the display name. Falls back to the toplevel `availableLocales` `config.json` setting if not set. */
220
222
  languages: PropTypes.arrayOf(PropTypes.shape({
221
223
  title: PropTypes.string,
222
224
  titleMsgId: PropTypes.string,
@@ -232,7 +234,7 @@ _defineProperty(Settings, "propTypes", {
232
234
  });
233
235
  _defineProperty(Settings, "defaultProps", {
234
236
  colorSchemes: [],
235
- languages: [],
237
+ languages: null,
236
238
  side: 'right',
237
239
  showDefaultThemeSelector: true
238
240
  });
package/plugins/View3D.js CHANGED
@@ -443,6 +443,7 @@ var View3D = /*#__PURE__*/function (_React$Component) {
443
443
  pluginsConfig: pluginsConfig
444
444
  }, /*#__PURE__*/React.createElement(Map3D, {
445
445
  controlsPosition: this.props.controlsPosition,
446
+ defaultFov: this.props.defaultFov,
446
447
  defaultSceneQuality: this.props.defaultSceneQuality,
447
448
  innerRef: this.setRef,
448
449
  mouseButtons: this.props.mouseButtons,
@@ -464,6 +465,8 @@ _defineProperty(View3D, "propTypes", {
464
465
  addLayerFeatures: PropTypes.func,
465
466
  /** The position of the navigation controls. Either `top` or `bottom`. */
466
467
  controlsPosition: PropTypes.string,
468
+ /** The default field of view (`20`: min, `100`: max). */
469
+ defaultFov: PropTypes.number,
467
470
  /** The default scene quality factor (`20`: min, `100`: max). */
468
471
  defaultSceneQuality: PropTypes.number,
469
472
  display: PropTypes.object,
@@ -500,6 +503,7 @@ _defineProperty(View3D, "propTypes", {
500
503
  });
501
504
  _defineProperty(View3D, "defaultProps", {
502
505
  controlsPosition: 'top',
506
+ defaultFov: 30,
503
507
  defaultSceneQuality: 100,
504
508
  geometry: {
505
509
  initialWidth: 600,
@@ -24,6 +24,7 @@ import React from 'react';
24
24
  import PropTypes from 'prop-types';
25
25
  import SideBar from '../../components/SideBar';
26
26
  import Input from '../../components/widgets/Input';
27
+ import InputContainer from '../../components/widgets/InputContainer';
27
28
  import LocaleUtils from '../../utils/LocaleUtils';
28
29
  import './style/Settings3D.css';
29
30
 
@@ -41,18 +42,34 @@ var Settings3D = /*#__PURE__*/function (_React$Component) {
41
42
  _defineProperty(_this, "renderBody", function () {
42
43
  return /*#__PURE__*/React.createElement("div", {
43
44
  className: "settings3d-body"
44
- }, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("settings3d.quality")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Input, {
45
+ }, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("settings3d.quality")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(InputContainer, null, /*#__PURE__*/React.createElement(Input, {
45
46
  max: 100,
46
47
  min: 20,
47
48
  onChange: _this.qualityChanged,
49
+ role: "input",
48
50
  step: 20,
49
51
  type: "range",
50
52
  value: _this.props.sceneContext.settings.sceneQuality
51
- }))))));
53
+ }), /*#__PURE__*/React.createElement("span", {
54
+ role: "suffix"
55
+ }, _this.props.sceneContext.settings.sceneQuality, "\xA0%")))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("settings3d.fov")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(InputContainer, null, /*#__PURE__*/React.createElement(Input, {
56
+ max: 100,
57
+ min: 25,
58
+ onChange: _this.fovChanged,
59
+ role: "input",
60
+ step: 5,
61
+ type: "range",
62
+ value: _this.props.sceneContext.settings.fov
63
+ }), /*#__PURE__*/React.createElement("span", {
64
+ role: "suffix"
65
+ }, _this.props.sceneContext.settings.fov, "\xA0\xB0")))))));
52
66
  });
53
67
  _defineProperty(_this, "qualityChanged", function (value) {
54
68
  _this.props.sceneContext.setSetting("sceneQuality", parseInt(value, 10));
55
69
  });
70
+ _defineProperty(_this, "fovChanged", function (value) {
71
+ _this.props.sceneContext.setSetting("fov", parseInt(value, 10));
72
+ });
56
73
  return _this;
57
74
  }
58
75
  _inherits(Settings3D, _React$Component);
@@ -6,6 +6,11 @@ div.settings3d-body table td {
6
6
  padding: 0 0.25em;
7
7
  }
8
8
 
9
- div.settings3d-body table td > input {
9
+ div.settings3d-body table td:nth-child(2) {
10
+ width: 99%;
11
+ }
12
+
13
+ div.settings3d-body table td > input,
14
+ div.settings3d-body table td > div.input-container {
10
15
  width: 100%;
11
- }
16
+ }
@@ -640,6 +640,7 @@
640
640
  "themes": "Теми"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temes"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Themen"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Sichtfeld",
643
644
  "quality": "Qualität"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Themen"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Sichtfeld",
643
644
  "quality": "Qualität"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Themes"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Field of view",
643
644
  "quality": "Quality"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temas"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Campo de visión",
643
644
  "quality": "Calidad"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Thèmes"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Champ de vue",
643
644
  "quality": "Qualité"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temi"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "Campo visivo",
643
644
  "quality": "Qualità"
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "テーマ"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Kaarten"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temas"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temas"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -640,6 +640,7 @@
640
640
  "themes": "Temalar"
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -550,6 +550,7 @@
550
550
  "settings.language",
551
551
  "settings.systemlang",
552
552
  "settings.themes",
553
+ "settings3d.fov",
553
554
  "settings3d.quality",
554
555
  "share.QRCodeLinkTitle",
555
556
  "share.directLinkTitle",
@@ -640,6 +640,7 @@
640
640
  "themes": ""
641
641
  },
642
642
  "settings3d": {
643
+ "fov": "",
643
644
  "quality": ""
644
645
  },
645
646
  "share": {
@@ -15,7 +15,12 @@ var LocaleUtils = {
15
15
  loadLocale: function loadLocale(lang, fallbackLangData) {
16
16
  return new Promise(function (resolve) {
17
17
  var loadLang = null;
18
- var availableLanguages = process.env.AvailableLanguages;
18
+ var availableLanguages = ConfigUtils.getConfigProp("availableLocales");
19
+ if (availableLanguages) {
20
+ availableLanguages = Object.keys(availableLanguages);
21
+ } else {
22
+ availableLanguages = process.env.AvailableLanguages;
23
+ }
19
24
  if (availableLanguages.indexOf(lang) !== -1) {
20
25
  // Exact match: lang-REGION
21
26
  loadLang = lang;
@@ -1,21 +1,49 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
1
2
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
3
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
4
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
5
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
6
  function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
6
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
9
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
10
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
11
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
12
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
13
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
14
+ function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
15
+ function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
16
+ function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
17
+ function _wrapNativeSuper(t) { var r = "function" == typeof Map ? new Map() : void 0; return _wrapNativeSuper = function _wrapNativeSuper(t) { if (null === t || !_isNativeFunction(t)) return t; if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function"); if (void 0 !== r) { if (r.has(t)) return r.get(t); r.set(t, Wrapper); } function Wrapper() { return _construct(t, arguments, _getPrototypeOf(this).constructor); } return Wrapper.prototype = Object.create(t.prototype, { constructor: { value: Wrapper, enumerable: !1, writable: !0, configurable: !0 } }), _setPrototypeOf(Wrapper, t); }, _wrapNativeSuper(t); }
18
+ function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return r && _setPrototypeOf(p, r.prototype), p; }
19
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
20
+ function _isNativeFunction(t) { try { return -1 !== Function.toString.call(t).indexOf("[native code]"); } catch (n) { return "function" == typeof t; } }
21
+ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
22
+ function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
8
23
  // Generated automatically by nearley, version 2.20.1
9
24
  // http://github.com/Hardmath123/nearley
10
25
  (function () {
11
26
  function id(x) {
12
27
  return x[0];
13
28
  }
29
+ var Field = /*#__PURE__*/function (_String) {
30
+ function Field(value) {
31
+ _classCallCheck(this, Field);
32
+ return _callSuper(this, Field, [value]);
33
+ }
34
+ _inherits(Field, _String);
35
+ return _createClass(Field, [{
36
+ key: "toJSON",
37
+ value: function toJSON() {
38
+ return this.toString();
39
+ }
40
+ }]);
41
+ }(/*#__PURE__*/_wrapNativeSuper(String));
14
42
  if (typeof window === 'undefined') {
15
43
  window = global;
16
44
  }
17
45
  function asFilter(d) {
18
- return window.qwc2ExpressionParserContext.asFilter && ["string", "object"].includes(_typeof(d[0]));
46
+ return window.qwc2ExpressionParserContext.asFilter && (d[0] instanceof Field || d[0] instanceof Array);
19
47
  }
20
48
  function generateUUID() {
21
49
  var d = new Date().getTime();
@@ -476,7 +504,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
476
504
  "symbols": ["dqstring"],
477
505
  "postprocess": function postprocess(d) {
478
506
  var _window$qwc2Expressio, _window$qwc2Expressio2;
479
- return asFilter(d) ? d[0] : (_window$qwc2Expressio = (_window$qwc2Expressio2 = window.qwc2ExpressionParserContext.feature.properties) === null || _window$qwc2Expressio2 === void 0 ? void 0 : _window$qwc2Expressio2[d[0]]) !== null && _window$qwc2Expressio !== void 0 ? _window$qwc2Expressio : null;
507
+ return window.qwc2ExpressionParserContext.asFilter ? new Field(d[0]) : (_window$qwc2Expressio = (_window$qwc2Expressio2 = window.qwc2ExpressionParserContext.feature.properties) === null || _window$qwc2Expressio2 === void 0 ? void 0 : _window$qwc2Expressio2[d[0]]) !== null && _window$qwc2Expressio !== void 0 ? _window$qwc2Expressio : null;
480
508
  }
481
509
  }, {
482
510
  "name": "N$string$1",
@@ -1921,7 +1949,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
1921
1949
  "literal": ")"
1922
1950
  }],
1923
1951
  "postprocess": function postprocess(d) {
1924
- return asFilter(d) ? [d[4], "HAS", d[8]] : d[4].includes(d[8]);
1952
+ return window.qwc2ExpressionParserContext.asFilter ? [d[4], "HAS", d[8]] : d[4].includes(d[8]);
1925
1953
  }
1926
1954
  }, {
1927
1955
  "name": "N$string$51",
@@ -1,12 +1,20 @@
1
1
  @builtin "string.ne"
2
2
 
3
3
  @{%
4
+ class Field extends String {
5
+ constructor(value) {
6
+ super(value);
7
+ }
8
+ toJSON() {
9
+ return this.toString();
10
+ }
11
+ }
4
12
 
5
13
  if (typeof window === 'undefined') {
6
14
  window = global;
7
15
  }
8
- function asFilter(d) {
9
- return window.qwc2ExpressionParserContext.asFilter && ["string", "object"].includes(typeof(d[0]));
16
+ function opAsFilter(d) {
17
+ return window.qwc2ExpressionParserContext.asFilter && (d[0] instanceof Field || d[0] instanceof Array);
10
18
  }
11
19
  function generateUUID() {
12
20
  let d = new Date().getTime();
@@ -27,30 +35,31 @@ function generateUUID() {
27
35
  function replaceWildcards(str) {
28
36
  return "^" + str.replace(/(?<!\\)%/g, '.*').replace(/(?<!\\)_/g, '.{1}') + "$";
29
37
  }
38
+
30
39
  %}
31
40
 
32
41
  main -> _ P0 _ {% function(d) {return d[1]; } %}
33
42
 
34
43
  # Priority-0 operators (OR)
35
- P0 -> P0 _ "OR"i _ P1 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] || d[4]); } %}
44
+ P0 -> P0 _ "OR"i _ P1 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] || d[4]); } %}
36
45
  | P1 {% id %}
37
46
 
38
47
  # Priority-1 operators (AND)
39
- P1 -> P1 _ "AND"i _ P2 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] && d[4]); } %}
48
+ P1 -> P1 _ "AND"i _ P2 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] && d[4]); } %}
40
49
  | P2 {% id %}
41
50
 
42
51
  # Priority-2 operators (comparison operators)
43
- P2 -> P2 _ "<" _ P3 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] < d[4]); } %}
44
- | P2 _ ">" _ P3 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] > d[4]); } %}
45
- | P2 _ ">=" _ P3 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] >= d[4]); } %}
46
- | P2 _ "<=" _ P3 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] <= d[4]); } %}
47
- | P2 _ "=" _ P3 {% function(d) { return asFilter(d) ? [d[0], d[2], d[4]] : (d[0] == d[4]); } %}
48
- | P2 _ "<>" _ P3 {% function(d) { return asFilter(d) ? [d[0], "!=", d[4]] : (d[0] != d[4]); } %}
49
- | P2 _ "IS"i _ P3 {% function(d) { return asFilter(d) ? [d[0], "=", d[4]] : d[0] === d[4]; } %}
50
- | P2 _ "IS"i _ "NOT"i _ P3 {% function(d) { return asFilter(d) ? [d[0], "!=", d[6]] : d[0] !== d[6]; } %}
51
- | P2 _ "~" _ P3 {% function(d) { return asFilter(d) ? [d[0], "~", d[4]] : new RegExp(d[4]).exec(d[0]) !== null; } %}
52
- | P2 _ "LIKE"i _ P3 {% function(d) { return asFilter(d) ? [d[0], "LIKE", d[4]] : new RegExp(replaceWildcards(d[4])).exec(d[0]) !== null; } %}
53
- | P2 _ "ILIKE"i _ P3 {% function(d) { return asFilter(d) ? [d[0], "ILIKE", d[4]] : new RegExp(replaceWildcards(d[4]), 'i').exec(d[0]) !== null; } %}
52
+ P2 -> P2 _ "<" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] < d[4]); } %}
53
+ | P2 _ ">" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] > d[4]); } %}
54
+ | P2 _ ">=" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] >= d[4]); } %}
55
+ | P2 _ "<=" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] <= d[4]); } %}
56
+ | P2 _ "=" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], d[2], d[4]] : (d[0] == d[4]); } %}
57
+ | P2 _ "<>" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "!=", d[4]] : (d[0] != d[4]); } %}
58
+ | P2 _ "IS"i _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "=", d[4]] : d[0] === d[4]; } %}
59
+ | P2 _ "IS"i _ "NOT"i _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "!=", d[6]] : d[0] !== d[6]; } %}
60
+ | P2 _ "~" _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "~", d[4]] : new RegExp(d[4]).exec(d[0]) !== null; } %}
61
+ | P2 _ "LIKE"i _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "LIKE", d[4]] : new RegExp(replaceWildcards(d[4])).exec(d[0]) !== null; } %}
62
+ | P2 _ "ILIKE"i _ P3 {% function(d) { return opAsFilter(d) ? [d[0], "ILIKE", d[4]] : new RegExp(replaceWildcards(d[4]), 'i').exec(d[0]) !== null; } %}
54
63
  | P3 {% id %}
55
64
 
56
65
  # Priority-3 operators (addition, subtraction, concatenation)
@@ -87,7 +96,7 @@ P8 -> "(" _ P0 _ ")" {% function(d) { return d[2]; } %}
87
96
  # A number or a function of a number, a variable or a constant
88
97
  N -> float {% id %}
89
98
  | sqstring {% id %}
90
- | dqstring {% function(d) { return asFilter(d) ? d[0] : window.qwc2ExpressionParserContext.feature.properties?.[d[0]] ?? null; } %}
99
+ | dqstring {% function(d) { return window.qwc2ExpressionParserContext.asFilter ? new Field(d[0]) : window.qwc2ExpressionParserContext.feature.properties?.[d[0]] ?? null; } %}
91
100
  | "uuid" _ "(" _ ")" {% function(d) { return generateUUID(); } %}
92
101
  | "now" _ "(" _ ")" {% function(d) { return (new Date()).toISOString(); } %}
93
102
  | "abs" _ "(" _ P0 _ ")" {% function(d) { return Math.abs(d[4]); } %}
@@ -135,7 +144,7 @@ N -> float {% id %}
135
144
  | "array_all" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return d[8].every(val => d[4].includes(val)); } %}
136
145
  | "array_append" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return [...d[4], d[8]]; } %}
137
146
  | "array_cat" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return [...d[4], ...d[8]]; } %}
138
- | "array_contains" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return asFilter(d) ? [d[4], "HAS", d[8]] : d[4].includes(d[8]); } %}
147
+ | "array_contains" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return window.qwc2ExpressionParserContext.asFilter ? [d[4], "HAS", d[8]] : d[4].includes(d[8]); } %}
139
148
  | "array_count" _ "(" _ P0 _ "," _ P0 _ ")" {% function(d) { return d[4].filter(val => val === d[8]).length; } %}
140
149
  | "array_distinct" _ "(" _ P0 _ ")" {% function(d) { return [...new Set(d[4])].sort((a,b) => a-b); } %}
141
150
  # "array_filter" _ "(" _ P0 _ "," _ P1 _ ")" TODO