@teipublisher/pb-components 1.30.2 → 1.32.0
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/CHANGELOG.md +39 -0
- package/Dockerfile +1 -1
- package/css/leaflet/MarkerCluster.Default.css +60 -0
- package/css/leaflet/MarkerCluster.css +14 -0
- package/dist/demo/demos.json +3 -0
- package/dist/demo/pb-custom-form.html +61 -0
- package/dist/demo/pb-leaflet-map.html +9 -7
- package/dist/demo/pb-leaflet-map2.html +2 -2
- package/dist/demo/pb-leaflet-map3.html +15 -22
- package/dist/es-global-bridge-6abe3a88.js +5 -0
- package/dist/pb-components-bundle.js +179 -139
- package/dist/pb-elements.json +191 -2
- package/dist/pb-leaflet-map.js +4 -8
- package/i18n/common/de.json +20 -0
- package/i18n/common/en.json +20 -0
- package/lib/leaflet-src.js +14062 -0
- package/lib/leaflet.markercluster-src.js +2718 -0
- package/package.json +2 -1
- package/pb-elements.json +191 -2
- package/src/pb-components.js +1 -0
- package/src/pb-custom-form.js +49 -7
- package/src/pb-geolocation.js +36 -11
- package/src/pb-leaflet-map.js +75 -37
- package/src/pb-select-feature.js +6 -0
- package/src/pb-split-list.js +188 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teipublisher/pb-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
4
4
|
"description": "Collection of webcomponents underlying TEI Publisher",
|
|
5
5
|
"repository": "https://github.com/eeditiones/tei-publisher-components.git",
|
|
6
6
|
"main": "index.html",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"i18next-xhr-backend": "^3.2.2",
|
|
77
77
|
"js-cookie": "^2.2.1",
|
|
78
78
|
"leaflet": "^1.7.1",
|
|
79
|
+
"leaflet.markercluster": "^1.5.3",
|
|
79
80
|
"lit-element": "latest",
|
|
80
81
|
"lit-html": "^1.3.0",
|
|
81
82
|
"marked": "^1.2.0",
|
package/pb-elements.json
CHANGED
|
@@ -2249,8 +2249,13 @@
|
|
|
2249
2249
|
{
|
|
2250
2250
|
"name": "pb-custom-form",
|
|
2251
2251
|
"path": "./src/pb-custom-form.js",
|
|
2252
|
-
"description": "A custom form element which loads the actual form from a server-side script using AJAX.\nEmits
|
|
2252
|
+
"description": "A custom form element which loads the actual form from a server-side script using AJAX.\nEmits `pb-search-resubmit` and `pb-submit` events, signalling the receiver that it should\nrefresh.\n\nThe component is currently used to implement the additional search facets on the start and\nsearch result page. It can also be combined with `pb-split-list` to contain an additional form\nwith options.",
|
|
2253
2253
|
"attributes": [
|
|
2254
|
+
{
|
|
2255
|
+
"name": "auto-submit",
|
|
2256
|
+
"description": "Register event handlers on all inputs and submit the form\nautomatically if any of those changes. For button-like controls,\na submit is triggered on click, for text input on keyUp, and for\nall other form components on change.",
|
|
2257
|
+
"type": "string"
|
|
2258
|
+
},
|
|
2254
2259
|
{
|
|
2255
2260
|
"name": "url",
|
|
2256
2261
|
"description": "The URL for the AJAX request. If a relative URL is passed, it will be resolved\nagainst the current API endpoint.",
|
|
@@ -2345,6 +2350,12 @@
|
|
|
2345
2350
|
}
|
|
2346
2351
|
],
|
|
2347
2352
|
"properties": [
|
|
2353
|
+
{
|
|
2354
|
+
"name": "autoSubmit",
|
|
2355
|
+
"attribute": "auto-submit",
|
|
2356
|
+
"description": "Register event handlers on all inputs and submit the form\nautomatically if any of those changes. For button-like controls,\na submit is triggered on click, for text input on keyUp, and for\nall other form components on change.",
|
|
2357
|
+
"type": "string"
|
|
2358
|
+
},
|
|
2348
2359
|
{
|
|
2349
2360
|
"name": "url",
|
|
2350
2361
|
"attribute": "url",
|
|
@@ -2466,7 +2477,16 @@
|
|
|
2466
2477
|
],
|
|
2467
2478
|
"events": [
|
|
2468
2479
|
{
|
|
2469
|
-
"name": "pb-custom-form-loaded"
|
|
2480
|
+
"name": "pb-custom-form-loaded",
|
|
2481
|
+
"description": "Fired before the element updates its content"
|
|
2482
|
+
},
|
|
2483
|
+
{
|
|
2484
|
+
"name": "pb-search-resubmit",
|
|
2485
|
+
"description": "Fired when the form is submitted"
|
|
2486
|
+
},
|
|
2487
|
+
{
|
|
2488
|
+
"name": "pb-submit",
|
|
2489
|
+
"description": "Fired when the form is submitted"
|
|
2470
2490
|
},
|
|
2471
2491
|
{
|
|
2472
2492
|
"name": "pb-start-update",
|
|
@@ -3738,6 +3758,12 @@
|
|
|
3738
3758
|
"type": "string",
|
|
3739
3759
|
"default": "\"mouseover\""
|
|
3740
3760
|
},
|
|
3761
|
+
{
|
|
3762
|
+
"name": "auto",
|
|
3763
|
+
"description": "If set, add location to a map automatically upon load by\nemitting an event. If not set, locations are only added when\nthe configured event is triggered.",
|
|
3764
|
+
"type": "boolean",
|
|
3765
|
+
"default": "false"
|
|
3766
|
+
},
|
|
3741
3767
|
{
|
|
3742
3768
|
"name": "key",
|
|
3743
3769
|
"description": "The key to which this element is connected.",
|
|
@@ -3819,6 +3845,13 @@
|
|
|
3819
3845
|
"type": "string",
|
|
3820
3846
|
"default": "\"mouseover\""
|
|
3821
3847
|
},
|
|
3848
|
+
{
|
|
3849
|
+
"name": "auto",
|
|
3850
|
+
"attribute": "auto",
|
|
3851
|
+
"description": "If set, add location to a map automatically upon load by\nemitting an event. If not set, locations are only added when\nthe configured event is triggered.",
|
|
3852
|
+
"type": "boolean",
|
|
3853
|
+
"default": "false"
|
|
3854
|
+
},
|
|
3822
3855
|
{
|
|
3823
3856
|
"name": "key",
|
|
3824
3857
|
"attribute": "key",
|
|
@@ -4547,6 +4580,18 @@
|
|
|
4547
4580
|
"type": "boolean",
|
|
4548
4581
|
"default": "false"
|
|
4549
4582
|
},
|
|
4583
|
+
{
|
|
4584
|
+
"name": "cluster",
|
|
4585
|
+
"description": "If set, combine markers into clusters if they are located too close together\nto display as single markers",
|
|
4586
|
+
"type": "boolean",
|
|
4587
|
+
"default": "false"
|
|
4588
|
+
},
|
|
4589
|
+
{
|
|
4590
|
+
"name": "fit-markers",
|
|
4591
|
+
"description": "If set, the map will automatically zoom so it can fit all the markers",
|
|
4592
|
+
"type": "boolean",
|
|
4593
|
+
"default": "false"
|
|
4594
|
+
},
|
|
4550
4595
|
{
|
|
4551
4596
|
"name": "subscribe",
|
|
4552
4597
|
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
@@ -4636,6 +4681,20 @@
|
|
|
4636
4681
|
"type": "boolean",
|
|
4637
4682
|
"default": "false"
|
|
4638
4683
|
},
|
|
4684
|
+
{
|
|
4685
|
+
"name": "cluster",
|
|
4686
|
+
"attribute": "cluster",
|
|
4687
|
+
"description": "If set, combine markers into clusters if they are located too close together\nto display as single markers",
|
|
4688
|
+
"type": "boolean",
|
|
4689
|
+
"default": "false"
|
|
4690
|
+
},
|
|
4691
|
+
{
|
|
4692
|
+
"name": "fitMarkers",
|
|
4693
|
+
"attribute": "fit-markers",
|
|
4694
|
+
"description": "If set, the map will automatically zoom so it can fit all the markers",
|
|
4695
|
+
"type": "boolean",
|
|
4696
|
+
"default": "false"
|
|
4697
|
+
},
|
|
4639
4698
|
{
|
|
4640
4699
|
"name": "subscribe",
|
|
4641
4700
|
"attribute": "subscribe",
|
|
@@ -8841,6 +8900,136 @@
|
|
|
8841
8900
|
}
|
|
8842
8901
|
]
|
|
8843
8902
|
},
|
|
8903
|
+
{
|
|
8904
|
+
"name": "pb-split-list",
|
|
8905
|
+
"path": "./src/pb-split-list.js",
|
|
8906
|
+
"description": "Implements a list which is split into different categories \n(e.g. letters of the alphabet, countries ...).\nOnly one category is shown at a time unless the server reports\nno categories (e.g. if the number of items to display goes below\na defined threshold).\n\nThe server-side API endpoint should return a JSON object with two\nproperties:\n\n+ `categories`: an array of category descriptions: each item should \n be an object with two properties: `category` - containing the name of the category\n and `count` - containing a count of items available under this category.\n+ `items`: an array with the items to be shown for the currently selected\n category. Those may contain HTML markup.",
|
|
8907
|
+
"attributes": [
|
|
8908
|
+
{
|
|
8909
|
+
"name": "url",
|
|
8910
|
+
"description": "Server-side API endpoint to retrieve items from",
|
|
8911
|
+
"type": "string"
|
|
8912
|
+
},
|
|
8913
|
+
{
|
|
8914
|
+
"name": "selected",
|
|
8915
|
+
"description": "The initially selected category",
|
|
8916
|
+
"type": "string"
|
|
8917
|
+
},
|
|
8918
|
+
{
|
|
8919
|
+
"name": "subforms",
|
|
8920
|
+
"description": "A CSS selector pointing to one or more `pb-custom-form`\ninstances. The element will collect additional parameters\nfrom those forms and includes them in the request to the server",
|
|
8921
|
+
"type": "string"
|
|
8922
|
+
},
|
|
8923
|
+
{
|
|
8924
|
+
"name": "subscribe",
|
|
8925
|
+
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
8926
|
+
"type": "string"
|
|
8927
|
+
},
|
|
8928
|
+
{
|
|
8929
|
+
"name": "subscribe-config",
|
|
8930
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
|
|
8931
|
+
"type": "object"
|
|
8932
|
+
},
|
|
8933
|
+
{
|
|
8934
|
+
"name": "emit",
|
|
8935
|
+
"description": "The name of the channel to send events to.",
|
|
8936
|
+
"type": "string"
|
|
8937
|
+
},
|
|
8938
|
+
{
|
|
8939
|
+
"name": "emit-config",
|
|
8940
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
|
|
8941
|
+
"type": "object"
|
|
8942
|
+
},
|
|
8943
|
+
{
|
|
8944
|
+
"name": "wait-for",
|
|
8945
|
+
"description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
|
|
8946
|
+
"type": "string"
|
|
8947
|
+
},
|
|
8948
|
+
{
|
|
8949
|
+
"name": "disabled",
|
|
8950
|
+
"description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
|
|
8951
|
+
"type": "boolean",
|
|
8952
|
+
"default": "false"
|
|
8953
|
+
}
|
|
8954
|
+
],
|
|
8955
|
+
"properties": [
|
|
8956
|
+
{
|
|
8957
|
+
"name": "url",
|
|
8958
|
+
"attribute": "url",
|
|
8959
|
+
"description": "Server-side API endpoint to retrieve items from",
|
|
8960
|
+
"type": "string"
|
|
8961
|
+
},
|
|
8962
|
+
{
|
|
8963
|
+
"name": "selected",
|
|
8964
|
+
"attribute": "selected",
|
|
8965
|
+
"description": "The initially selected category",
|
|
8966
|
+
"type": "string"
|
|
8967
|
+
},
|
|
8968
|
+
{
|
|
8969
|
+
"name": "subforms",
|
|
8970
|
+
"attribute": "subforms",
|
|
8971
|
+
"description": "A CSS selector pointing to one or more `pb-custom-form`\ninstances. The element will collect additional parameters\nfrom those forms and includes them in the request to the server",
|
|
8972
|
+
"type": "string"
|
|
8973
|
+
},
|
|
8974
|
+
{
|
|
8975
|
+
"name": "subscribe",
|
|
8976
|
+
"attribute": "subscribe",
|
|
8977
|
+
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
8978
|
+
"type": "string"
|
|
8979
|
+
},
|
|
8980
|
+
{
|
|
8981
|
+
"name": "subscribeConfig",
|
|
8982
|
+
"attribute": "subscribe-config",
|
|
8983
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
|
|
8984
|
+
"type": "object"
|
|
8985
|
+
},
|
|
8986
|
+
{
|
|
8987
|
+
"name": "emit",
|
|
8988
|
+
"attribute": "emit",
|
|
8989
|
+
"description": "The name of the channel to send events to.",
|
|
8990
|
+
"type": "string"
|
|
8991
|
+
},
|
|
8992
|
+
{
|
|
8993
|
+
"name": "emitConfig",
|
|
8994
|
+
"attribute": "emit-config",
|
|
8995
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
|
|
8996
|
+
"type": "object"
|
|
8997
|
+
},
|
|
8998
|
+
{
|
|
8999
|
+
"name": "waitFor",
|
|
9000
|
+
"attribute": "wait-for",
|
|
9001
|
+
"description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
|
|
9002
|
+
"type": "string"
|
|
9003
|
+
},
|
|
9004
|
+
{
|
|
9005
|
+
"name": "disabled",
|
|
9006
|
+
"attribute": "disabled",
|
|
9007
|
+
"description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
|
|
9008
|
+
"type": "boolean",
|
|
9009
|
+
"default": "false"
|
|
9010
|
+
}
|
|
9011
|
+
],
|
|
9012
|
+
"events": [
|
|
9013
|
+
{
|
|
9014
|
+
"name": "pb-submit",
|
|
9015
|
+
"description": "when received, submit a request to the server and refresh"
|
|
9016
|
+
},
|
|
9017
|
+
{
|
|
9018
|
+
"name": "pb-start-update",
|
|
9019
|
+
"description": "sent before the element sends the request to the server"
|
|
9020
|
+
},
|
|
9021
|
+
{
|
|
9022
|
+
"name": "pb-end-update",
|
|
9023
|
+
"description": "sent after new content has been received"
|
|
9024
|
+
}
|
|
9025
|
+
],
|
|
9026
|
+
"cssProperties": [
|
|
9027
|
+
{
|
|
9028
|
+
"name": "--pb-categorized-list-columns",
|
|
9029
|
+
"description": "the number of columns to display (default: 2)"
|
|
9030
|
+
}
|
|
9031
|
+
]
|
|
9032
|
+
},
|
|
8844
9033
|
{
|
|
8845
9034
|
"name": "pb-svg",
|
|
8846
9035
|
"path": "./src/pb-svg.js",
|
package/src/pb-components.js
CHANGED
|
@@ -57,6 +57,7 @@ import './pb-message.js';
|
|
|
57
57
|
import './pb-blacklab-results.js';
|
|
58
58
|
import './pb-blacklab-highlight.js';
|
|
59
59
|
import './pb-table-grid.js';
|
|
60
|
+
import './pb-split-list.js';
|
|
60
61
|
|
|
61
62
|
import '@polymer/iron-icons/editor-icons';
|
|
62
63
|
import '@polymer/iron-icons/social-icons';
|
package/src/pb-custom-form.js
CHANGED
|
@@ -7,14 +7,16 @@ import { PbLoad } from './pb-load.js';
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* A custom form element which loads the actual form from a server-side script using AJAX.
|
|
10
|
-
* Emits
|
|
11
|
-
*
|
|
10
|
+
* Emits `pb-search-resubmit` and `pb-submit` events, signalling the receiver that it should
|
|
11
|
+
* refresh.
|
|
12
12
|
*
|
|
13
|
-
* The component is currently used to implement the additional search facets on the start
|
|
14
|
-
* search result page.
|
|
13
|
+
* The component is currently used to implement the additional search facets on the start and
|
|
14
|
+
* search result page. It can also be combined with `pb-split-list` to contain an additional form
|
|
15
|
+
* with options.
|
|
15
16
|
*
|
|
16
|
-
* @
|
|
17
|
-
* @
|
|
17
|
+
* @fires pb-custom-form-loaded - Fired before the element updates its content
|
|
18
|
+
* @fires pb-search-resubmit - Fired when the form is submitted
|
|
19
|
+
* @fires pb-submit - Fired when the form is submitted
|
|
18
20
|
*/
|
|
19
21
|
export class PbCustomForm extends PbLoad {
|
|
20
22
|
|
|
@@ -34,6 +36,8 @@ export class PbCustomForm extends PbLoad {
|
|
|
34
36
|
this._reset();
|
|
35
37
|
}
|
|
36
38
|
});
|
|
39
|
+
|
|
40
|
+
this._submissionHandlers();
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
render() {
|
|
@@ -81,7 +85,8 @@ export class PbCustomForm extends PbLoad {
|
|
|
81
85
|
|
|
82
86
|
_submit() {
|
|
83
87
|
const json = this.serializeForm();
|
|
84
|
-
this.emitTo('pb-search-resubmit', {
|
|
88
|
+
this.emitTo('pb-search-resubmit', { params: json });
|
|
89
|
+
this.emitTo('pb-submit', { params: json});
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
_reset(){
|
|
@@ -102,6 +107,43 @@ export class PbCustomForm extends PbLoad {
|
|
|
102
107
|
this.dispatchEvent(new CustomEvent('pb-custom-form-loaded', { detail: content }));
|
|
103
108
|
}
|
|
104
109
|
|
|
110
|
+
_submissionHandlers() {
|
|
111
|
+
if (!this.autoSubmit) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.querySelectorAll(this.autoSubmit).forEach((control) => {
|
|
115
|
+
const name = control.nodeName.toLowerCase();
|
|
116
|
+
let event = 'change';
|
|
117
|
+
if (control instanceof HTMLButtonElement ||
|
|
118
|
+
name === 'paper-icon-button' || name === 'paper-button' ||
|
|
119
|
+
(name === 'input' && (control.type === 'button' || control.type === 'submit' || control.type === 'reset'))
|
|
120
|
+
) {
|
|
121
|
+
event = 'click';
|
|
122
|
+
} else if (name === 'paper-input' || (control instanceof HTMLInputElement && control.type === 'text')) {
|
|
123
|
+
event = 'keyup';
|
|
124
|
+
} else if (name === 'paper-dropdown-menu') {
|
|
125
|
+
event = 'value-changed';
|
|
126
|
+
}
|
|
127
|
+
control.addEventListener(event, this._submit.bind(this));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static get properties() {
|
|
132
|
+
return {
|
|
133
|
+
/**
|
|
134
|
+
* Register event handlers on all inputs and submit the form
|
|
135
|
+
* automatically if any of those changes. For button-like controls,
|
|
136
|
+
* a submit is triggered on click, for text input on keyUp, and for
|
|
137
|
+
* all other form components on change.
|
|
138
|
+
*/
|
|
139
|
+
autoSubmit: {
|
|
140
|
+
type: String,
|
|
141
|
+
attribute: 'auto-submit'
|
|
142
|
+
},
|
|
143
|
+
...super.properties
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
105
147
|
/**
|
|
106
148
|
* Fired before the element updates its content
|
|
107
149
|
*
|
package/src/pb-geolocation.js
CHANGED
|
@@ -32,6 +32,14 @@ export class PbGeolocation extends PbHighlight {
|
|
|
32
32
|
},
|
|
33
33
|
event: {
|
|
34
34
|
type: String
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* If set, add location to a map automatically upon load by
|
|
38
|
+
* emitting an event. If not set, locations are only added when
|
|
39
|
+
* the configured event is triggered.
|
|
40
|
+
*/
|
|
41
|
+
auto: {
|
|
42
|
+
type: Boolean
|
|
35
43
|
}
|
|
36
44
|
};
|
|
37
45
|
}
|
|
@@ -39,22 +47,39 @@ export class PbGeolocation extends PbHighlight {
|
|
|
39
47
|
constructor() {
|
|
40
48
|
super();
|
|
41
49
|
this.event = 'mouseover';
|
|
50
|
+
this.auto = false;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
connectedCallback() {
|
|
45
54
|
super.connectedCallback();
|
|
46
55
|
|
|
47
|
-
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
if (this.event) {
|
|
57
|
+
this.addEventListener(this.event, () =>
|
|
58
|
+
this.emitTo('pb-geolocation', {
|
|
59
|
+
coordinates: {
|
|
60
|
+
latitude: this.latitude,
|
|
61
|
+
longitude: this.longitude
|
|
62
|
+
},
|
|
63
|
+
label: this.label,
|
|
64
|
+
popup: this.popup,
|
|
65
|
+
element: this
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (this.auto) {
|
|
70
|
+
this.waitForChannel(() => {
|
|
71
|
+
this.emitTo('pb-geolocation', {
|
|
72
|
+
coordinates: {
|
|
73
|
+
latitude: this.latitude,
|
|
74
|
+
longitude: this.longitude
|
|
75
|
+
},
|
|
76
|
+
label: this.label,
|
|
77
|
+
popup: this.popup,
|
|
78
|
+
fitBounds: true,
|
|
79
|
+
element: this
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
58
83
|
}
|
|
59
84
|
|
|
60
85
|
render() {
|
package/src/pb-leaflet-map.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, css } from 'lit-element';
|
|
2
|
-
import
|
|
2
|
+
import "@lrnwebcomponents/es-global-bridge";
|
|
3
3
|
import { pbMixin } from './pb-mixin.js';
|
|
4
4
|
import { resolveURL } from './utils.js';
|
|
5
5
|
import './pb-map-layer.js';
|
|
@@ -12,7 +12,6 @@ import './pb-map-layer.js';
|
|
|
12
12
|
* @fires pb-update-map - When received, redraws the map to fit markers passed in with the event
|
|
13
13
|
* @fires pb-update - When received, redraws the map to show markers for all pb-geolocation elements
|
|
14
14
|
* @fires pb-geolocation - When received, focuses the map on the geocoordinates passed in with the event
|
|
15
|
-
|
|
16
15
|
*/
|
|
17
16
|
export class PbLeafletMap extends pbMixin(LitElement) {
|
|
18
17
|
static get properties() {
|
|
@@ -30,6 +29,20 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
30
29
|
crs: {
|
|
31
30
|
type: String
|
|
32
31
|
},
|
|
32
|
+
/**
|
|
33
|
+
* If set, the map will automatically zoom so it can fit all the markers
|
|
34
|
+
*/
|
|
35
|
+
fitMarkers: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
attribute: 'fit-markers'
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* If set, combine markers into clusters if they are located too close together
|
|
41
|
+
* to display as single markers
|
|
42
|
+
*/
|
|
43
|
+
cluster: {
|
|
44
|
+
type: Boolean
|
|
45
|
+
},
|
|
33
46
|
/**
|
|
34
47
|
* If enabled, the map will not automatically scroll to the coordinates received via `pb-geolocation`
|
|
35
48
|
*/
|
|
@@ -74,6 +87,8 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
74
87
|
this.toggle = false;
|
|
75
88
|
this.noScroll = false;
|
|
76
89
|
this.disabled = true;
|
|
90
|
+
this.cluster = false;
|
|
91
|
+
this.fitMarkers = false;
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
connectedCallback() {
|
|
@@ -86,7 +101,8 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
86
101
|
* @param {{ detail: any[]; }} ev
|
|
87
102
|
*/
|
|
88
103
|
this.subscribeTo('pb-update-map', (ev) => {
|
|
89
|
-
|
|
104
|
+
this._markerLayer.clearLayers();
|
|
105
|
+
|
|
90
106
|
/**
|
|
91
107
|
* @param {{ latitude: any; longitude: any; label: any; }} loc
|
|
92
108
|
*/
|
|
@@ -102,14 +118,9 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
102
118
|
this.emitTo('pb-leaflet-marker-click', loc);
|
|
103
119
|
});
|
|
104
120
|
marker.bindTooltip(loc.label);
|
|
105
|
-
|
|
106
|
-
bounds.extend([loc.latitude, loc.longitude]);
|
|
121
|
+
this._markerLayer.addLayer(marker);
|
|
107
122
|
});
|
|
108
|
-
|
|
109
|
-
this._map.fitBounds(bounds);
|
|
110
|
-
} else {
|
|
111
|
-
this._map.setZoom(this.zoom);
|
|
112
|
-
}
|
|
123
|
+
this._fitBounds();
|
|
113
124
|
});
|
|
114
125
|
|
|
115
126
|
/**
|
|
@@ -118,20 +129,14 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
118
129
|
* @param {{ detail: { root: { querySelectorAll: (arg0: string) => any[]; }; }; }} ev
|
|
119
130
|
*/
|
|
120
131
|
this.subscribeTo('pb-update', (ev) => {
|
|
121
|
-
this.
|
|
122
|
-
if (layer instanceof L.Marker) {
|
|
123
|
-
layer.remove();
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
const bounds = L.latLngBounds();
|
|
132
|
+
this._markerLayer.clearLayers();
|
|
127
133
|
const locations = ev.detail.root.querySelectorAll('pb-geolocation');
|
|
128
134
|
/**
|
|
129
135
|
* @param {{ latitude: any; longitude: any; }} loc
|
|
130
136
|
*/
|
|
131
137
|
locations.forEach((loc) => {
|
|
132
138
|
const coords = L.latLng(loc.latitude, loc.longitude);
|
|
133
|
-
|
|
134
|
-
const marker = L.marker(coords).addTo(this._map);
|
|
139
|
+
const marker = L.marker(coords).addTo(this._markerLayer);
|
|
135
140
|
if (loc.label) {
|
|
136
141
|
marker.bindTooltip(loc.label);
|
|
137
142
|
}
|
|
@@ -142,12 +147,7 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
142
147
|
this.emitTo('pb-leaflet-marker-click', loc);
|
|
143
148
|
});
|
|
144
149
|
});
|
|
145
|
-
|
|
146
|
-
if (locations.length > 1) {
|
|
147
|
-
this._map.fitBounds(bounds);
|
|
148
|
-
} else {
|
|
149
|
-
this._map.fitWorld();
|
|
150
|
-
}
|
|
150
|
+
this._fitBounds();
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
/**
|
|
@@ -170,7 +170,12 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
170
170
|
if (ev.detail.popup) {
|
|
171
171
|
marker.bindPopup(ev.detail.popup);
|
|
172
172
|
}
|
|
173
|
-
marker.addTo(this.
|
|
173
|
+
marker.addTo(this._markerLayer);
|
|
174
|
+
|
|
175
|
+
if (ev.detail.fitBounds) {
|
|
176
|
+
this._fitBounds();
|
|
177
|
+
}
|
|
178
|
+
|
|
174
179
|
console.log('<pb-leaflet-map> added marker');
|
|
175
180
|
} else {
|
|
176
181
|
console.log('<pb-leaflet-map> Marker already added to map');
|
|
@@ -178,7 +183,7 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
178
183
|
if (this.toggle) {
|
|
179
184
|
this.disabled = false;
|
|
180
185
|
}
|
|
181
|
-
this._locationChanged();
|
|
186
|
+
this._locationChanged(this.latitude, this.longitude);
|
|
182
187
|
}
|
|
183
188
|
});
|
|
184
189
|
}
|
|
@@ -187,13 +192,23 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
187
192
|
if (!this.toggle) {
|
|
188
193
|
this.disabled = false;
|
|
189
194
|
}
|
|
190
|
-
|
|
195
|
+
window.ESGlobalBridge.requestAvailability();
|
|
196
|
+
const leafletPath = resolveURL('../lib/leaflet-src.js');
|
|
197
|
+
const pluginPath = resolveURL('../lib/leaflet.markercluster-src.js');
|
|
198
|
+
window.ESGlobalBridge.instance.load("leaflet", leafletPath)
|
|
199
|
+
.then(() => window.ESGlobalBridge.instance.load("plugin", pluginPath));
|
|
200
|
+
window.addEventListener(
|
|
201
|
+
"es-bridge-plugin-loaded",
|
|
202
|
+
this._initMap.bind(this),
|
|
203
|
+
{ once: true }
|
|
204
|
+
);
|
|
191
205
|
}
|
|
192
206
|
|
|
193
207
|
render() {
|
|
194
208
|
const cssPath = resolveURL(this.cssPath);
|
|
195
209
|
return html`
|
|
196
210
|
<link rel="Stylesheet" href="${cssPath}/leaflet.css">
|
|
211
|
+
<link rel="Stylesheet" href="${cssPath}/MarkerCluster.Default.css">
|
|
197
212
|
<div id="map" style="height: 100%; width: 100%"></div>
|
|
198
213
|
`;
|
|
199
214
|
}
|
|
@@ -235,6 +250,14 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
235
250
|
crs
|
|
236
251
|
});
|
|
237
252
|
this._configureLayers();
|
|
253
|
+
|
|
254
|
+
if (this.cluster) {
|
|
255
|
+
this._markerLayer = L.markerClusterGroup();
|
|
256
|
+
} else {
|
|
257
|
+
this._markerLayer = L.layerGroup();
|
|
258
|
+
}
|
|
259
|
+
this._markerLayer.addTo(this._map);
|
|
260
|
+
|
|
238
261
|
this.signalReady();
|
|
239
262
|
|
|
240
263
|
L.control.scale().addTo(this._map);
|
|
@@ -309,16 +332,31 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
309
332
|
}
|
|
310
333
|
}
|
|
311
334
|
|
|
312
|
-
|
|
335
|
+
_fitBounds() {
|
|
336
|
+
if (!this.fitMarkers) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const bounds = L.latLngBounds();
|
|
340
|
+
let len = 0;
|
|
341
|
+
this._markerLayer.eachLayer((layer) => {
|
|
342
|
+
bounds.extend(layer.getLatLng());
|
|
343
|
+
len += 1;
|
|
344
|
+
});
|
|
345
|
+
if (len === 0) {
|
|
346
|
+
this._map.fitWorld();
|
|
347
|
+
} else if (len === 1) {
|
|
348
|
+
this._map.fitBounds(bounds, {maxZoom: this.zoom});
|
|
349
|
+
} else {
|
|
350
|
+
this._map.fitBounds(bounds);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
_locationChanged(lat, long) {
|
|
313
355
|
if (this._map) {
|
|
314
|
-
const coords = L.latLng([
|
|
315
|
-
this.
|
|
316
|
-
if (layer
|
|
317
|
-
|
|
318
|
-
layer.openTooltip();
|
|
319
|
-
} else {
|
|
320
|
-
layer.closeTooltip();
|
|
321
|
-
}
|
|
356
|
+
const coords = L.latLng([lat, long]);
|
|
357
|
+
this._markerLayer.eachLayer((layer) => {
|
|
358
|
+
if (layer.getLatLng().equals(coords)) {
|
|
359
|
+
layer.openTooltip();
|
|
322
360
|
}
|
|
323
361
|
});
|
|
324
362
|
if (!this.noScroll)
|
|
@@ -329,7 +367,7 @@ export class PbLeafletMap extends pbMixin(LitElement) {
|
|
|
329
367
|
_hasMarker(lat, long) {
|
|
330
368
|
const coords = L.latLng([lat, long]);
|
|
331
369
|
let found = false;
|
|
332
|
-
this.
|
|
370
|
+
this._markerLayer.eachLayer((layer) => {
|
|
333
371
|
if (layer instanceof L.Marker && layer.getLatLng().equals(coords)) {
|
|
334
372
|
found = true;
|
|
335
373
|
}
|
package/src/pb-select-feature.js
CHANGED