This commit is contained in:
33333-33333 2026-07-20 14:36:59 +09:00
commit f6d7412744
94 changed files with 3836 additions and 1226 deletions

View file

@ -1,7 +1,5 @@
"use strict";
function escapeHtml(value) { return window.TarinaiUIHelpers.htmlEscape(value); }
function lineageSplitByActualEdges(component) {
const family = lineageEdgeFamily(world.family || {});
const nodes = Array.from(new Map(lineageCleanComponent(component, family).filter(Boolean).map(n => [n.id, n])).values());
@ -116,7 +114,7 @@ function lineageFamilyHtml(component, index, family, signature = "") {
const nodeHtml = layout.nodes.map(p => lineageTreeNodeHtml(p.node, p.x, p.y)).join("");
const empty = !layout.childLinks.length ? `<div class="lineage-empty-family">\u89aa\u5b50\u95a2\u4fc2\u306e\u7dda\u306f\u307e\u3060\u3042\u308a\u307e\u305b\u3093\u3002</div>` : "";
const html = `<section class="lineage-family lineage-family-tree" data-lineage-key="${escapeHtml(cacheKey)}">
const html = `<section class="lineage-family lineage-family-tree" data-lineage-key="${window.TarinaiUIHelpers.htmlEscape(cacheKey)}">
<h3>\u5bb6\u7cfb {{LINEAGE_INDEX}} / ${uniqueComponent.length}\u5339 / \u751f\u5b58 ${aliveCount}</h3>
<div class="lineage-tree-panel" style="width:${Math.ceil(layout.width)}px;height:${Math.ceil(layout.height)}px">
<svg class="lineage-links" viewBox="0 0 ${Math.ceil(layout.width)} ${Math.ceil(layout.height)}" aria-hidden="true">
@ -134,10 +132,11 @@ function lineageFamilyHtml(component, index, family, signature = "") {
function lineageArchiveNeedsRender() {
const familyVersion = world.familyVersion || 0;
const familyDirty = Boolean(world.familyTreeDirty);
// A cancelled/cleared DOM must never make the family view permanently blank
// merely because the cached data version still matches the world.
const hasSnapshot = Boolean(ui.archiveContent?.firstElementChild);
return !hasSnapshot || !uiCache.archiveVersion || uiCache.archiveFamilyVersion !== familyVersion || familyDirty;
// Only a completed tree or completed empty-state counts as a usable snapshot.
// A preparation/status shell left by an interrupted async render must be rebuilt.
const hasCompletedSnapshot = Boolean(ui.archiveContent?.querySelector?.(".lineage-family-tree, .selected-info.empty"));
const renderingNow = Boolean(uiCache.archiveRenderRunning && ui.archiveContent?.querySelector?.(".lineage-render-status"));
return (!hasCompletedSnapshot && !renderingNow) || !uiCache.archiveVersion || uiCache.archiveFamilyVersion !== familyVersion || familyDirty;
}
function lineageDeferArchiveIfOffscreen(hiddenInterval = 30000) {
@ -216,7 +215,8 @@ function renderArchive(options = {}) {
}
const family = world.family || {};
const version = String(world.familyVersion || 0);
if (uiCache.archiveVersion === version) {
const hasArchiveSnapshot = Boolean(ui.archiveContent?.querySelector?.(".lineage-family-tree, .selected-info.empty"));
if (uiCache.archiveVersion === version && hasArchiveSnapshot && !familyDirty) {
world.familyTreeDirty = false;
uiCache.archivePendingDirtyAfterRun = false;
return;