leaflet-draw-tooltips 1.0.0 → 1.0.2

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * leaflet-draw-tooltips v1.0.0
2
+ * leaflet-draw-tooltips v1.0.2
3
3
  * External tooltip plugin for Leaflet.draw - move drawing hints outside the map
4
4
  * @license MIT
5
5
  * @copyright (c) 2025
@@ -88,23 +88,31 @@ class ExternalCardTooltip {
88
88
  * 创建内部 DOM 结构
89
89
  */
90
90
  _setupDOM() {
91
- // 清空容器
92
- this.containerEl.innerHTML = '';
93
-
94
- // 创建主文本元素
95
- this.textEl = document.createElement('div');
96
- this.textEl.className = 'leaflet-draw-hint-text';
97
-
98
- // 创建副文本元素
99
- this.subtextEl = document.createElement('div');
100
- this.subtextEl.className = 'leaflet-draw-hint-subtext';
101
-
102
- // 添加到容器
103
- this.containerEl.appendChild(this.textEl);
104
- this.containerEl.appendChild(this.subtextEl);
105
-
106
- // 初始隐藏
107
- this.containerEl.style.display = 'none';
91
+ // 如果容器中已有预期的元素,则重用它们(避免被其它实例清空)
92
+ const existingText = this.containerEl.querySelector('.leaflet-draw-hint-text');
93
+ const existingSubtext = this.containerEl.querySelector('.leaflet-draw-hint-subtext');
94
+
95
+ if (existingText && existingSubtext) {
96
+ this.textEl = existingText;
97
+ this.subtextEl = existingSubtext;
98
+ } else {
99
+ // 创建主文本元素
100
+ this.textEl = document.createElement('div');
101
+ this.textEl.className = 'leaflet-draw-hint-text';
102
+
103
+ // 创建副文本元素
104
+ this.subtextEl = document.createElement('div');
105
+ this.subtextEl.className = 'leaflet-draw-hint-subtext';
106
+
107
+ // 如果容器为空或没有结构,则追加元素(但不盲目清空已有内容)
108
+ this.containerEl.appendChild(this.textEl);
109
+ this.containerEl.appendChild(this.subtextEl);
110
+ }
111
+
112
+ // 初始隐藏(如果尚未设置)
113
+ if (!this.containerEl.style.display) {
114
+ this.containerEl.style.display = 'none';
115
+ }
108
116
  }
109
117
 
110
118
  /**
@@ -182,14 +190,11 @@ class ExternalCardTooltip {
182
190
  // 清空 DOM 内容但不删除元素(外部容器需要保留)
183
191
  if (this.textEl) this.textEl.textContent = '';
184
192
  if (this.subtextEl) this.subtextEl.textContent = '';
185
-
193
+
186
194
  this._notifyUpdate();
187
-
188
- // 注意:不删除 DOM 元素,只清空引用
189
- // DOM 元素(containerEl)是外部传入的,应该保留在页面上
190
- this.containerEl = null;
191
- this.textEl = null;
192
- this.subtextEl = null;
195
+
196
+ // 注意:不删除 DOM 元素,也不清空对 DOM 的引用。
197
+ // containerEl 是外部传入的共享容器,保留引用以便其它实例或返回的 tooltip 继续可用。
193
198
  this.onUpdate = null;
194
199
  }
195
200
 
@@ -274,23 +279,28 @@ class ExternalCardTooltip {
274
279
  * @param {boolean} config.sanitize - 是否转义 HTML
275
280
  * @param {Function} config.onUpdate - 状态更新回调
276
281
  */
277
- function patchDrawTooltip(config) {
282
+ function patchDrawTooltip(configOrInstance) {
278
283
  if (typeof L === 'undefined' || !L.Draw || !L.Draw.Tooltip) {
279
284
  throw new Error('[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用');
280
285
  }
281
-
286
+
287
+ // 如果传入的是已有的 ExternalCardTooltip 实例,则复用;否则根据 config 创建一个共享实例
288
+ const sharedExternalTooltip =
289
+ configOrInstance && configOrInstance instanceof ExternalCardTooltip
290
+ ? configOrInstance
291
+ : new ExternalCardTooltip(configOrInstance || {});
292
+
282
293
  // 保存原始类(可选,用于调试)
283
294
  const OriginalTooltip = L.Draw.Tooltip;
284
-
295
+
285
296
  /**
286
297
  * 新的 L.Draw.Tooltip 适配器
287
- * 每次实例化时创建新的 ExternalCardTooltip
298
+ * 所有实例都共享同一个 ExternalCardTooltip
288
299
  */
289
300
  L.Draw.Tooltip = L.Class.extend({
290
301
  initialize: function(map) {
291
- // console.log('🆕 L.Draw.Tooltip 实例化,创建新的 ExternalCardTooltip');
292
- // 每次都创建新的实例
293
- this._externalTooltip = new ExternalCardTooltip(config);
302
+ // 复用共享实例
303
+ this._externalTooltip = sharedExternalTooltip;
294
304
  },
295
305
 
296
306
  /**
@@ -329,14 +339,25 @@ function patchDrawTooltip(config) {
329
339
  * 销毁
330
340
  */
331
341
  dispose: function() {
332
- this._externalTooltip.dispose();
342
+ // 不在此处 dispose 共享实例(以免被局部销毁)。
333
343
  return this;
344
+ },
345
+
346
+ /**
347
+ * 空实现,避免调用时报错
348
+ */
349
+ _onMouseOut: function() {
350
+ return;
334
351
  }
335
352
  });
336
353
 
337
354
  // 标记已替换(可用于调试)
338
355
  L.Draw.Tooltip._isPatched = true;
339
356
  L.Draw.Tooltip._originalClass = OriginalTooltip;
357
+ // 暴露共享实例以便调试或外部访问
358
+ L.Draw.Tooltip._sharedExternalTooltip = sharedExternalTooltip;
359
+
360
+ return sharedExternalTooltip;
340
361
  }
341
362
 
342
363
  /**
@@ -406,26 +427,24 @@ function installLeafletDrawExternalTooltip(options = {}) {
406
427
  }
407
428
  }
408
429
 
409
- // 4. 准备配置对象(不创建实例)
430
+ // 4. 准备配置对象并创建共享 ExternalCardTooltip 实例
410
431
  const tooltipConfig = {
411
432
  containerEl,
412
433
  sanitize,
413
434
  onUpdate
414
435
  };
415
-
416
- // 5. Runtime 替换 L.Draw.Tooltip(传递配置而非实例)
417
- patchDrawTooltip(tooltipConfig);
418
-
419
- // 6. 创建一个初始实例用于返回(供用户手动控制)
420
- const externalTooltip = new ExternalCardTooltip(tooltipConfig);
436
+
437
+ // 5. 创建共享实例并让 patch 使用该实例(避免绘制期间产生命名冲突/覆盖)
438
+ const sharedExternalTooltip = new ExternalCardTooltip(tooltipConfig);
439
+ patchDrawTooltip(sharedExternalTooltip);
421
440
 
422
441
  // 8. 返回清理函数和 tooltip 实例
423
442
  const cleanup = function() {
424
- // 清理用户手动控制的实例
425
- if (externalTooltip) {
426
- externalTooltip.dispose();
443
+ // 仅在卸载插件时彻底 dispose 共享实例
444
+ if (sharedExternalTooltip) {
445
+ sharedExternalTooltip.dispose();
427
446
  }
428
-
447
+
429
448
  if (hideMapTooltip) {
430
449
  const mapContainer = map.getContainer();
431
450
  if (mapContainer) {
@@ -433,10 +452,10 @@ function installLeafletDrawExternalTooltip(options = {}) {
433
452
  }
434
453
  }
435
454
  };
436
-
455
+
437
456
  return {
438
457
  cleanup,
439
- tooltip: externalTooltip
458
+ tooltip: sharedExternalTooltip
440
459
  };
441
460
  }
442
461
 
@@ -0,0 +1 @@
1
+ function t(t,e,i=!0){t&&(i?t.textContent=e||"":t.innerHTML=e||"")}class e{constructor({containerEl:t,sanitize:e=!0,onUpdate:i=null}){this.containerEl=t,this.sanitize=e,this.onUpdate=i,this._visible=!1,this._isError=!1,this._currentContent={text:"",subtext:""},this._setupDOM()}_setupDOM(){const t=this.containerEl.querySelector(".leaflet-draw-hint-text"),e=this.containerEl.querySelector(".leaflet-draw-hint-subtext");t&&e?(this.textEl=t,this.subtextEl=e):(this.textEl=document.createElement("div"),this.textEl.className="leaflet-draw-hint-text",this.subtextEl=document.createElement("div"),this.subtextEl.className="leaflet-draw-hint-subtext",this.containerEl.appendChild(this.textEl),this.containerEl.appendChild(this.subtextEl)),this.containerEl.style.display||(this.containerEl.style.display="none")}updateContent(e){if(!this.containerEl)return this;const{text:i="",subtext:n=""}=e||{};return this._currentContent={text:i,subtext:n},i||n?(t(this.textEl,i,this.sanitize),t(this.subtextEl,n,this.sanitize),this._show()):this._hide(),this._notifyUpdate(),this}updatePosition(t){return this}showAsError(){return this.containerEl?(this._isError=!0,this.containerEl.classList.add("is-error"),this._notifyUpdate(),this):this}removeError(){return this.containerEl?(this._isError=!1,this.containerEl.classList.remove("is-error"),this._notifyUpdate(),this):this}dispose(){this._hide(),this._currentContent={text:"",subtext:""},this.textEl&&(this.textEl.textContent=""),this.subtextEl&&(this.subtextEl.textContent=""),this._notifyUpdate(),this.onUpdate=null}_show(){this.containerEl&&(this._visible||(this._visible=!0,this.containerEl.style.display="block"))}_hide(){this.containerEl&&this._visible&&(this._visible=!1,this.containerEl.style.display="none",this.removeError())}_notifyUpdate(){"function"==typeof this.onUpdate&&this.onUpdate({...this._currentContent},{visible:this._visible,isError:this._isError})}}function i(t={}){const{map:i,el:n,hideMapTooltip:o=!0,sanitize:s=!0,onUpdate:r=null}=t;if(!i||"function"!=typeof i.on)throw new Error("[leaflet-draw-tooltip] options.map 必须是有效的 Leaflet Map 实例");if(!n)throw new Error("[leaflet-draw-tooltip] options.el 必须提供(HTMLElement 或选择器)");const l=function(t){if(t instanceof HTMLElement)return t;if("string"==typeof t){const e=document.querySelector(t);if(!e)throw new Error(`[leaflet-draw-tooltip] 找不到元素: ${t}`);return e}throw new Error("[leaflet-draw-tooltip] el 必须是 HTMLElement 或选择器字符串")}(n);if(o){const t=i.getContainer();t&&t.classList.add("leaflet-draw-tooltip-hide")}const a=new e({containerEl:l,sanitize:s,onUpdate:r});return function(t){if("undefined"==typeof L||!L.Draw||!L.Draw.Tooltip)throw new Error("[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用");const i=t&&t instanceof e?t:new e(t||{}),n=L.Draw.Tooltip;L.Draw.Tooltip=L.Class.extend({initialize:function(t){this._externalTooltip=i},updateContent:function(t){return this._externalTooltip.updateContent(t),this},updatePosition:function(t){return this._externalTooltip.updatePosition(t),this},showAsError:function(){return this._externalTooltip.showAsError(),this},removeError:function(){return this._externalTooltip.removeError(),this},dispose:function(){return this},_onMouseOut:function(){}}),L.Draw.Tooltip._isPatched=!0,L.Draw.Tooltip._originalClass=n,L.Draw.Tooltip._sharedExternalTooltip=i}(a),{cleanup:function(){if(a&&a.dispose(),o){const t=i.getContainer();t&&t.classList.remove("leaflet-draw-tooltip-hide")}},tooltip:a}}export{i as installLeafletDrawExternalTooltip};
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).LeafletDrawTooltip={})}(this,function(t){"use strict";function e(t,e,i=!0){t&&(i?t.textContent=e||"":t.innerHTML=e||"")}class i{constructor({containerEl:t,sanitize:e=!0,onUpdate:i=null}){this.containerEl=t,this.sanitize=e,this.onUpdate=i,this._visible=!1,this._isError=!1,this._currentContent={text:"",subtext:""},this._setupDOM()}_setupDOM(){const t=this.containerEl.querySelector(".leaflet-draw-hint-text"),e=this.containerEl.querySelector(".leaflet-draw-hint-subtext");t&&e?(this.textEl=t,this.subtextEl=e):(this.textEl=document.createElement("div"),this.textEl.className="leaflet-draw-hint-text",this.subtextEl=document.createElement("div"),this.subtextEl.className="leaflet-draw-hint-subtext",this.containerEl.appendChild(this.textEl),this.containerEl.appendChild(this.subtextEl)),this.containerEl.style.display||(this.containerEl.style.display="none")}updateContent(t){if(!this.containerEl)return this;const{text:i="",subtext:n=""}=t||{};return this._currentContent={text:i,subtext:n},i||n?(e(this.textEl,i,this.sanitize),e(this.subtextEl,n,this.sanitize),this._show()):this._hide(),this._notifyUpdate(),this}updatePosition(t){return this}showAsError(){return this.containerEl?(this._isError=!0,this.containerEl.classList.add("is-error"),this._notifyUpdate(),this):this}removeError(){return this.containerEl?(this._isError=!1,this.containerEl.classList.remove("is-error"),this._notifyUpdate(),this):this}dispose(){this._hide(),this._currentContent={text:"",subtext:""},this.textEl&&(this.textEl.textContent=""),this.subtextEl&&(this.subtextEl.textContent=""),this._notifyUpdate(),this.onUpdate=null}_show(){this.containerEl&&(this._visible||(this._visible=!0,this.containerEl.style.display="block"))}_hide(){this.containerEl&&this._visible&&(this._visible=!1,this.containerEl.style.display="none",this.removeError())}_notifyUpdate(){"function"==typeof this.onUpdate&&this.onUpdate({...this._currentContent},{visible:this._visible,isError:this._isError})}}t.installLeafletDrawExternalTooltip=function(t={}){const{map:e,el:n,hideMapTooltip:o=!0,sanitize:s=!0,onUpdate:r=null}=t;if(!e||"function"!=typeof e.on)throw new Error("[leaflet-draw-tooltip] options.map 必须是有效的 Leaflet Map 实例");if(!n)throw new Error("[leaflet-draw-tooltip] options.el 必须提供(HTMLElement 或选择器)");const l=function(t){if(t instanceof HTMLElement)return t;if("string"==typeof t){const e=document.querySelector(t);if(!e)throw new Error(`[leaflet-draw-tooltip] 找不到元素: ${t}`);return e}throw new Error("[leaflet-draw-tooltip] el 必须是 HTMLElement 或选择器字符串")}(n);if(o){const t=e.getContainer();t&&t.classList.add("leaflet-draw-tooltip-hide")}const a=new i({containerEl:l,sanitize:s,onUpdate:r});return function(t){if("undefined"==typeof L||!L.Draw||!L.Draw.Tooltip)throw new Error("[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用");const e=t&&t instanceof i?t:new i(t||{}),n=L.Draw.Tooltip;L.Draw.Tooltip=L.Class.extend({initialize:function(t){this._externalTooltip=e},updateContent:function(t){return this._externalTooltip.updateContent(t),this},updatePosition:function(t){return this._externalTooltip.updatePosition(t),this},showAsError:function(){return this._externalTooltip.showAsError(),this},removeError:function(){return this._externalTooltip.removeError(),this},dispose:function(){return this},_onMouseOut:function(){}}),L.Draw.Tooltip._isPatched=!0,L.Draw.Tooltip._originalClass=n,L.Draw.Tooltip._sharedExternalTooltip=e}(a),{cleanup:function(){if(a&&a.dispose(),o){const t=e.getContainer();t&&t.classList.remove("leaflet-draw-tooltip-hide")}},tooltip:a}}});
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * leaflet-draw-tooltips v1.0.0
2
+ * leaflet-draw-tooltips v1.0.2
3
3
  * External tooltip plugin for Leaflet.draw - move drawing hints outside the map
4
4
  * @license MIT
5
5
  * @copyright (c) 2025
@@ -94,23 +94,31 @@
94
94
  * 创建内部 DOM 结构
95
95
  */
96
96
  _setupDOM() {
97
- // 清空容器
98
- this.containerEl.innerHTML = '';
99
-
100
- // 创建主文本元素
101
- this.textEl = document.createElement('div');
102
- this.textEl.className = 'leaflet-draw-hint-text';
103
-
104
- // 创建副文本元素
105
- this.subtextEl = document.createElement('div');
106
- this.subtextEl.className = 'leaflet-draw-hint-subtext';
107
-
108
- // 添加到容器
109
- this.containerEl.appendChild(this.textEl);
110
- this.containerEl.appendChild(this.subtextEl);
111
-
112
- // 初始隐藏
113
- this.containerEl.style.display = 'none';
97
+ // 如果容器中已有预期的元素,则重用它们(避免被其它实例清空)
98
+ const existingText = this.containerEl.querySelector('.leaflet-draw-hint-text');
99
+ const existingSubtext = this.containerEl.querySelector('.leaflet-draw-hint-subtext');
100
+
101
+ if (existingText && existingSubtext) {
102
+ this.textEl = existingText;
103
+ this.subtextEl = existingSubtext;
104
+ } else {
105
+ // 创建主文本元素
106
+ this.textEl = document.createElement('div');
107
+ this.textEl.className = 'leaflet-draw-hint-text';
108
+
109
+ // 创建副文本元素
110
+ this.subtextEl = document.createElement('div');
111
+ this.subtextEl.className = 'leaflet-draw-hint-subtext';
112
+
113
+ // 如果容器为空或没有结构,则追加元素(但不盲目清空已有内容)
114
+ this.containerEl.appendChild(this.textEl);
115
+ this.containerEl.appendChild(this.subtextEl);
116
+ }
117
+
118
+ // 初始隐藏(如果尚未设置)
119
+ if (!this.containerEl.style.display) {
120
+ this.containerEl.style.display = 'none';
121
+ }
114
122
  }
115
123
 
116
124
  /**
@@ -188,14 +196,11 @@
188
196
  // 清空 DOM 内容但不删除元素(外部容器需要保留)
189
197
  if (this.textEl) this.textEl.textContent = '';
190
198
  if (this.subtextEl) this.subtextEl.textContent = '';
191
-
199
+
192
200
  this._notifyUpdate();
193
-
194
- // 注意:不删除 DOM 元素,只清空引用
195
- // DOM 元素(containerEl)是外部传入的,应该保留在页面上
196
- this.containerEl = null;
197
- this.textEl = null;
198
- this.subtextEl = null;
201
+
202
+ // 注意:不删除 DOM 元素,也不清空对 DOM 的引用。
203
+ // containerEl 是外部传入的共享容器,保留引用以便其它实例或返回的 tooltip 继续可用。
199
204
  this.onUpdate = null;
200
205
  }
201
206
 
@@ -280,23 +285,28 @@
280
285
  * @param {boolean} config.sanitize - 是否转义 HTML
281
286
  * @param {Function} config.onUpdate - 状态更新回调
282
287
  */
283
- function patchDrawTooltip(config) {
288
+ function patchDrawTooltip(configOrInstance) {
284
289
  if (typeof L === 'undefined' || !L.Draw || !L.Draw.Tooltip) {
285
290
  throw new Error('[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用');
286
291
  }
287
-
292
+
293
+ // 如果传入的是已有的 ExternalCardTooltip 实例,则复用;否则根据 config 创建一个共享实例
294
+ const sharedExternalTooltip =
295
+ configOrInstance && configOrInstance instanceof ExternalCardTooltip
296
+ ? configOrInstance
297
+ : new ExternalCardTooltip(configOrInstance || {});
298
+
288
299
  // 保存原始类(可选,用于调试)
289
300
  const OriginalTooltip = L.Draw.Tooltip;
290
-
301
+
291
302
  /**
292
303
  * 新的 L.Draw.Tooltip 适配器
293
- * 每次实例化时创建新的 ExternalCardTooltip
304
+ * 所有实例都共享同一个 ExternalCardTooltip
294
305
  */
295
306
  L.Draw.Tooltip = L.Class.extend({
296
307
  initialize: function(map) {
297
- // console.log('🆕 L.Draw.Tooltip 实例化,创建新的 ExternalCardTooltip');
298
- // 每次都创建新的实例
299
- this._externalTooltip = new ExternalCardTooltip(config);
308
+ // 复用共享实例
309
+ this._externalTooltip = sharedExternalTooltip;
300
310
  },
301
311
 
302
312
  /**
@@ -335,14 +345,25 @@
335
345
  * 销毁
336
346
  */
337
347
  dispose: function() {
338
- this._externalTooltip.dispose();
348
+ // 不在此处 dispose 共享实例(以免被局部销毁)。
339
349
  return this;
350
+ },
351
+
352
+ /**
353
+ * 空实现,避免调用时报错
354
+ */
355
+ _onMouseOut: function() {
356
+ return;
340
357
  }
341
358
  });
342
359
 
343
360
  // 标记已替换(可用于调试)
344
361
  L.Draw.Tooltip._isPatched = true;
345
362
  L.Draw.Tooltip._originalClass = OriginalTooltip;
363
+ // 暴露共享实例以便调试或外部访问
364
+ L.Draw.Tooltip._sharedExternalTooltip = sharedExternalTooltip;
365
+
366
+ return sharedExternalTooltip;
346
367
  }
347
368
 
348
369
  /**
@@ -412,26 +433,24 @@
412
433
  }
413
434
  }
414
435
 
415
- // 4. 准备配置对象(不创建实例)
436
+ // 4. 准备配置对象并创建共享 ExternalCardTooltip 实例
416
437
  const tooltipConfig = {
417
438
  containerEl,
418
439
  sanitize,
419
440
  onUpdate
420
441
  };
421
-
422
- // 5. Runtime 替换 L.Draw.Tooltip(传递配置而非实例)
423
- patchDrawTooltip(tooltipConfig);
424
-
425
- // 6. 创建一个初始实例用于返回(供用户手动控制)
426
- const externalTooltip = new ExternalCardTooltip(tooltipConfig);
442
+
443
+ // 5. 创建共享实例并让 patch 使用该实例(避免绘制期间产生命名冲突/覆盖)
444
+ const sharedExternalTooltip = new ExternalCardTooltip(tooltipConfig);
445
+ patchDrawTooltip(sharedExternalTooltip);
427
446
 
428
447
  // 8. 返回清理函数和 tooltip 实例
429
448
  const cleanup = function() {
430
- // 清理用户手动控制的实例
431
- if (externalTooltip) {
432
- externalTooltip.dispose();
449
+ // 仅在卸载插件时彻底 dispose 共享实例
450
+ if (sharedExternalTooltip) {
451
+ sharedExternalTooltip.dispose();
433
452
  }
434
-
453
+
435
454
  if (hideMapTooltip) {
436
455
  const mapContainer = map.getContainer();
437
456
  if (mapContainer) {
@@ -439,10 +458,10 @@
439
458
  }
440
459
  }
441
460
  };
442
-
461
+
443
462
  return {
444
463
  cleanup,
445
- tooltip: externalTooltip
464
+ tooltip: sharedExternalTooltip
446
465
  };
447
466
  }
448
467
 
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "leaflet-draw-tooltips",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "External tooltip plugin for Leaflet.draw - move drawing hints outside the map",
5
- "main": "dist/leaflet-draw-tooltip.umd.cjs",
6
- "module": "dist/leaflet-draw-tooltip.js",
5
+ "main": "dist/leaflet-draw-tooltips.umd.cjs",
6
+ "module": "dist/leaflet-draw-tooltips.js",
7
7
  "type": "module",
8
8
  "exports": {
9
9
  ".": {
10
- "import": "./dist/leaflet-draw-tooltip.js",
11
- "require": "./dist/leaflet-draw-tooltip.umd.cjs"
10
+ "import": "./dist/leaflet-draw-tooltips.js",
11
+ "require": "./dist/leaflet-draw-tooltips.umd.cjs"
12
12
  }
13
13
  },
14
14
  "files": [
@@ -21,7 +21,7 @@
21
21
  "keywords": [
22
22
  "leaflet",
23
23
  "leaflet-draw",
24
- "tooltip",
24
+ "tooltips",
25
25
  "external",
26
26
  "plugin"
27
27
  ],
@@ -29,12 +29,12 @@
29
29
  "license": "MIT",
30
30
  "repository": {
31
31
  "type": "git",
32
- "url": "https://github.com/Qun88/leaflet-draw-tooltip.git"
32
+ "url": "https://github.com/Qun88/leaflet-draw-tooltips.git"
33
33
  },
34
34
  "bugs": {
35
- "url": "https://github.com/Qun88/leaflet-draw-tooltip/issues"
35
+ "url": "https://github.com/Qun88/leaflet-draw-tooltips/issues"
36
36
  },
37
- "homepage": "https://github.com/Qun88/leaflet-draw-tooltip#readme",
37
+ "homepage": "https://github.com/Qun88/leaflet-draw-tooltips#readme",
38
38
  "devDependencies": {
39
39
  "@rollup/plugin-terser": "^0.4.4",
40
40
  "rollup": "^4.54.0",
@@ -37,23 +37,31 @@ export class ExternalCardTooltip {
37
37
  * 创建内部 DOM 结构
38
38
  */
39
39
  _setupDOM() {
40
- // 清空容器
41
- this.containerEl.innerHTML = '';
42
-
43
- // 创建主文本元素
44
- this.textEl = document.createElement('div');
45
- this.textEl.className = 'leaflet-draw-hint-text';
46
-
47
- // 创建副文本元素
48
- this.subtextEl = document.createElement('div');
49
- this.subtextEl.className = 'leaflet-draw-hint-subtext';
50
-
51
- // 添加到容器
52
- this.containerEl.appendChild(this.textEl);
53
- this.containerEl.appendChild(this.subtextEl);
54
-
55
- // 初始隐藏
56
- this.containerEl.style.display = 'none';
40
+ // 如果容器中已有预期的元素,则重用它们(避免被其它实例清空)
41
+ const existingText = this.containerEl.querySelector('.leaflet-draw-hint-text');
42
+ const existingSubtext = this.containerEl.querySelector('.leaflet-draw-hint-subtext');
43
+
44
+ if (existingText && existingSubtext) {
45
+ this.textEl = existingText;
46
+ this.subtextEl = existingSubtext;
47
+ } else {
48
+ // 创建主文本元素
49
+ this.textEl = document.createElement('div');
50
+ this.textEl.className = 'leaflet-draw-hint-text';
51
+
52
+ // 创建副文本元素
53
+ this.subtextEl = document.createElement('div');
54
+ this.subtextEl.className = 'leaflet-draw-hint-subtext';
55
+
56
+ // 如果容器为空或没有结构,则追加元素(但不盲目清空已有内容)
57
+ this.containerEl.appendChild(this.textEl);
58
+ this.containerEl.appendChild(this.subtextEl);
59
+ }
60
+
61
+ // 初始隐藏(如果尚未设置)
62
+ if (!this.containerEl.style.display) {
63
+ this.containerEl.style.display = 'none';
64
+ }
57
65
  }
58
66
 
59
67
  /**
@@ -131,14 +139,11 @@ export class ExternalCardTooltip {
131
139
  // 清空 DOM 内容但不删除元素(外部容器需要保留)
132
140
  if (this.textEl) this.textEl.textContent = '';
133
141
  if (this.subtextEl) this.subtextEl.textContent = '';
134
-
142
+
135
143
  this._notifyUpdate();
136
-
137
- // 注意:不删除 DOM 元素,只清空引用
138
- // DOM 元素(containerEl)是外部传入的,应该保留在页面上
139
- this.containerEl = null;
140
- this.textEl = null;
141
- this.subtextEl = null;
144
+
145
+ // 注意:不删除 DOM 元素,也不清空对 DOM 的引用。
146
+ // containerEl 是外部传入的共享容器,保留引用以便其它实例或返回的 tooltip 继续可用。
142
147
  this.onUpdate = null;
143
148
  }
144
149
 
package/src/index.js CHANGED
@@ -73,26 +73,24 @@ export function installLeafletDrawExternalTooltip(options = {}) {
73
73
  }
74
74
  }
75
75
 
76
- // 4. 准备配置对象(不创建实例)
76
+ // 4. 准备配置对象并创建共享 ExternalCardTooltip 实例
77
77
  const tooltipConfig = {
78
78
  containerEl,
79
79
  sanitize,
80
80
  onUpdate
81
81
  };
82
-
83
- // 5. Runtime 替换 L.Draw.Tooltip(传递配置而非实例)
84
- patchDrawTooltip(tooltipConfig);
85
-
86
- // 6. 创建一个初始实例用于返回(供用户手动控制)
87
- const externalTooltip = new ExternalCardTooltip(tooltipConfig);
82
+
83
+ // 5. 创建共享实例并让 patch 使用该实例(避免绘制期间产生命名冲突/覆盖)
84
+ const sharedExternalTooltip = new ExternalCardTooltip(tooltipConfig);
85
+ patchDrawTooltip(sharedExternalTooltip);
88
86
 
89
87
  // 8. 返回清理函数和 tooltip 实例
90
88
  const cleanup = function() {
91
- // 清理用户手动控制的实例
92
- if (externalTooltip) {
93
- externalTooltip.dispose();
89
+ // 仅在卸载插件时彻底 dispose 共享实例
90
+ if (sharedExternalTooltip) {
91
+ sharedExternalTooltip.dispose();
94
92
  }
95
-
93
+
96
94
  if (hideMapTooltip) {
97
95
  const mapContainer = map.getContainer();
98
96
  if (mapContainer) {
@@ -100,9 +98,9 @@ export function installLeafletDrawExternalTooltip(options = {}) {
100
98
  }
101
99
  }
102
100
  };
103
-
101
+
104
102
  return {
105
103
  cleanup,
106
- tooltip: externalTooltip
104
+ tooltip: sharedExternalTooltip
107
105
  };
108
106
  }
@@ -19,23 +19,28 @@ import { ExternalCardTooltip } from './ExternalCardTooltip.js';
19
19
  * @param {boolean} config.sanitize - 是否转义 HTML
20
20
  * @param {Function} config.onUpdate - 状态更新回调
21
21
  */
22
- export function patchDrawTooltip(config) {
22
+ export function patchDrawTooltip(configOrInstance) {
23
23
  if (typeof L === 'undefined' || !L.Draw || !L.Draw.Tooltip) {
24
24
  throw new Error('[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用');
25
25
  }
26
-
26
+
27
+ // 如果传入的是已有的 ExternalCardTooltip 实例,则复用;否则根据 config 创建一个共享实例
28
+ const sharedExternalTooltip =
29
+ configOrInstance && configOrInstance instanceof ExternalCardTooltip
30
+ ? configOrInstance
31
+ : new ExternalCardTooltip(configOrInstance || {});
32
+
27
33
  // 保存原始类(可选,用于调试)
28
34
  const OriginalTooltip = L.Draw.Tooltip;
29
-
35
+
30
36
  /**
31
37
  * 新的 L.Draw.Tooltip 适配器
32
- * 每次实例化时创建新的 ExternalCardTooltip
38
+ * 所有实例都共享同一个 ExternalCardTooltip
33
39
  */
34
40
  L.Draw.Tooltip = L.Class.extend({
35
41
  initialize: function(map) {
36
- // console.log('🆕 L.Draw.Tooltip 实例化,创建新的 ExternalCardTooltip');
37
- // 每次都创建新的实例
38
- this._externalTooltip = new ExternalCardTooltip(config);
42
+ // 复用共享实例
43
+ this._externalTooltip = sharedExternalTooltip;
39
44
  },
40
45
 
41
46
  /**
@@ -74,12 +79,23 @@ export function patchDrawTooltip(config) {
74
79
  * 销毁
75
80
  */
76
81
  dispose: function() {
77
- this._externalTooltip.dispose();
82
+ // 不在此处 dispose 共享实例(以免被局部销毁)。
78
83
  return this;
84
+ },
85
+
86
+ /**
87
+ * 空实现,避免调用时报错
88
+ */
89
+ _onMouseOut: function() {
90
+ return;
79
91
  }
80
92
  });
81
93
 
82
94
  // 标记已替换(可用于调试)
83
95
  L.Draw.Tooltip._isPatched = true;
84
96
  L.Draw.Tooltip._originalClass = OriginalTooltip;
97
+ // 暴露共享实例以便调试或外部访问
98
+ L.Draw.Tooltip._sharedExternalTooltip = sharedExternalTooltip;
99
+
100
+ return sharedExternalTooltip;
85
101
  }
@@ -1 +0,0 @@
1
- function t(t,e,i=!0){t&&(i?t.textContent=e||"":t.innerHTML=e||"")}class e{constructor({containerEl:t,sanitize:e=!0,onUpdate:i=null}){this.containerEl=t,this.sanitize=e,this.onUpdate=i,this._visible=!1,this._isError=!1,this._currentContent={text:"",subtext:""},this._setupDOM()}_setupDOM(){this.containerEl.innerHTML="",this.textEl=document.createElement("div"),this.textEl.className="leaflet-draw-hint-text",this.subtextEl=document.createElement("div"),this.subtextEl.className="leaflet-draw-hint-subtext",this.containerEl.appendChild(this.textEl),this.containerEl.appendChild(this.subtextEl),this.containerEl.style.display="none"}updateContent(e){if(!this.containerEl)return this;const{text:i="",subtext:n=""}=e||{};return this._currentContent={text:i,subtext:n},i||n?(t(this.textEl,i,this.sanitize),t(this.subtextEl,n,this.sanitize),this._show()):this._hide(),this._notifyUpdate(),this}updatePosition(t){return this}showAsError(){return this.containerEl?(this._isError=!0,this.containerEl.classList.add("is-error"),this._notifyUpdate(),this):this}removeError(){return this.containerEl?(this._isError=!1,this.containerEl.classList.remove("is-error"),this._notifyUpdate(),this):this}dispose(){this._hide(),this._currentContent={text:"",subtext:""},this.textEl&&(this.textEl.textContent=""),this.subtextEl&&(this.subtextEl.textContent=""),this._notifyUpdate(),this.containerEl=null,this.textEl=null,this.subtextEl=null,this.onUpdate=null}_show(){this.containerEl&&(this._visible||(this._visible=!0,this.containerEl.style.display="block"))}_hide(){this.containerEl&&this._visible&&(this._visible=!1,this.containerEl.style.display="none",this.removeError())}_notifyUpdate(){"function"==typeof this.onUpdate&&this.onUpdate({...this._currentContent},{visible:this._visible,isError:this._isError})}}function i(t={}){const{map:i,el:n,hideMapTooltip:s=!0,sanitize:o=!0,onUpdate:r=null}=t;if(!i||"function"!=typeof i.on)throw new Error("[leaflet-draw-tooltip] options.map 必须是有效的 Leaflet Map 实例");if(!n)throw new Error("[leaflet-draw-tooltip] options.el 必须提供(HTMLElement 或选择器)");const l=function(t){if(t instanceof HTMLElement)return t;if("string"==typeof t){const e=document.querySelector(t);if(!e)throw new Error(`[leaflet-draw-tooltip] 找不到元素: ${t}`);return e}throw new Error("[leaflet-draw-tooltip] el 必须是 HTMLElement 或选择器字符串")}(n);if(s){const t=i.getContainer();t&&t.classList.add("leaflet-draw-tooltip-hide")}const a={containerEl:l,sanitize:o,onUpdate:r};!function(t){if("undefined"==typeof L||!L.Draw||!L.Draw.Tooltip)throw new Error("[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用");const i=L.Draw.Tooltip;L.Draw.Tooltip=L.Class.extend({initialize:function(i){this._externalTooltip=new e(t)},updateContent:function(t){return this._externalTooltip.updateContent(t),this},updatePosition:function(t){return this._externalTooltip.updatePosition(t),this},showAsError:function(){return this._externalTooltip.showAsError(),this},removeError:function(){return this._externalTooltip.removeError(),this},dispose:function(){return this._externalTooltip.dispose(),this}}),L.Draw.Tooltip._isPatched=!0,L.Draw.Tooltip._originalClass=i}(a);const h=new e(a);return{cleanup:function(){if(h&&h.dispose(),s){const t=i.getContainer();t&&t.classList.remove("leaflet-draw-tooltip-hide")}},tooltip:h}}export{i as installLeafletDrawExternalTooltip};
@@ -1 +0,0 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).LeafletDrawTooltip={})}(this,function(t){"use strict";function e(t,e,i=!0){t&&(i?t.textContent=e||"":t.innerHTML=e||"")}class i{constructor({containerEl:t,sanitize:e=!0,onUpdate:i=null}){this.containerEl=t,this.sanitize=e,this.onUpdate=i,this._visible=!1,this._isError=!1,this._currentContent={text:"",subtext:""},this._setupDOM()}_setupDOM(){this.containerEl.innerHTML="",this.textEl=document.createElement("div"),this.textEl.className="leaflet-draw-hint-text",this.subtextEl=document.createElement("div"),this.subtextEl.className="leaflet-draw-hint-subtext",this.containerEl.appendChild(this.textEl),this.containerEl.appendChild(this.subtextEl),this.containerEl.style.display="none"}updateContent(t){if(!this.containerEl)return this;const{text:i="",subtext:n=""}=t||{};return this._currentContent={text:i,subtext:n},i||n?(e(this.textEl,i,this.sanitize),e(this.subtextEl,n,this.sanitize),this._show()):this._hide(),this._notifyUpdate(),this}updatePosition(t){return this}showAsError(){return this.containerEl?(this._isError=!0,this.containerEl.classList.add("is-error"),this._notifyUpdate(),this):this}removeError(){return this.containerEl?(this._isError=!1,this.containerEl.classList.remove("is-error"),this._notifyUpdate(),this):this}dispose(){this._hide(),this._currentContent={text:"",subtext:""},this.textEl&&(this.textEl.textContent=""),this.subtextEl&&(this.subtextEl.textContent=""),this._notifyUpdate(),this.containerEl=null,this.textEl=null,this.subtextEl=null,this.onUpdate=null}_show(){this.containerEl&&(this._visible||(this._visible=!0,this.containerEl.style.display="block"))}_hide(){this.containerEl&&this._visible&&(this._visible=!1,this.containerEl.style.display="none",this.removeError())}_notifyUpdate(){"function"==typeof this.onUpdate&&this.onUpdate({...this._currentContent},{visible:this._visible,isError:this._isError})}}t.installLeafletDrawExternalTooltip=function(t={}){const{map:e,el:n,hideMapTooltip:o=!0,sanitize:s=!0,onUpdate:r=null}=t;if(!e||"function"!=typeof e.on)throw new Error("[leaflet-draw-tooltip] options.map 必须是有效的 Leaflet Map 实例");if(!n)throw new Error("[leaflet-draw-tooltip] options.el 必须提供(HTMLElement 或选择器)");const l=function(t){if(t instanceof HTMLElement)return t;if("string"==typeof t){const e=document.querySelector(t);if(!e)throw new Error(`[leaflet-draw-tooltip] 找不到元素: ${t}`);return e}throw new Error("[leaflet-draw-tooltip] el 必须是 HTMLElement 或选择器字符串")}(n);if(o){const t=e.getContainer();t&&t.classList.add("leaflet-draw-tooltip-hide")}const a={containerEl:l,sanitize:s,onUpdate:r};!function(t){if("undefined"==typeof L||!L.Draw||!L.Draw.Tooltip)throw new Error("[leaflet-draw-tooltip] Leaflet.draw 未加载,请确保在加载 leaflet-draw 之后调用");const e=L.Draw.Tooltip;L.Draw.Tooltip=L.Class.extend({initialize:function(e){this._externalTooltip=new i(t)},updateContent:function(t){return this._externalTooltip.updateContent(t),this},updatePosition:function(t){return this._externalTooltip.updatePosition(t),this},showAsError:function(){return this._externalTooltip.showAsError(),this},removeError:function(){return this._externalTooltip.removeError(),this},dispose:function(){return this._externalTooltip.dispose(),this}}),L.Draw.Tooltip._isPatched=!0,L.Draw.Tooltip._originalClass=e}(a);const h=new i(a);return{cleanup:function(){if(h&&h.dispose(),o){const t=e.getContainer();t&&t.classList.remove("leaflet-draw-tooltip-hide")}},tooltip:h}}});