@footprint-studio/web-component 0.0.0-stage → 1.0.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/README.md +89 -2
- package/dist/auto.cjs +300 -0
- package/dist/auto.cjs.map +1 -0
- package/dist/auto.d.cts +2 -0
- package/dist/auto.d.ts +2 -0
- package/dist/auto.js +6 -0
- package/dist/auto.js.map +1 -0
- package/dist/chunk-Y7DEBPPV.js +291 -0
- package/dist/chunk-Y7DEBPPV.js.map +1 -0
- package/dist/index.cjs +308 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +94 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -4
package/README.md
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @footprint-studio/web-component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
足迹地球的 Web Component 封装。`<footprint-globe>` 自定义元素,Shadow DOM 隔离。
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@footprint-studio/web-component)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## 用法
|
|
9
|
+
|
|
10
|
+
### 零配置(auto-init)
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@footprint-studio/web-component@1/dist/auto.js"></script>
|
|
14
|
+
|
|
15
|
+
<footprint-globe
|
|
16
|
+
data-src="./pins.json"
|
|
17
|
+
height="480px"
|
|
18
|
+
legend="true">
|
|
19
|
+
</footprint-globe>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 手动注册
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<script type="importmap">
|
|
26
|
+
{ "imports": { "footprint-globe": "https://cdn.jsdelivr.net/npm/footprint-globe@1/dist/index.js" } }
|
|
27
|
+
</script>
|
|
28
|
+
<script type="module">
|
|
29
|
+
import { register } from 'https://cdn.jsdelivr.net/npm/@footprint-studio/web-component@1/dist/index.js';
|
|
30
|
+
register();
|
|
31
|
+
</script>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 属性
|
|
35
|
+
|
|
36
|
+
| 属性 | 类型 | 说明 |
|
|
37
|
+
| ------------------- | --------------------------- | ----------------- |
|
|
38
|
+
| `data-id` | string | 短链(v1.1) |
|
|
39
|
+
| `data-pins` | string | inline JSON |
|
|
40
|
+
| `data-src` | string | JSON URL(HTTPS) |
|
|
41
|
+
| `maplibre-url` | string | MapLibre CDN |
|
|
42
|
+
| `theme` | `light` \| `dark` \| `auto` | 主题 |
|
|
43
|
+
| `projection` | `globe` \| `mercator` | 投影 |
|
|
44
|
+
| `center` | `"lng,lat"` | 初始中心 |
|
|
45
|
+
| `zoom` | number | 初始缩放 |
|
|
46
|
+
| `height` | string | 容器高度 |
|
|
47
|
+
| `legend` | `"true"` \| `"false"` | 图例 |
|
|
48
|
+
| `autorotate` | `"true"` \| `"false"` | 自动旋转 |
|
|
49
|
+
| `privacy-blur` | number | 坐标模糊半径 |
|
|
50
|
+
| `privacy-city-only` | `"true"` \| `"false"` | 仅城市 |
|
|
51
|
+
|
|
52
|
+
## 方法
|
|
53
|
+
|
|
54
|
+
- `update(config)` — 差异更新
|
|
55
|
+
- `destroy()` — 销毁
|
|
56
|
+
- `getInstance()` — 获取核心实例
|
|
57
|
+
|
|
58
|
+
## 事件
|
|
59
|
+
|
|
60
|
+
- `fp-ready`
|
|
61
|
+
- `fp-error`
|
|
62
|
+
|
|
63
|
+
## CSS 变量与 Parts
|
|
64
|
+
|
|
65
|
+
通过 `--fp-*` 变量定制样式:
|
|
66
|
+
|
|
67
|
+
```css
|
|
68
|
+
:root {
|
|
69
|
+
--fp-globe-radius: 24px;
|
|
70
|
+
--fp-marker-size: 10px;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
通过 `::part()` 定制 Shadow DOM 内部元素:
|
|
75
|
+
|
|
76
|
+
```css
|
|
77
|
+
footprint-globe::part(legend) { border: 1px solid #e5e7eb; }
|
|
78
|
+
footprint-globe::part(list) { padding: 2rem; }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
支持 parts:`globe` / `legend` / `list` / `error`。
|
|
82
|
+
|
|
83
|
+
## 文档
|
|
84
|
+
|
|
85
|
+
- [完整文档](https://footprint-studio.pages.dev/)
|
|
86
|
+
- [Web Component API](https://footprint-studio.pages.dev/api/web-component)
|
|
87
|
+
|
|
88
|
+
## 许可
|
|
89
|
+
|
|
90
|
+
MIT © 2025 Footprint Studio
|
package/dist/auto.cjs
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var footprintGlobe = require('footprint-globe');
|
|
4
|
+
|
|
5
|
+
// src/auto-init.ts
|
|
6
|
+
|
|
7
|
+
// src/attributes.ts
|
|
8
|
+
function parseBool(v) {
|
|
9
|
+
if (v === null) return void 0;
|
|
10
|
+
if (v === "true" || v === "1" || v === "") return true;
|
|
11
|
+
if (v === "false" || v === "0") return false;
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
function parseNumber(v) {
|
|
15
|
+
if (v === null) return void 0;
|
|
16
|
+
const n = Number(v);
|
|
17
|
+
return Number.isFinite(n) ? n : void 0;
|
|
18
|
+
}
|
|
19
|
+
function parseCenter(v) {
|
|
20
|
+
if (!v) return void 0;
|
|
21
|
+
const parts = v.split(",").map((s) => Number(s.trim()));
|
|
22
|
+
if (parts.length !== 2) return void 0;
|
|
23
|
+
const [lng, lat] = parts;
|
|
24
|
+
if (!Number.isFinite(lng) || !Number.isFinite(lat)) return void 0;
|
|
25
|
+
return [lng, lat];
|
|
26
|
+
}
|
|
27
|
+
function parseAttributes(el) {
|
|
28
|
+
const out = {};
|
|
29
|
+
const id = el.getAttribute("data-id");
|
|
30
|
+
if (id) out.id = id;
|
|
31
|
+
const pins = el.getAttribute("data-pins");
|
|
32
|
+
if (pins) out.pins = pins;
|
|
33
|
+
const src = el.getAttribute("data-src");
|
|
34
|
+
if (src) out.src = src;
|
|
35
|
+
const maplibreUrl = el.getAttribute("maplibre-url");
|
|
36
|
+
if (maplibreUrl) out.maplibreUrl = maplibreUrl;
|
|
37
|
+
const height = el.getAttribute("height");
|
|
38
|
+
if (height) out.height = height;
|
|
39
|
+
const cfg = {};
|
|
40
|
+
const theme = el.getAttribute("theme");
|
|
41
|
+
if (theme === "light" || theme === "dark" || theme === "auto") cfg.theme = theme;
|
|
42
|
+
const projection = el.getAttribute("projection");
|
|
43
|
+
if (projection === "globe" || projection === "mercator") cfg.projection = projection;
|
|
44
|
+
const center = parseCenter(el.getAttribute("center"));
|
|
45
|
+
if (center) cfg.center = center;
|
|
46
|
+
const zoom = parseNumber(el.getAttribute("zoom"));
|
|
47
|
+
if (zoom !== void 0) cfg.zoom = zoom;
|
|
48
|
+
const legend = parseBool(el.getAttribute("legend"));
|
|
49
|
+
if (legend !== void 0) cfg.legend = legend;
|
|
50
|
+
const autorotate = parseBool(el.getAttribute("autorotate"));
|
|
51
|
+
if (autorotate !== void 0) cfg.autorotate = autorotate;
|
|
52
|
+
const attribution = parseBool(el.getAttribute("attribution"));
|
|
53
|
+
if (attribution !== void 0) cfg.attribution = attribution;
|
|
54
|
+
const privacy = {};
|
|
55
|
+
const blur = parseNumber(el.getAttribute("privacy-blur"));
|
|
56
|
+
if (blur !== void 0) privacy.blur = blur;
|
|
57
|
+
const cityOnly = parseBool(el.getAttribute("privacy-city-only"));
|
|
58
|
+
if (cityOnly !== void 0) privacy.cityOnly = cityOnly;
|
|
59
|
+
if (Object.keys(privacy).length > 0) cfg.privacy = privacy;
|
|
60
|
+
if (Object.keys(cfg).length > 0) out.config = cfg;
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
function mergeAttributeConfig(base, attrs) {
|
|
64
|
+
if (!attrs.config) return base;
|
|
65
|
+
return {
|
|
66
|
+
...base,
|
|
67
|
+
config: { ...base.config ?? {}, ...attrs.config }
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/styles.ts
|
|
72
|
+
var RAW = "/* ============================================================\n * \u8DB3\u8FF9\u5730\u7403 \xB7 \u7EC4\u4EF6\u6837\u5F0F\n * \u5951\u7EA6\u4F9D\u636E\uFF1AADR-0001 \u51B3\u7B56 4\u3001PRD v1.1 \xA77.1\n * \u7C7B\u540D\u524D\u7F00\uFF1Afootprint-\n * CSS \u53D8\u91CF\u524D\u7F00\uFF1A--fp-\n * ============================================================ */\n\n:root {\n /* \u5C3A\u5BF8 */\n --fp-marker-size: 8px;\n --fp-marker-hover-scale: 1.15;\n --fp-globe-height: 400px;\n --fp-globe-radius: 12px;\n\n /* \u989C\u8272 */\n --fp-marker-color: #2563eb;\n --fp-marker-border: #fff;\n --fp-globe-bg: #eef2f7;\n --fp-legend-bg: rgba(255, 255, 255, 0.9);\n --fp-legend-color: #111827;\n\n /* \u9634\u5F71 */\n --fp-marker-shadow: 0 0 0 4px rgba(17, 24, 39, 0.08), 0 1px 3px rgba(0, 0, 0, 0.25);\n --fp-legend-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n\n /* \u5E03\u5C40 */\n --fp-legend-radius: 9999px;\n --fp-legend-gap: 0.75rem;\n}\n\n/* \u6697\u8272\u4E3B\u9898\u8986\u76D6 */\n[data-fp-theme='dark'] {\n --fp-globe-bg: #111827;\n --fp-legend-bg: rgba(17, 24, 39, 0.85);\n --fp-legend-color: #f9fafb;\n --fp-marker-border: #111827;\n}\n\n/* ===== \u5BB9\u5668 ===== */\n.footprint-globe {\n width: 100%;\n min-height: var(--fp-globe-height);\n border-radius: var(--fp-globe-radius);\n overflow: hidden;\n background: var(--fp-globe-bg);\n position: relative;\n}\n\n/* ===== \u6807\u8BB0 ===== */\n.footprint-marker {\n width: var(--fp-marker-size);\n height: var(--fp-marker-size);\n border-radius: 9999px;\n border: 1px solid var(--fp-marker-border);\n background: var(--fp-marker-color);\n box-shadow: var(--fp-marker-shadow);\n cursor: pointer;\n padding: 0;\n margin: 0;\n display: block;\n transition:\n transform 120ms ease,\n box-shadow 120ms ease;\n appearance: none;\n -webkit-appearance: none;\n}\n\n.footprint-marker:hover,\n.footprint-marker:focus-visible {\n transform: scale(var(--fp-marker-hover-scale));\n outline: none;\n}\n\n.footprint-marker:focus-visible {\n box-shadow:\n 0 0 0 2px var(--fp-marker-border),\n 0 0 0 6px var(--fp-marker-color);\n}\n\n/* ===== \u56FE\u4F8B ===== */\n.footprint-legend {\n position: absolute;\n right: 12px;\n bottom: 12px;\n display: flex;\n gap: var(--fp-legend-gap);\n align-items: center;\n padding: 0.5rem 0.75rem;\n border-radius: var(--fp-legend-radius);\n background: var(--fp-legend-bg);\n box-shadow: var(--fp-legend-shadow);\n backdrop-filter: blur(6px);\n color: var(--fp-legend-color);\n font-size: 0.85rem;\n line-height: 1.1;\n z-index: 1;\n}\n\n.footprint-legend__item {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n white-space: nowrap;\n}\n\n.footprint-legend__dot {\n width: 10px;\n height: 10px;\n border-radius: 9999px;\n display: inline-block;\n border: 2px solid var(--fp-marker-border);\n box-shadow: 0 0 0 2px rgba(17, 24, 39, 0.08);\n background: var(--fp-marker-color);\n}\n\n/* ===== \u964D\u7EA7\u5217\u8868 ===== */\n.footprint-list {\n padding: 1rem 1.25rem;\n background: var(--fp-globe-bg);\n border-radius: var(--fp-globe-radius);\n color: var(--fp-legend-color);\n font-size: 0.95rem;\n}\n\n.footprint-list__notice {\n margin: 0 0 1rem;\n padding: 0.6rem 0.8rem;\n border-radius: 8px;\n background: rgba(0, 0, 0, 0.05);\n font-size: 0.85rem;\n color: var(--fp-legend-color);\n}\n\n.footprint-list__group {\n margin-bottom: 1rem;\n}\n\n.footprint-list__heading {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin: 0 0 0.5rem;\n font-size: 0.95rem;\n font-weight: 600;\n}\n\n.footprint-list__items {\n margin: 0;\n padding-left: 1.4rem;\n list-style: disc;\n}\n\n.footprint-list__item {\n margin: 0.2rem 0;\n line-height: 1.5;\n}\n\n/* ===== \u54CD\u5E94\u5F0F ===== */\n@media (max-width: 768px) {\n .footprint-globe {\n min-height: 300px;\n }\n .footprint-legend {\n font-size: 0.78rem;\n padding: 0.4rem 0.6rem;\n gap: 0.5rem;\n }\n}\n\n/* ===== \u517C\u5BB9\u522B\u540D\uFF08\u4E00\u4E2A minor \u7248\u672C\u540E\u79FB\u9664\uFF09 ===== */\n.mapbox-globe {\n width: 100%;\n min-height: var(--fp-globe-height);\n border-radius: var(--fp-globe-radius);\n overflow: hidden;\n background: var(--fp-globe-bg);\n position: relative;\n}\n" ;
|
|
73
|
+
function adaptRootSelector(css) {
|
|
74
|
+
return css.replace(/(^|[^\w-]):root(\b)/g, "$1:host, :root$2");
|
|
75
|
+
}
|
|
76
|
+
var SHADOW_CSS = adaptRootSelector(RAW);
|
|
77
|
+
var HOST_CSS = `
|
|
78
|
+
:host {
|
|
79
|
+
display: block;
|
|
80
|
+
width: 100%;
|
|
81
|
+
min-height: var(--fp-globe-height, 400px);
|
|
82
|
+
border-radius: var(--fp-globe-radius, 12px);
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
background: var(--fp-globe-bg, #eef2f7);
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
function getShadowStyle() {
|
|
88
|
+
return HOST_CSS + "\n" + SHADOW_CSS;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/element.ts
|
|
92
|
+
var DEFAULT_ARIA_LABEL = "\u8DB3\u8FF9\u5730\u7403";
|
|
93
|
+
var FootprintGlobeElement = class extends HTMLElement {
|
|
94
|
+
static get observedAttributes() {
|
|
95
|
+
return [
|
|
96
|
+
"data-id",
|
|
97
|
+
"data-pins",
|
|
98
|
+
"data-src",
|
|
99
|
+
"maplibre-url",
|
|
100
|
+
"theme",
|
|
101
|
+
"projection",
|
|
102
|
+
"center",
|
|
103
|
+
"zoom",
|
|
104
|
+
"height",
|
|
105
|
+
"legend",
|
|
106
|
+
"autorotate",
|
|
107
|
+
"attribution",
|
|
108
|
+
"privacy-blur",
|
|
109
|
+
"privacy-city-only"
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
root;
|
|
113
|
+
container;
|
|
114
|
+
instance = null;
|
|
115
|
+
initToken = 0;
|
|
116
|
+
ready = false;
|
|
117
|
+
constructor() {
|
|
118
|
+
super();
|
|
119
|
+
this.root = this.attachShadow({ mode: "open" });
|
|
120
|
+
const style = document.createElement("style");
|
|
121
|
+
style.textContent = getShadowStyle();
|
|
122
|
+
this.root.appendChild(style);
|
|
123
|
+
this.container = document.createElement("div");
|
|
124
|
+
this.container.className = "footprint-globe";
|
|
125
|
+
this.container.setAttribute("part", "globe");
|
|
126
|
+
this.root.appendChild(this.container);
|
|
127
|
+
}
|
|
128
|
+
connectedCallback() {
|
|
129
|
+
if (!this.hasAttribute("role")) {
|
|
130
|
+
this.setAttribute("role", "region");
|
|
131
|
+
}
|
|
132
|
+
if (!this.hasAttribute("aria-label")) {
|
|
133
|
+
this.setAttribute("aria-label", DEFAULT_ARIA_LABEL);
|
|
134
|
+
}
|
|
135
|
+
void this.init();
|
|
136
|
+
}
|
|
137
|
+
disconnectedCallback() {
|
|
138
|
+
this.destroy();
|
|
139
|
+
}
|
|
140
|
+
attributeChangedCallback() {
|
|
141
|
+
if (!this.instance || !this.ready) return;
|
|
142
|
+
const attrs = parseAttributes(this);
|
|
143
|
+
if (attrs.config) {
|
|
144
|
+
this.instance.update({ config: attrs.config });
|
|
145
|
+
}
|
|
146
|
+
if (attrs.height) {
|
|
147
|
+
this.container.style.setProperty("--fp-globe-height", attrs.height);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async init() {
|
|
151
|
+
if (this.ready || this.instance) return;
|
|
152
|
+
const token = ++this.initToken;
|
|
153
|
+
try {
|
|
154
|
+
const attrs = parseAttributes(this);
|
|
155
|
+
let baseConfig;
|
|
156
|
+
if (attrs.id || attrs.src || attrs.pins) {
|
|
157
|
+
const r = await footprintGlobe.loadData({
|
|
158
|
+
id: attrs.id,
|
|
159
|
+
src: attrs.src,
|
|
160
|
+
data: attrs.pins
|
|
161
|
+
});
|
|
162
|
+
baseConfig = r.config;
|
|
163
|
+
} else {
|
|
164
|
+
const g = globalThis.FOOTPRINT_PINS;
|
|
165
|
+
if (!g) {
|
|
166
|
+
this.renderError("\u672A\u63D0\u4F9B\u6570\u636E\u6E90\uFF1A\u8BF7\u8BBE\u7F6E data-pins\u3001data-src \u6216 window.FOOTPRINT_PINS");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const r = await footprintGlobe.loadData({ globalVar: "FOOTPRINT_PINS" });
|
|
170
|
+
baseConfig = r.config;
|
|
171
|
+
}
|
|
172
|
+
if (token !== this.initToken) return;
|
|
173
|
+
const config = mergeAttributeConfig(baseConfig, attrs);
|
|
174
|
+
const errs = footprintGlobe.validateConfig(config);
|
|
175
|
+
if (errs.length > 0) {
|
|
176
|
+
this.renderError(errs[0].userMessage);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (attrs.height) {
|
|
180
|
+
this.container.style.setProperty("--fp-globe-height", attrs.height);
|
|
181
|
+
}
|
|
182
|
+
this.instance = new footprintGlobe.FootprintGlobe(this.container, {
|
|
183
|
+
config,
|
|
184
|
+
maplibreUrl: attrs.maplibreUrl,
|
|
185
|
+
onReady: () => {
|
|
186
|
+
this.ready = true;
|
|
187
|
+
this.dispatchEvent(new CustomEvent("fp-ready", { bubbles: true }));
|
|
188
|
+
},
|
|
189
|
+
onError: (err) => {
|
|
190
|
+
this.dispatchEvent(new CustomEvent("fp-error", { detail: err, bubbles: true }));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
} catch (e) {
|
|
194
|
+
if (token !== this.initToken) return;
|
|
195
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
196
|
+
this.renderError(msg);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
renderError(msg) {
|
|
200
|
+
this.container.innerHTML = "";
|
|
201
|
+
const div = document.createElement("div");
|
|
202
|
+
div.className = "footprint-error";
|
|
203
|
+
div.setAttribute("part", "error");
|
|
204
|
+
div.setAttribute("role", "alert");
|
|
205
|
+
div.textContent = msg;
|
|
206
|
+
this.container.appendChild(div);
|
|
207
|
+
}
|
|
208
|
+
// ===== 对外方法(S2-4) =====
|
|
209
|
+
update(config) {
|
|
210
|
+
this.instance?.update(config);
|
|
211
|
+
}
|
|
212
|
+
destroy() {
|
|
213
|
+
this.initToken++;
|
|
214
|
+
this.ready = false;
|
|
215
|
+
this.instance?.destroy();
|
|
216
|
+
this.instance = null;
|
|
217
|
+
}
|
|
218
|
+
getInstance() {
|
|
219
|
+
return this.instance;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
function register() {
|
|
223
|
+
if (typeof customElements === "undefined") return;
|
|
224
|
+
if (!customElements.get("footprint-globe")) {
|
|
225
|
+
customElements.define("footprint-globe", FootprintGlobeElement);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/auto-init.ts
|
|
230
|
+
var BOUND_ATTR = "data-fp-bound";
|
|
231
|
+
var SELECTOR = ".footprint-globe";
|
|
232
|
+
function isCustomElement(el) {
|
|
233
|
+
return el.tagName.toLowerCase() === "footprint-globe";
|
|
234
|
+
}
|
|
235
|
+
function renderError(container, msg) {
|
|
236
|
+
container.innerHTML = "";
|
|
237
|
+
const div = document.createElement("div");
|
|
238
|
+
div.className = "footprint-error";
|
|
239
|
+
div.textContent = msg;
|
|
240
|
+
container.appendChild(div);
|
|
241
|
+
}
|
|
242
|
+
async function initOne(el) {
|
|
243
|
+
if (el.hasAttribute(BOUND_ATTR)) return;
|
|
244
|
+
el.setAttribute(BOUND_ATTR, "1");
|
|
245
|
+
if (isCustomElement(el)) return;
|
|
246
|
+
try {
|
|
247
|
+
const attrs = parseAttributes(el);
|
|
248
|
+
let baseConfig;
|
|
249
|
+
if (attrs.id || attrs.src || attrs.pins) {
|
|
250
|
+
const r = await footprintGlobe.loadData({
|
|
251
|
+
id: attrs.id,
|
|
252
|
+
src: attrs.src,
|
|
253
|
+
data: attrs.pins
|
|
254
|
+
});
|
|
255
|
+
baseConfig = r.config;
|
|
256
|
+
} else {
|
|
257
|
+
const g = globalThis.FOOTPRINT_PINS;
|
|
258
|
+
if (!g) {
|
|
259
|
+
renderError(el, "\u672A\u63D0\u4F9B\u6570\u636E\u6E90\uFF1A\u8BF7\u8BBE\u7F6E data-pins\u3001data-src \u6216 window.FOOTPRINT_PINS");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const r = await footprintGlobe.loadData({ globalVar: "FOOTPRINT_PINS" });
|
|
263
|
+
baseConfig = r.config;
|
|
264
|
+
}
|
|
265
|
+
const config = mergeAttributeConfig(baseConfig, attrs);
|
|
266
|
+
const errs = footprintGlobe.validateConfig(config);
|
|
267
|
+
if (errs.length > 0) {
|
|
268
|
+
renderError(el, errs[0].userMessage);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (attrs.height) {
|
|
272
|
+
el.style.setProperty("--fp-globe-height", attrs.height);
|
|
273
|
+
}
|
|
274
|
+
new footprintGlobe.FootprintGlobe(el, {
|
|
275
|
+
config,
|
|
276
|
+
maplibreUrl: attrs.maplibreUrl
|
|
277
|
+
});
|
|
278
|
+
} catch (e) {
|
|
279
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
280
|
+
renderError(el, msg);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function autoInit(root = document) {
|
|
284
|
+
const nodes = root.querySelectorAll(SELECTOR);
|
|
285
|
+
nodes.forEach((el) => void initOne(el));
|
|
286
|
+
}
|
|
287
|
+
function boot() {
|
|
288
|
+
register();
|
|
289
|
+
if (typeof document === "undefined") return;
|
|
290
|
+
if (document.readyState === "loading") {
|
|
291
|
+
document.addEventListener("DOMContentLoaded", () => autoInit(), { once: true });
|
|
292
|
+
} else {
|
|
293
|
+
autoInit();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// src/auto-entry.ts
|
|
298
|
+
boot();
|
|
299
|
+
//# sourceMappingURL=auto.cjs.map
|
|
300
|
+
//# sourceMappingURL=auto.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/attributes.ts","../src/styles.ts","../src/element.ts","../src/auto-init.ts","../src/auto-entry.ts"],"names":["loadData","validateConfig","FootprintGlobe"],"mappings":"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","file":"auto.cjs","sourcesContent":["/**\n * 足迹地球 · Web Component 属性解析\n * 契约依据:《Sprint 2 执行方案》§4.1、§6 S2-3\n */\n\nimport type { FootprintConfig, RenderConfig } from 'footprint-globe';\n\nexport interface ParsedAttributes {\n id?: string;\n pins?: string;\n src?: string;\n maplibreUrl?: string;\n config?: Partial<RenderConfig>;\n height?: string;\n}\n\nfunction parseBool(v: string | null): boolean | undefined {\n if (v === null) return undefined;\n if (v === 'true' || v === '1' || v === '') return true;\n if (v === 'false' || v === '0') return false;\n return undefined;\n}\n\nfunction parseNumber(v: string | null): number | undefined {\n if (v === null) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction parseCenter(v: string | null): [number, number] | undefined {\n if (!v) return undefined;\n const parts = v.split(',').map((s) => Number(s.trim()));\n if (parts.length !== 2) return undefined;\n const [lng, lat] = parts;\n if (!Number.isFinite(lng) || !Number.isFinite(lat)) return undefined;\n return [lng!, lat!];\n}\n\n/**\n * 从宿主元素读取所有 footprint-globe 相关属性。\n * 非法值静默忽略,由 core 使用默认值兜底。\n */\nexport function parseAttributes(el: HTMLElement): ParsedAttributes {\n const out: ParsedAttributes = {};\n\n const id = el.getAttribute('data-id');\n if (id) out.id = id;\n\n const pins = el.getAttribute('data-pins');\n if (pins) out.pins = pins;\n\n const src = el.getAttribute('data-src');\n if (src) out.src = src;\n\n const maplibreUrl = el.getAttribute('maplibre-url');\n if (maplibreUrl) out.maplibreUrl = maplibreUrl;\n\n const height = el.getAttribute('height');\n if (height) out.height = height;\n\n const cfg: Partial<RenderConfig> = {};\n\n const theme = el.getAttribute('theme');\n if (theme === 'light' || theme === 'dark' || theme === 'auto') cfg.theme = theme;\n\n const projection = el.getAttribute('projection');\n if (projection === 'globe' || projection === 'mercator') cfg.projection = projection;\n\n const center = parseCenter(el.getAttribute('center'));\n if (center) cfg.center = center;\n\n const zoom = parseNumber(el.getAttribute('zoom'));\n if (zoom !== undefined) cfg.zoom = zoom;\n\n const legend = parseBool(el.getAttribute('legend'));\n if (legend !== undefined) cfg.legend = legend;\n\n const autorotate = parseBool(el.getAttribute('autorotate'));\n if (autorotate !== undefined) cfg.autorotate = autorotate;\n\n const attribution = parseBool(el.getAttribute('attribution'));\n if (attribution !== undefined) cfg.attribution = attribution;\n\n const privacy: { blur?: number; cityOnly?: boolean } = {};\n const blur = parseNumber(el.getAttribute('privacy-blur'));\n if (blur !== undefined) privacy.blur = blur;\n const cityOnly = parseBool(el.getAttribute('privacy-city-only'));\n if (cityOnly !== undefined) privacy.cityOnly = cityOnly;\n if (Object.keys(privacy).length > 0) cfg.privacy = privacy;\n\n if (Object.keys(cfg).length > 0) out.config = cfg;\n\n return out;\n}\n\n/** 合并属性 config 到已有 config(属性优先) */\nexport function mergeAttributeConfig(\n base: FootprintConfig,\n attrs: ParsedAttributes,\n): FootprintConfig {\n if (!attrs.config) return base;\n return {\n ...base,\n config: { ...(base.config ?? {}), ...attrs.config },\n };\n}\n","/**\n * 足迹地球 · Shadow DOM 样式注入\n * 契约依据:《Sprint 2 执行方案》§6 S2-2\n *\n * 构建时通过 tsup define 把 core 的 CSS 注入为 __FP_SHADOW_CSS__。\n * 运行时把 `:root` 改写为 `:host, :root`,使变量在 Shadow DOM 内生效。\n */\n\ndeclare const __FP_SHADOW_CSS__: string | undefined;\n\nconst RAW: string = typeof __FP_SHADOW_CSS__ !== 'undefined' ? __FP_SHADOW_CSS__ : '';\n\n/** 把顶层 `:root` 选择器改写为 `:host, :root`,兼容 Shadow DOM */\nfunction adaptRootSelector(css: string): string {\n return css.replace(/(^|[^\\w-]):root(\\b)/g, '$1:host, :root$2');\n}\n\nexport const SHADOW_CSS: string = adaptRootSelector(RAW);\n\n/** 额外补充:Shadow DOM 内的容器基础样式(core CSS 里给的是 .footprint-globe,这里补 :host) */\nconst HOST_CSS = `\n:host {\n display: block;\n width: 100%;\n min-height: var(--fp-globe-height, 400px);\n border-radius: var(--fp-globe-radius, 12px);\n overflow: hidden;\n background: var(--fp-globe-bg, #eef2f7);\n}\n`;\n\nexport function getShadowStyle(): string {\n return HOST_CSS + '\\n' + SHADOW_CSS;\n}\n","/**\n * 足迹地球 · 自定义元素 <footprint-globe>\n * 契约依据:《Sprint 2 执行方案》§4.1、§6 S2-1 / S2-4、§8 S2-12\n * 决策:S2-Q1 Shadow DOM open;S2-Q9 disconnect 自动 destroy\n */\n\nimport { FootprintGlobe, loadData, validateConfig, type FootprintConfig } from 'footprint-globe';\nimport { mergeAttributeConfig, parseAttributes } from './attributes';\nimport { getShadowStyle } from './styles';\n\nconst DEFAULT_ARIA_LABEL = '足迹地球';\n\nexport class FootprintGlobeElement extends HTMLElement {\n static get observedAttributes(): string[] {\n return [\n 'data-id',\n 'data-pins',\n 'data-src',\n 'maplibre-url',\n 'theme',\n 'projection',\n 'center',\n 'zoom',\n 'height',\n 'legend',\n 'autorotate',\n 'attribution',\n 'privacy-blur',\n 'privacy-city-only',\n ];\n }\n\n private root: ShadowRoot;\n private container: HTMLElement;\n private instance: FootprintGlobe | null = null;\n private initToken = 0;\n private ready = false;\n\n constructor() {\n super();\n\n this.root = this.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = getShadowStyle();\n this.root.appendChild(style);\n\n this.container = document.createElement('div');\n this.container.className = 'footprint-globe';\n this.container.setAttribute('part', 'globe');\n this.root.appendChild(this.container);\n }\n\n connectedCallback(): void {\n // a11y:默认 role 与 aria-label(可被宿主覆盖)\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'region');\n }\n if (!this.hasAttribute('aria-label')) {\n this.setAttribute('aria-label', DEFAULT_ARIA_LABEL);\n }\n void this.init();\n }\n\n disconnectedCallback(): void {\n this.destroy();\n }\n\n attributeChangedCallback(): void {\n if (!this.instance || !this.ready) return;\n // 简化:属性变更时只同步 config(数据源变更需手动重挂载)\n const attrs = parseAttributes(this);\n if (attrs.config) {\n this.instance.update({ config: attrs.config });\n }\n if (attrs.height) {\n this.container.style.setProperty('--fp-globe-height', attrs.height);\n }\n }\n\n private async init(): Promise<void> {\n if (this.ready || this.instance) return;\n const token = ++this.initToken;\n\n try {\n const attrs = parseAttributes(this);\n let baseConfig: FootprintConfig;\n\n if (attrs.id || attrs.src || attrs.pins) {\n const r = await loadData({\n id: attrs.id,\n src: attrs.src,\n data: attrs.pins,\n });\n baseConfig = r.config;\n } else {\n const g = (globalThis as { FOOTPRINT_PINS?: unknown }).FOOTPRINT_PINS;\n if (!g) {\n this.renderError('未提供数据源:请设置 data-pins、data-src 或 window.FOOTPRINT_PINS');\n return;\n }\n const r = await loadData({ globalVar: 'FOOTPRINT_PINS' });\n baseConfig = r.config;\n }\n\n if (token !== this.initToken) return; // 已取消\n\n const config = mergeAttributeConfig(baseConfig, attrs);\n\n const errs = validateConfig(config);\n if (errs.length > 0) {\n this.renderError(errs[0]!.userMessage);\n return;\n }\n\n if (attrs.height) {\n this.container.style.setProperty('--fp-globe-height', attrs.height);\n }\n\n this.instance = new FootprintGlobe(this.container, {\n config,\n maplibreUrl: attrs.maplibreUrl,\n onReady: () => {\n this.ready = true;\n this.dispatchEvent(new CustomEvent('fp-ready', { bubbles: true }));\n },\n onError: (err) => {\n this.dispatchEvent(new CustomEvent('fp-error', { detail: err, bubbles: true }));\n },\n });\n } catch (e) {\n if (token !== this.initToken) return;\n const msg = e instanceof Error ? e.message : String(e);\n this.renderError(msg);\n }\n }\n\n private renderError(msg: string): void {\n this.container.innerHTML = '';\n const div = document.createElement('div');\n div.className = 'footprint-error';\n div.setAttribute('part', 'error');\n div.setAttribute('role', 'alert');\n div.textContent = msg;\n this.container.appendChild(div);\n }\n\n // ===== 对外方法(S2-4) =====\n\n update(config: Partial<FootprintConfig>): void {\n this.instance?.update(config);\n }\n\n destroy(): void {\n this.initToken++;\n this.ready = false;\n this.instance?.destroy();\n this.instance = null;\n }\n\n getInstance(): FootprintGlobe | null {\n return this.instance;\n }\n}\n\nexport function register(): void {\n if (typeof customElements === 'undefined') return;\n if (!customElements.get('footprint-globe')) {\n customElements.define('footprint-globe', FootprintGlobeElement);\n }\n}\n","/**\n * 足迹地球 · auto-init 扫描\n * 契约依据:《Sprint 2 执行方案》§4.3、§7 S2-5\n *\n * 用法:\n * <script type=\"module\" src=\".../embed.js\"></script>\n * <div class=\"footprint-globe\" data-pins=\"...\"></div>\n *\n * 行为:\n * - 扫描 .footprint-globe\n * - 若为 <footprint-globe>,跳过(由自定义元素接管)\n * - 否则作为容器挂载 FootprintGlobe 实例\n * - 用 data-fp-bound 防止重复初始化\n * - 不监听 DOM 变化(v1.1 加 MutationObserver)\n */\n\nimport { FootprintGlobe, loadData, validateConfig, type FootprintConfig } from 'footprint-globe';\nimport { mergeAttributeConfig, parseAttributes } from './attributes';\nimport { register } from './element';\n\nconst BOUND_ATTR = 'data-fp-bound';\nconst SELECTOR = '.footprint-globe';\n\nfunction isCustomElement(el: Element): boolean {\n return el.tagName.toLowerCase() === 'footprint-globe';\n}\n\nfunction renderError(container: HTMLElement, msg: string): void {\n container.innerHTML = '';\n const div = document.createElement('div');\n div.className = 'footprint-error';\n div.textContent = msg;\n container.appendChild(div);\n}\n\nasync function initOne(el: HTMLElement): Promise<void> {\n if (el.hasAttribute(BOUND_ATTR)) return;\n el.setAttribute(BOUND_ATTR, '1');\n\n if (isCustomElement(el)) return;\n\n try {\n const attrs = parseAttributes(el);\n let baseConfig: FootprintConfig;\n\n if (attrs.id || attrs.src || attrs.pins) {\n const r = await loadData({\n id: attrs.id,\n src: attrs.src,\n data: attrs.pins,\n });\n baseConfig = r.config;\n } else {\n const g = (globalThis as { FOOTPRINT_PINS?: unknown }).FOOTPRINT_PINS;\n if (!g) {\n renderError(el, '未提供数据源:请设置 data-pins、data-src 或 window.FOOTPRINT_PINS');\n return;\n }\n const r = await loadData({ globalVar: 'FOOTPRINT_PINS' });\n baseConfig = r.config;\n }\n\n const config = mergeAttributeConfig(baseConfig, attrs);\n\n const errs = validateConfig(config);\n if (errs.length > 0) {\n renderError(el, errs[0]!.userMessage);\n return;\n }\n\n if (attrs.height) {\n el.style.setProperty('--fp-globe-height', attrs.height);\n }\n\n new FootprintGlobe(el, {\n config,\n maplibreUrl: attrs.maplibreUrl,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n renderError(el, msg);\n }\n}\n\n/** 扫描并初始化所有未绑定的 .footprint-globe */\nexport function autoInit(root: ParentNode = document): void {\n const nodes = root.querySelectorAll<HTMLElement>(SELECTOR);\n nodes.forEach((el) => void initOne(el));\n}\n\n/** 引导入口:注册自定义元素 + 自动扫描 */\nexport function boot(): void {\n register();\n\n if (typeof document === 'undefined') return;\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => autoInit(), { once: true });\n } else {\n autoInit();\n }\n}\n","/**\n * 足迹地球 · auto 入口\n * 只做一件事:boot()\n * 用法:\n * <script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@footprint-studio/web-component@1/dist/auto.js\"></script>\n */\n\nimport { boot } from './auto-init';\n\nboot();\n"]}
|
package/dist/auto.d.cts
ADDED
package/dist/auto.d.ts
ADDED
package/dist/auto.js
ADDED
package/dist/auto.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auto-entry.ts"],"names":[],"mappings":";;;AASA,IAAA,EAAK","file":"auto.js","sourcesContent":["/**\n * 足迹地球 · auto 入口\n * 只做一件事:boot()\n * 用法:\n * <script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@footprint-studio/web-component@1/dist/auto.js\"></script>\n */\n\nimport { boot } from './auto-init';\n\nboot();\n"]}
|