gis-view-webgl2 0.1.0 → 0.1.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.
- package/README.md +40 -8
- package/dist/gis-view.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1036 -249
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +194 -0
- package/docs/GisView.md +9 -8
- package/docs/GisView/345/256/236/347/216/260/345/216/237/347/220/206.md +2 -2
- package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +172 -0
- package/docs/api/index.html +545 -59
- package/docs/demos/BackendSyncDemo.vue +10 -8
- package/docs/demos/BasicDemo.vue +101 -101
- package/docs/demos/BatchAddDemo.vue +5 -5
- package/docs/demos/ChannelDemo.vue +617 -10
- package/docs/demos/ConnectDemo.vue +392 -0
- package/docs/demos/CopyMergeDemo.vue +980 -929
- package/docs/demos/DecorationDraftDemo.vue +1300 -0
- package/docs/demos/DemoShell.vue +569 -240
- package/docs/demos/DragDropDemo.vue +11 -11
- package/docs/demos/EffectsDemo.vue +6 -6
- package/docs/demos/EventDemo.vue +327 -327
- package/docs/demos/ExtensionDemo.vue +458 -0
- package/docs/demos/GisViewDemo.vue +61 -48
- package/docs/demos/GraphicDemo.vue +338 -0
- package/docs/demos/LabelDemo.vue +553 -497
- package/docs/demos/MinimapDemo.vue +358 -0
- package/docs/demos/PerfDemo.vue +29 -0
- package/docs/demos/SearchFilterDemo.vue +412 -0
- package/docs/demos/StyleDemo.vue +121 -121
- package/docs/demos/api-index.js +98 -77
- package/docs/demos/demos.js +159 -135
- package/docs/demos/shared/demoData.js +107 -107
- package/docs/demos/shared/demoStyle.css +249 -249
- package/docs/demos/shared/fakeBackend.js +93 -6
- package/docs/format/03-/346/213/220/347/202/271/350/243/205/351/245/260/344/270/216/346/240/267/345/274/217.md +28 -8
- package/docs/format/04-/351/200/232/351/201/223/344/270/216/346/240/207/347/255/276.md +5 -4
- package/docs/format/06-/345/257/274/345/205/245/345/257/274/345/207/272/344/270/216/346/240/207/345/207/206/346/226/207/346/241/243.md +8 -6
- package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +6 -6
- package/docs/guide/sample-document.html +4 -4
- package/docs/index.html +180 -9
- package/docs/internals/11-/350/246/206/347/233/226/345/261/202/346/240/207/347/255/276/344/270/216/346/217/220/347/244/272.md +1 -1
- package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +3 -2
- package/docs/internals/15-03-/351/200/220/350/275/256/350/256/260/345/275/225-/346/200/247/350/203/275/344/270/216/344/277/256/345/244/215-/344/270/213.md +16 -0
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +11 -0
- package/docs/internals/17-/350/260/203/350/257/225/344/270/216/346/211/251/345/261/225/345/273/272/350/256/256.md +1 -1
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +18 -4
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +110 -25
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +13 -8
- package/docs/manual/06-/346/225/260/346/215/256/344/270/216/345/234/272/346/231/257/346/233/264/346/226/260.md +111 -10
- package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +47 -9
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +17 -15
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +61 -11
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +74 -7
- package/docs/manual/11-/346/240/267/345/274/217/344/270/216/350/247/204/345/210/231.md +3 -2
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +260 -3
- package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +6 -5
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +27 -14
- package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +142 -49
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +31 -29
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +55 -39
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +189 -64
- package/docs/manual/19-/350/257/273/346/225/260/344/270/216/346/213/226/346/213/275/351/242/204/350/247/210.md +4 -4
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +42 -2
- package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +22 -6
- package/docs/playground/index.html +5 -5
- package/docs/steps/README.md +14 -10
- package/docs/steps/check-doc-truth.mjs +1 -1
- package/docs/steps/selftest-actions.html +10 -10
- package/docs/steps/selftest-data.html +96 -14
- package/docs/steps/selftest-decoration.html +577 -0
- package/docs/steps/selftest-demo.html +6 -5
- package/docs/steps/selftest-demos.html +2201 -1612
- package/docs/steps/selftest-docs.html +89 -16
- package/docs/steps/selftest-effects.html +5 -5
- package/docs/steps/selftest-features.html +757 -86
- package/docs/steps/selftest-full.html +583 -583
- package/docs/steps/selftest-labels.html +1034 -652
- package/docs/steps/selftest-perf.html +1899 -1844
- package/docs/steps/selftest-scale.html +117 -7
- package/docs/steps/selftest-select.html +24 -17
- package/docs/steps/step-10-full.js +1 -1
- package/docs//346/216/245/345/217/243/345/215/217/350/256/256.md +167 -17
- package/docs//346/225/260/346/215/256/346/240/274/345/274/217.md +1 -1
- package/package.json +43 -43
- package/docs/demos/HistoryDemo.vue +0 -230
- package/docs/demos/InterfaceDemo.vue +0 -309
- package/docs/demos/SampleDemo.vue +0 -283
|
@@ -121,12 +121,19 @@
|
|
|
121
121
|
await Promise.race([api.ready, sleep(8000)])
|
|
122
122
|
const meta = doc.querySelector('#content .meta')
|
|
123
123
|
check('文档中心:首屏 README 渲染完(行数 / 体积读数 + 标题 + 目录)', Boolean(meta) && meta.textContent.includes('README') && doc.querySelectorAll('#content h1, #content h2').length >= 2 && doc.querySelectorAll('#toc nav a').length >= 3, meta ? meta.textContent.trim().slice(0, 72) : '8 s 还没读完')
|
|
124
|
+
const pathCards = [...doc.querySelectorAll('#content .doc-path')]
|
|
125
|
+
const pathDocs = pathCards.map(card => card.dataset.doc).filter(Boolean)
|
|
126
|
+
const apiPathCard = pathCards.find(card => card.textContent.includes('查方法与参数'))
|
|
127
|
+
check('文档中心:README 顶部有 4 条推荐阅读路径,3 篇文档加 API 页都指向真实目标', pathCards.length === 4 && pathDocs.length === 3 && pathDocs.every(file => files.includes(file)) && (apiPathCard?.getAttribute('href') ?? '').includes('api/index.html') && pathCards.every(card => card.querySelector('.doc-path__badge') && card.textContent.trim().length > 12), pathCards.map(card => card.querySelector('b')?.textContent?.trim()).join(' / '))
|
|
124
128
|
check('文档中心:正文链接的解析(相对「当前那份文档」算,解析不到给 null)', api.resolve('docs/GisView.md', '../README.md') === 'GisView.md' && api.resolve('../从0到完整的实现.md', 'steps/README.md') === '从0到完整的实现.md' && api.resolve('../index.html', 'README.md') === null)
|
|
125
|
-
const fixture = api.render('## 标题\n\n| A | B |\n| --- | --- |\n| 1 | 2 |\n\n```js\nconst a = 1\n```\n\n- 一级\n - 二级\n\n>
|
|
126
|
-
|
|
129
|
+
const fixture = api.render('# 文档标题\n\n> 一句话摘要\n\n## 标题\n\n| A | B |\n| --- | --- |\n| 1 | 2 |\n\n```js\nconst a = 1\n```\n\n- 一级\n - 二级\n\n> 正文引用\n\n行内 `code` 与 [链接](GisView.md)\n')
|
|
130
|
+
const leadFixture = api.render('# 只有导语\n\n第一段就是全文导语。\n')
|
|
131
|
+
check('文档中心:markdown 渲染器(标题 / 表格 / 带语言代码块 / 两级列表 / 引用 / 行内代码 / md 链接 / 目录)', fixture.html.includes('<table>') && fixture.html.includes('data-lang="js"') && (fixture.html.match(/<ul>/g) ?? []).length >= 2 && fixture.html.includes('<blockquote class="doc-summary">') && fixture.html.includes('<blockquote><p>正文引用</p></blockquote>') && fixture.html.includes('<code>code</code>') && fixture.html.includes('data-doc="GisView.md"') && fixture.toc.length === 1, `${fixture.html.length} 字符 / ${fixture.toc.length} 条目录`)
|
|
132
|
+
check('文档中心:H1 后的摘要 / 首段分别套导语卡片与导语段落', leadFixture.html.includes('<p class="doc-lead">第一段就是全文导语。</p>'), leadFixture.html.slice(0, 120))
|
|
127
133
|
await api.load('数据格式.md')
|
|
128
134
|
const meta2 = doc.querySelector('#content .meta')
|
|
129
135
|
const indexLinks = [...doc.querySelectorAll('#content a[data-doc]')]
|
|
136
|
+
check('文档中心:阅读路径只在 README 首屏出现,切到其他文档后移除', doc.querySelectorAll('#content .doc-path').length === 0)
|
|
130
137
|
check('文档中心:索引页(数据格式.md)把 7 份子文档都链上了,每条都解析到清单里的真文件', Boolean(meta2) && meta2.textContent.includes('数据格式.md') && indexLinks.length >= 7 && indexLinks.every(link => files.includes(api.resolve('数据格式.md', link.dataset.doc))), meta2 ? `${indexLinks.length} 条子文档链接 / ${doc.querySelectorAll('#toc nav a').length} 条目录` : '')
|
|
131
138
|
await api.load('format/07-事件载荷与示例数据.md')
|
|
132
139
|
check('文档中心:子文档(format/07)表格与目录都渲染出来(这一份没有围栏代码,全是缩进续行)', doc.querySelectorAll('#content table').length >= 4 && doc.querySelectorAll('#toc nav a').length >= 5, `${doc.querySelectorAll('#content table').length} 表 / ${doc.querySelectorAll('#toc nav a').length} 条目录`)
|
|
@@ -373,23 +380,25 @@
|
|
|
373
380
|
doc.documentElement.classList.contains('theme-dark') === Boolean(docsFrame.contentWindow.matchMedia('(prefers-color-scheme: dark)').matches))
|
|
374
381
|
const progressEl = doc.querySelector('#progress')
|
|
375
382
|
const backtopEl = doc.querySelector('#backtop')
|
|
383
|
+
const backtopPercentEl = doc.querySelector('#backtop-percent')
|
|
376
384
|
docsFrame.contentWindow.scrollTo(0, 4000)
|
|
377
385
|
api.syncScrollReadouts()
|
|
378
386
|
const scrolledWidth = progressEl.style.width
|
|
379
387
|
const backtopOn = backtopEl.classList.contains('on')
|
|
388
|
+
const scrolledPercent = backtopPercentEl?.textContent ?? ''
|
|
380
389
|
docsFrame.contentWindow.scrollTo(0, 0)
|
|
381
390
|
api.syncScrollReadouts()
|
|
382
391
|
check('文档中心:顶部进度条跟着滚动长、「回到顶部」滚下去才出现(回顶后收回去)',
|
|
383
392
|
scrolledWidth !== '' && scrolledWidth !== '0%' && scrolledWidth !== '0.00%' && backtopOn &&
|
|
384
|
-
parseFloat(progressEl.style.width || '0') === 0 && !backtopEl.classList.contains('on'),
|
|
385
|
-
`滚下去 ${scrolledWidth} / 回顶 ${progressEl.style.width} · 按钮 ${backtopOn ? '在' : '不在'}`)
|
|
393
|
+
parseInt(scrolledPercent, 10) > 0 && parseFloat(progressEl.style.width || '0') === 0 && backtopPercentEl?.textContent === '0%' && !backtopEl.classList.contains('on'),
|
|
394
|
+
`滚下去 ${scrolledWidth} / ${scrolledPercent} · 回顶 ${progressEl.style.width} · 数字 ${backtopPercentEl?.textContent} · 按钮 ${backtopOn ? '在' : '不在'}`)
|
|
386
395
|
/* ---- 这一轮加的:文档页的观感(侧栏计数 / 元信息胶囊 / 代码块头部 / 空态 / 「/」快捷键) ---- */
|
|
387
396
|
const counts = [doc.querySelector('#doc-count')?.textContent, doc.querySelector('#page-count')?.textContent]
|
|
388
397
|
check('文档中心:侧栏两个分组标题上挂着计数(数得跟清单一样)', counts[0] === String(api.docs.length) && counts[1] === String(api.pages.length), counts.join(' / '))
|
|
389
398
|
await api.load('GisView.md')
|
|
390
399
|
const chips = [...doc.querySelectorAll('#content .meta > *')]
|
|
391
|
-
check('文档中心:正文开头那行元信息是几枚胶囊(文件 / 行数 + 体积 / 小节数 / 代码块数 / 看原文)',
|
|
392
|
-
chips.length ===
|
|
400
|
+
check('文档中心:正文开头那行元信息是几枚胶囊(文件 / 行数 + 体积 / 阅读时长 / 小节数 / 代码块数 / 看原文)',
|
|
401
|
+
chips.length === 6 && chips[0].textContent === 'GisView.md' && /\d+ 行 \/ [\d.]+ KB/.test(chips[1].textContent) && /^约 \d+ 分钟$/.test(chips[2].textContent) && /\d+ 个小节/.test(chips[3].textContent) && /\d+ 段代码/.test(chips[4].textContent) && chips[5].textContent === '看原文',
|
|
393
402
|
chips.map(node => node.textContent).join(' | ').slice(0, 120))
|
|
394
403
|
check('文档中心:语言徽标与「复制」都收在代码块头部那一条里(一块只有一个按钮)',
|
|
395
404
|
[...doc.querySelectorAll('#content .code')].every(block => block.querySelector('.code-head > button') && block.querySelectorAll('button').length === 1),
|
|
@@ -409,6 +418,39 @@
|
|
|
409
418
|
searchInputEl.value = ''
|
|
410
419
|
searchInputEl.dispatchEvent(new Event('input', { bubbles: true }))
|
|
411
420
|
await api.load('README.md')
|
|
421
|
+
/* 390px 视口回归:窄屏时侧栏排在正文上方,首屏不能被 content.scrollIntoView 带过目录 */
|
|
422
|
+
const mobileFrame = document.createElement('iframe')
|
|
423
|
+
mobileFrame.title = '文档中心 390px'
|
|
424
|
+
mobileFrame.style.width = '390px'
|
|
425
|
+
mobileFrame.style.height = '760px'
|
|
426
|
+
mobileFrame.src = '../index.html?selftest=390'
|
|
427
|
+
document.body.append(mobileFrame)
|
|
428
|
+
const mobileReady = await waitFor(() => {
|
|
429
|
+
const win = mobileFrame.contentWindow
|
|
430
|
+
return win?.__gisDocs && mobileFrame.contentDocument?.querySelector('#content .meta') ? win : null
|
|
431
|
+
})
|
|
432
|
+
await sleep(350)
|
|
433
|
+
const mobileWin = mobileReady
|
|
434
|
+
const mobileDoc = mobileFrame.contentDocument
|
|
435
|
+
const initialScroll = mobileWin.scrollY
|
|
436
|
+
const initialOverflow = mobileDoc.documentElement.scrollWidth > mobileDoc.documentElement.clientWidth + 1
|
|
437
|
+
check('文档中心:390px 首屏停在页面顶部(不被正文 scrollIntoView 带过目录)', initialScroll === 0 && mobileWin.history.scrollRestoration === 'manual', `scrollY=${initialScroll} / ${mobileWin.history.scrollRestoration}`)
|
|
438
|
+
check('文档中心:390px 首屏无横向溢出', !initialOverflow && mobileWin.innerWidth < 941, `视口 ${mobileWin.innerWidth}px / ${mobileDoc.documentElement.scrollWidth}px`)
|
|
439
|
+
const deepUrl = new URL('../index.html?selftest=deep', location.href)
|
|
440
|
+
deepUrl.hash = `${encodeURIComponent('manual/15-导出与集成.md')}~${encodeURIComponent('插件')}`
|
|
441
|
+
const mobileReloaded = new Promise(resolve => mobileFrame.addEventListener('load', resolve, { once: true }))
|
|
442
|
+
mobileFrame.src = deepUrl.href
|
|
443
|
+
await mobileReloaded
|
|
444
|
+
const deepReady = await waitFor(() => {
|
|
445
|
+
const win = mobileFrame.contentWindow
|
|
446
|
+
return win?.__gisDocs && mobileFrame.contentDocument?.querySelector('[data-slug="插件"]') ? win : null
|
|
447
|
+
})
|
|
448
|
+
await sleep(350)
|
|
449
|
+
const deepDoc = mobileFrame.contentDocument
|
|
450
|
+
const deepTarget = deepDoc.querySelector('[data-slug="插件"]')
|
|
451
|
+
const deepTop = deepTarget?.getBoundingClientRect().top ?? -1
|
|
452
|
+
check('文档中心:390px 深链仍落到对应小节(顶栏下 72px)', deepReady.__gisDocs.current() === 'manual/15-导出与集成.md' && deepReady.scrollY > 0 && deepTop >= 60 && deepTop <= 90, `${deepReady.__gisDocs.current()} / scrollY=${Math.round(deepReady.scrollY)} / top=${Math.round(deepTop)}`)
|
|
453
|
+
mobileFrame.remove()
|
|
412
454
|
}
|
|
413
455
|
/* ---------------- 图解页:docs/guide/sample-document.html ---------------- */
|
|
414
456
|
const guideFrame = document.querySelector('#guide-frame')
|
|
@@ -476,21 +518,39 @@
|
|
|
476
518
|
if (check('API 速查:挂上了 __gisApi 钩子(数据来自 api-index.js,没钩子多半是 file:// 打开的)', Boolean(apiHook))) {
|
|
477
519
|
const apiDoc = apiFrame.contentDocument
|
|
478
520
|
const summary = apiHook.summary
|
|
479
|
-
check('API 速查:清单来自 api-index(
|
|
480
|
-
summary.members ===
|
|
521
|
+
check('API 速查:清单来自 api-index(249 个成员 / 92 个 options / 16 个分组)',
|
|
522
|
+
summary.members === 249 && summary.options === 92 && summary.sections === 16,
|
|
481
523
|
JSON.stringify(summary))
|
|
482
|
-
check('API
|
|
483
|
-
|
|
524
|
+
check('API 速查:左侧分组有当前项,滚动 / 点选时会跟着亮', apiHook.activeGroup() !== null, String(apiHook.activeGroup()))
|
|
525
|
+
check('API 速查:分组都渲染出来(16 组 + options 一组)',
|
|
526
|
+
apiDoc.querySelectorAll('.api-group').length === 17 && apiDoc.querySelectorAll('.api-group > h2 b').length === 17,
|
|
484
527
|
`${apiDoc.querySelectorAll('.api-group').length} 组`)
|
|
485
528
|
check('API 速查:成员卡片全在(方法与属性按清单来)',
|
|
486
529
|
apiDoc.querySelectorAll('.api-member').length === summary.members && apiDoc.querySelectorAll('.api-member[data-kind="property"]').length === summary.properties,
|
|
487
530
|
`${apiDoc.querySelectorAll('.api-member').length} 张卡片 / 属性 ${apiDoc.querySelectorAll('.api-member[data-kind="property"]').length} 张`)
|
|
488
531
|
const noExample = [...apiDoc.querySelectorAll('.api-member')].filter(node => Number(node.dataset.examples) < 1)
|
|
489
532
|
check('API 速查:每个成员都带至少一段示例(不出现空卡片)', noExample.length === 0,
|
|
490
|
-
noExample.length ? noExample.map(node => node.dataset.name).join(' / ') : '
|
|
491
|
-
check('API 速查:
|
|
533
|
+
noExample.length ? noExample.map(node => node.dataset.name).join(' / ') : '249 张卡片都有示例')
|
|
534
|
+
check('API 速查:92 个 options 都列全(名字 / 类型 / 默认值 / 说明四件套)',
|
|
492
535
|
apiDoc.querySelectorAll('.api-option').length === summary.options && [...apiDoc.querySelectorAll('.api-option')].every(node => node.querySelector('.name code') && node.querySelector('.type') && node.querySelector('.def') && node.querySelector('.doc')),
|
|
493
536
|
`${apiDoc.querySelectorAll('.api-option').length} 个`)
|
|
537
|
+
const statCards = [...apiDoc.querySelectorAll('#stats .api-stat')]
|
|
538
|
+
const optionStat = statCards.find(node => node.dataset.stat === 'options')
|
|
539
|
+
check('API 速查:首屏统计卡为六张,options 卡读数与清单一致',
|
|
540
|
+
statCards.length === 6 && statCards.map(node => node.dataset.stat).join(',') === 'members,methods,properties,options,sections,examples' && (optionStat?.textContent ?? '').includes(String(summary.options)),
|
|
541
|
+
`${statCards.length} 张 / ${optionStat?.textContent ?? '缺 options 卡'}`)
|
|
542
|
+
const optionHead = apiDoc.querySelector('.option-table > .option-head')
|
|
543
|
+
check('API 速查:options 用四列表头(字段 / 类型 / 默认值 / 说明)',
|
|
544
|
+
optionHead?.children.length === 4 && [...optionHead.children].map(node => node.textContent).join(',') === '字段,类型,默认值,说明',
|
|
545
|
+
`${optionHead?.children.length ?? 0} 列`)
|
|
546
|
+
check('API 速查:成员卡片都带参数 / 返回签名网格',
|
|
547
|
+
apiDoc.querySelectorAll('.api-member .signature-grid').length === summary.members && [...apiDoc.querySelectorAll('.api-member .signature-grid')].every(node => node.children.length === 2),
|
|
548
|
+
`${apiDoc.querySelectorAll('.api-member .signature-grid').length} 张`)
|
|
549
|
+
const memberExamples = [...apiDoc.querySelectorAll('.api-member .example')]
|
|
550
|
+
check('API 速查:示例改为可折叠 details,首段默认展开且仍保留运行按钮',
|
|
551
|
+
memberExamples.length > 0 && memberExamples.every(node => node.tagName === 'DETAILS') && memberExamples[0]?.open === true &&
|
|
552
|
+
apiDoc.querySelectorAll('.api-member .example .try-code').length === memberExamples.length,
|
|
553
|
+
`${memberExamples.length} 段 / 首段展开 ${memberExamples[0]?.open === true}`)
|
|
494
554
|
check('API 速查:代码块带高亮,每段示例都有复制按钮',
|
|
495
555
|
apiDoc.querySelectorAll('.example pre code .tok-fn').length > 0 && [...apiDoc.querySelectorAll('.example')].every(node => node.querySelector('button')),
|
|
496
556
|
`${apiDoc.querySelectorAll('.example').length} 段示例`)
|
|
@@ -529,6 +589,18 @@
|
|
|
529
589
|
apiDoc.querySelectorAll('.api-member .try-code').length === apiDoc.querySelectorAll('.api-member .example').length &&
|
|
530
590
|
apiOpens.length === 1 && apiOpens[0].includes('playground/index.html?from=api') && stashed.includes('updateLine'),
|
|
531
591
|
`${apiDoc.querySelectorAll('.api-member .try-code').length} 个按钮 / ${apiOpens.join(',')}`)
|
|
592
|
+
const themeBefore = apiHook.theme()
|
|
593
|
+
apiHook.setTheme('dark')
|
|
594
|
+
await settle(apiFrame.contentWindow, 1)
|
|
595
|
+
const darkThemeApplied = apiDoc.documentElement.classList.contains('theme-dark') && apiDoc.querySelector('#theme-btn')?.textContent === '主题:深色'
|
|
596
|
+
const storedTheme = JSON.parse(apiFrame.contentWindow.localStorage.getItem('gisDocs.reading') ?? 'null')?.theme
|
|
597
|
+
apiHook.setTheme('light')
|
|
598
|
+
await settle(apiFrame.contentWindow, 1)
|
|
599
|
+
const lightThemeApplied = !apiDoc.documentElement.classList.contains('theme-dark') && apiDoc.querySelector('#theme-btn')?.textContent === '主题:浅色'
|
|
600
|
+
apiHook.setTheme(themeBefore)
|
|
601
|
+
check('API 速查:深 / 浅主题切换生效并写进文档中心共用的阅读设置',
|
|
602
|
+
darkThemeApplied && lightThemeApplied && storedTheme === 'dark',
|
|
603
|
+
`深色 ${darkThemeApplied} / 浅色 ${lightThemeApplied} / 存储 ${storedTheme}`)
|
|
532
604
|
}
|
|
533
605
|
/* ---------------- 调试演示页:docs/playground/index.html ---------------- */
|
|
534
606
|
const playFrame = document.querySelector('#playground-frame')
|
|
@@ -540,7 +612,7 @@
|
|
|
540
612
|
Boolean(playView) && playView.getData().points.length === 3 && playView.getData().lines.length === 3 && playView.getChannels().length === 2,
|
|
541
613
|
`${playView?.getData().points.length} 点 / ${playView?.getChannels().length} 组`)
|
|
542
614
|
check('调试演示页:示例下拉有货,编辑器默认载入欢迎示例', playHook.sampleNames().length >= 5 && (playHook.getCode() ?? '').includes('view.'), `${playHook.sampleNames().length} 个示例`)
|
|
543
|
-
await playHook.run('view.
|
|
615
|
+
await playHook.run('view.updatePoint(\'a\', { color: \'#123456\' })\nview.getData().points.length')
|
|
544
616
|
await settle(playFrame.contentWindow, 1)
|
|
545
617
|
const playOut = playDoc.querySelector('#out').textContent
|
|
546
618
|
check('调试演示页:run(code) 改到真实视图,最后一行返回值打在输出区',
|
|
@@ -550,12 +622,13 @@
|
|
|
550
622
|
await settle(playFrame.contentWindow, 1)
|
|
551
623
|
const playErr = playDoc.querySelector('#out').textContent
|
|
552
624
|
check('调试演示页:代码报错打在输出区(红字 + 不炸整页)', playErr.includes('noSuchMethod') && playDoc.querySelector('#out .err') !== null, playErr.split('\n')[0])
|
|
625
|
+
const playCanvasCount = playDoc.querySelectorAll('#map canvas').length
|
|
553
626
|
await playHook.run('createGisView(\'#map\', {})\nview.getData().points.length')
|
|
554
627
|
await settle(playFrame.contentWindow, 1)
|
|
555
628
|
check('调试演示页:示例里的 createGisView(\'#map\') 沿用右边这份视图(不会新开一块画布)',
|
|
556
|
-
playDoc.querySelectorAll('#map canvas').length ===
|
|
557
|
-
`画布 ${playDoc.querySelectorAll('#map canvas').length} 块`)
|
|
558
|
-
playHook.setCode('view.
|
|
629
|
+
playDoc.querySelectorAll('#map canvas').length === playCanvasCount && (playDoc.querySelector('#out').textContent ?? '').includes('3'),
|
|
630
|
+
`画布 ${playCanvasCount} → ${playDoc.querySelectorAll('#map canvas').length} 块`)
|
|
631
|
+
playHook.setCode('view.updatePoint(\'b\', { color: \'#00aa88\' })')
|
|
559
632
|
check('调试演示页:setCode 换编辑器内容(深链 #code= 与 API 页带过来的代码都走它)', playHook.getCode().includes('00aa88'))
|
|
560
633
|
playHook.reset()
|
|
561
634
|
await settle(playFrame.contentWindow, 1)
|
|
@@ -284,19 +284,19 @@
|
|
|
284
284
|
JSON.stringify({ point: stats.pointEffectCount, line: stats.lineEffectCount }))
|
|
285
285
|
const still = view.getEffects()
|
|
286
286
|
check('关掉一层之后 getEffects 读得出来(point 为 null)', still.point === null && still.line.period === 1, JSON.stringify({ point: still.point, period: still.line?.period }))
|
|
287
|
-
view.
|
|
287
|
+
view.updateOptions({ effects: false })
|
|
288
288
|
await advance(60, 2)
|
|
289
289
|
stats = view.getStats()
|
|
290
|
-
check('
|
|
290
|
+
check('effects: false 一处关掉:动点与涟漪都收掉、动画停下',
|
|
291
291
|
stats.lineEffectCount === 0 && stats.pointEffectCount === 0 && stats.animating === false && view.getLineEffects().length === 0,
|
|
292
292
|
JSON.stringify({ line: stats.lineEffectCount, point: stats.pointEffectCount, animating: stats.animating }))
|
|
293
293
|
check('总开关关着时 getEffects.enabled 为 false', view.getEffects().enabled === false)
|
|
294
|
-
view.
|
|
294
|
+
view.updateOptions({ effects: { line: { period: 1 }, point: { radius: 18 } } })
|
|
295
295
|
await advance(60, 2)
|
|
296
296
|
stats = view.getStats()
|
|
297
297
|
check('再次打开:动点与涟漪都回来', stats.lineEffectCount === 1 && stats.pointEffectCount === 3,
|
|
298
298
|
JSON.stringify({ line: stats.lineEffectCount, point: stats.pointEffectCount }))
|
|
299
|
-
check('getOptions 与
|
|
299
|
+
check('getOptions 与 updateOptions({ effects }) 一致(配置记进了 current)', view.getOptions().effects?.line?.period === 1, JSON.stringify(view.getOptions().effects?.line?.period))
|
|
300
300
|
|
|
301
301
|
/* ---------------- 引擎:全局什么都不配,只在数据里逐条配 ---------------- */
|
|
302
302
|
// 需求里的第二种写法:不动全局缺省,写在哪条上哪条就动(全局没配不代表关掉)
|
|
@@ -317,7 +317,7 @@
|
|
|
317
317
|
const soloEffects = solo.getEffects()
|
|
318
318
|
check('这一份的 getEffects:总开关为真、两层缺省都是 null(画什么全看逐要素)',
|
|
319
319
|
soloEffects.enabled === true && soloEffects.line === null && soloEffects.point === null, JSON.stringify(soloEffects))
|
|
320
|
-
solo.
|
|
320
|
+
solo.updateOptions({ effects: false })
|
|
321
321
|
await advance(60, 2)
|
|
322
322
|
check('显式 effects: false 连逐要素配的一起关掉(一处关掉的语义)',
|
|
323
323
|
solo.getStats().lineEffectCount === 0 && solo.getStats().pointEffectCount === 0 && solo.getStats().animating === false,
|