PageSourceSearch

https://www.endangeredalphabets.net/wp-content/plugins/wp-google-m…?ver=10.1.08%2Bpro-10.1.05

js endangeredalphabets.net collected 2026-10-02 06:10:51 UTC 8,230 bytes, 258 lines download raw bytes

1/**
2 * @namespace WPGMZA
3 * @module OLTextOverlay
4 * @requires WPGMZA.OLText
5 */
6jQuery(function($) {
7
8	WPGMZA.OLTextOverlay = function(options){
9		if(!options.position || !options.map) {
10			return;
11		}
12
13		this.element = $("<div class='wpgmza-ol-text-overlay-wrapper" + (options.class ? ` ${options.class}` : '') + "'></div>")[0];
14
15		this.styleOptions = (!options) ? {} : options;
16		this.map = options.map;
17
18		this.offsetX = parseFloat(options.offsetX) || 0;
19		this.offsetY = parseFloat(options.offsetY) || 0;
20
21		/* "top-left" pins the element's own top-left corner at the projected pixel with no
22		 * measurement of any kind on OL's part - centering AND the user-configurable offset
23		 * are both applied ourselves as a single CSS transform on this.element (see
24		 * setOffset()), exactly like GoogleTextOverlay does on .wpgmza-inner. OL's own
25		 * "center-center" positioning was tried first, but unlike Leaflet/Google (which
26		 * center via a self-referential CSS percentage transform, unaffected by content
27		 * size or timing) OL centers via a JS-measured pixel margin - which didn't track
28		 * correctly here. Doing it ourselves in pure CSS sidesteps that entirely. */
29		this.olOverlay = new ol.Overlay({
30			element : this.element,
31			position : ol.proj.fromLonLat([options.position.lng, options.position.lat]),
32			positioning : "top-left",
33			stopEvent : false
34		});
35
36		this.applyTransform();
37
38		this.map.olMap.addOverlay(this.olOverlay);
39
40		this.refresh();
41	}
42
43	WPGMZA.OLTextOverlay.prototype.getStyle = function(){
44		let defaults = {
45			fontSize : 11,
46			fillColor : "#000000",
47			strokeColor : "#ffffff"
48		};
49
50		for(let i in defaults){
51			if(typeof this.styleOptions[i] === 'undefined'){
52				this.styleOptions[i] = defaults[i]
53			}
54		}
55
56        let labelStyles = [];
57        labelStyles.push("width: fit-content");
58        labelStyles.push("font: bold " + this.styleOptions.fontSize + "px \"Open Sans\", \"Arial Unicode MS\", \"sans-serif\"");
59        labelStyles.push("color: " + this.styleOptions.fillColor);
60        labelStyles.push("z-index: 10");
61        labelStyles.push("text-shadow: -1px -1px 0 " + this.styleOptions.strokeColor + ", 1px -1px 0 " + this.styleOptions.strokeColor + ", -1px 1px 0 " + this.styleOptions.strokeColor + ", 1px 1px 0 " + this.styleOptions.strokeColor);
62
63        if(this.styleOptions.opacity){
64            labelStyles.push("opacity: " + this.styleOptions.opacity);
65        }
66
67		return labelStyles.join('; ');
68	}
69
70	WPGMZA.OLTextOverlay.prototype.refresh = function(){
71		if(!this.styleOptions){ return; }
72		this.setText(this.styleOptions.text);
73	}
74
75	/**
76	 * Applies centering plus the user-configurable offset as ONE CSS transform on
77	 * this.element itself - translate(-50%,-50%) centers the element on the point (a
78	 * self-referential percentage, always correct regardless of the element's actual
79	 * rendered size, with no measurement needed), composed with a further translate(X%,Y%)
80	 * for the offset, which is a percentage of that same box - so "100%" always means
81	 * "shifted by one full label width/height", however long the title/subheading gets.
82	 * Not a pixel offset baked into a nudged lat/lng either - that only holds true at the
83	 * zoom level it was computed at, and would drift away from whatever this label is
84	 * meant to stay anchored next to (e.g. its owning marker) as soon as the map zoomed.
85	 *
86	 * @return void
87	 */
88	WPGMZA.OLTextOverlay.prototype.applyTransform = function(){
89		if(this.element){
90			$(this.element).css('transform', 'translate(-50%, -50%) translate(' + (this.offsetX || 0) + '%, ' + (this.offsetY || 0) + '%)');
91		}
92	}
93
94	/**
95	 * @param number x
96	 * @param number y
97	 *
98	 * @return void
99	 */
100	WPGMZA.OLTextOverlay.prototype.setOffset = function(x, y){
101		this.offsetX = parseFloat(x) || 0;
102		this.offsetY = parseFloat(y) || 0;
103
104		this.applyTransform();
105	}
106
107	/**
108	 * Stores the owning marker (only ever set for a marker-owned label, never a standalone
109	 * Point Label) and (re)applies click-to-select behaviour, gated behind the
110	 * marker_label_click_opens_infowindow map setting. Bound directly on this.element,
111	 * which OL never recreates itself. pointer-events is overridden here too, since the
112	 * wrapper is pointer-events:none by default (see open-layers.css) s
112o clicks reach the
113	 * map underneath when this is off.
114	 *
115	 * A real marker click dispatches a "select" event on the WPGMZA.Marker instance itself
116	 * (see WPGMZA.Marker.prototype.onSelect), which is what actually opens the info
117	 * window, so this reuses that same path rather than reimplementing it.
118	 *
119	 * @param WPGMZA.Marker|undefined marker
120	 *
121	 * @return void
122	 */
123	WPGMZA.OLTextOverlay.prototype.setMarker = function(marker){
124		this.marker = marker;
125
126		if(!this.element){ return; }
127
128		var self = this;
129		var clickable = !!(this.marker && this.marker.map && this.marker.map.settings && this.marker.map.settings.marker_label_click_opens_infowindow);
130
131		$(this.element).css('pointer-events', clickable ? 'auto' : '');
132		$(this.element).off('click.wpgmzaLabelSelect');
133
134		if(clickable){
135			$(this.element).on('click.wpgmzaLabelSelect', function(event){
136				event.stopPropagation();
137				self.marker.dispatchEvent("select");
138			});
139		}
140	}
141
142	WPGMZA.OLTextOverlay.prototype.setPosition = function(position){
143		if(this.olOverlay){
144			this.olOverlay.setPosition(ol.proj.fromLonLat([
145				parseFloat(position.lng),
146				parseFloat(position.lat)
147			]));
148		}
149	}
150
151	WPGMZA.OLTextOverlay.prototype.setText = function(text){
152		if(!this.styleOptions){ return; }
153
154		if(text){
155        	this.styleOptions.text = text;
156		}
157
158		if(this.element){
159			$(this.element).html(`<div class='wpgmza-ol-text-overlay' style='${this.getStyle()}'>${this.styleOptions.text || ''}</div>`);
160        }
161	}
162
163	/**
164	 * Builds the card element - title, optional subheading, optional icon. Colors/background/border/
165	 * font size come entirely from the --wpgmza-component-* CSS vars (see components.css), not
166	 * fillColor/lineColor/fontSize - those fields are hidden in the editor for card style. Opacity
167	 * still applies since that remains relevant either way
168	 *
169	 * @return jQuery
170	 */
171	WPGMZA.OLTextOverlay.prototype.getCardElement = function(){
172		const content = this.cardContent || {};
173		const card = $("<div class='wpgmza-text-overlay-card'></div>");
174
175		if(typeof this.styleOptions.opacity !== 'undefined'){
176			card.css('opacity', this.styleOptions.opacity);
177		}
178
179		if(content.icon){
180			card.append($("<img class='wpgmza-text-overlay-card-icon'/>").attr('src', content.icon));
181		}
182
183		const textWrapper = $("<div class='wpgmza-text-overlay-card-content'></div>");
184		textWrapper.append($("<div class='wpgmza-text-overlay-card-title'></div>").text(content.title || ''));
185
186		if(content.subText){
187			textWrapper.append($("<div class='wpgmza-text-overlay-card-subtext'></div>").text(content.subText));
188		}
189
190		card.append(textWrapper);
191
192		return card;
193	}
194
195	WPGMZA.OLTextOverlay.prototype.setCardContent = function(content){
196		if(!this.styleOptions){ return; }
197
198		this.cardContent = content || {};
199
200		if(this.element){
201			$(this.element).empty().append(this.getCardElement());
202		}
203	}
204
205	WPGMZA.OLTextOverlay.prototype.setFontSize = function(size){
206		if(!this.styleOptions){ return; }
207
208		size = parseInt(size);
209		this.styleOptions.fontSize = size;
210	}
211
212	WPGMZA.OLTextOverlay.prototype.setFillColor = function(color){
213		if(!this.styleOptions){ return; }
214
215		if(!color.match(/^#/))
216			color = "#" + color;
217
218
219		this.styleOptions.fillColor = color;
220	}
221
222	WPGMZA.OLTextOverlay.prototype.setLineColor = function(color){
223		if(!this.styleOptions){ return; }
224
225		if(!color.match(/^#/))
226			color = "#" + color;
227
228		this.styleOptions.strokeColor = color
229	}
230
231	WPGMZA.OLTextOverlay.prototype.setOpacity = function(opacity){
232		if(!this.styleOptions){ return; }
233
234		opacity = parseFloat(opacity);
235
236		if(opacity > 1){
237			opacity = 1;
238		} else if (opacity < 0){
239			opacity = 0;
240		}
241
242        this.styleOptions.opacity = opacity;
243	}
244
245	WPGMZA.OLTextOverlay.prototype.setZIndex = function(zIndex){
246		if(this.element){
247			$(this.element).css('z-index', zIndex);
248		}
249	}
250
251
252	WPGMZA.OLTextOverlay.prototype.remove = function(){
253		if(this.olOverlay && this.map && this.map.olMap){
254        	this.map.olMap.removeOverlay(this.olOverlay);
255		}
256	}
257
258});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.