doc-survival-kit 2.0.0 → 3.1.1
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/diagram/diagrams.js +240 -0
- package/diagram/events.js +603 -0
- package/diagram/globals.js +137 -0
- package/diagram/links.js +141 -0
- package/diagram/persistence.js +295 -0
- package/diagram/render.js +633 -0
- package/diagram/shape-ops.js +236 -0
- package/diagram/text-edit.js +292 -0
- package/diagram.html +8 -1
- package/package.json +9 -9
- package/diagram.js +0 -2556
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// ══════════════════════════════════════
|
|
2
|
+
// diagrams.js — Arbre de diagrammes et gestion de la barre latérale
|
|
3
|
+
// ══════════════════════════════════════
|
|
4
|
+
|
|
5
|
+
function findDiagramById(id, list) {
|
|
6
|
+
if (!list) return null;
|
|
7
|
+
for (var i = 0; i < list.length; i++) {
|
|
8
|
+
if (String(list[i].id) === String(id)) return list[i];
|
|
9
|
+
var found = findDiagramById(id, list[i].children);
|
|
10
|
+
if (found) return found;
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function findParentListOf(id, list) {
|
|
16
|
+
if (!list) return null;
|
|
17
|
+
for (var i = 0; i < list.length; i++) {
|
|
18
|
+
if (String(list[i].id) === String(id)) return { list: list, index: i };
|
|
19
|
+
var found = findParentListOf(id, list[i].children);
|
|
20
|
+
if (found) return found;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function flattenDiagrams(list, result) {
|
|
26
|
+
result = result || [];
|
|
27
|
+
(list || []).forEach(function (d) {
|
|
28
|
+
result.push(d);
|
|
29
|
+
flattenDiagrams(d.children, result);
|
|
30
|
+
});
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function calcMaxExpandedDepth(list, depth) {
|
|
35
|
+
var max = depth;
|
|
36
|
+
(list || []).forEach(function (d) {
|
|
37
|
+
if (d.children && d.children.length > 0 && diagExpandedIds[String(d.id)]) {
|
|
38
|
+
var childMax = calcMaxExpandedDepth(d.children, depth + 1);
|
|
39
|
+
max = Math.max(max, childMax);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return max;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function updateSidebarWidth() {
|
|
46
|
+
var depth = calcMaxExpandedDepth(diagramsList, 0);
|
|
47
|
+
var totalW = 220 + depth * 14;
|
|
48
|
+
var panel = document.getElementById("diagramListPanel");
|
|
49
|
+
if (!panel) return;
|
|
50
|
+
panel.style.width = totalW + "px";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getAncestorPath(targetId, list, path) {
|
|
54
|
+
path = path || [];
|
|
55
|
+
for (var i = 0; i < (list || []).length; i++) {
|
|
56
|
+
var d = list[i];
|
|
57
|
+
if (String(d.id) === String(targetId)) return path;
|
|
58
|
+
var childPath = getAncestorPath(targetId, d.children, path.concat([String(d.id)]));
|
|
59
|
+
if (childPath !== null) return childPath;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getCurrentDiagram() {
|
|
65
|
+
if (currentDiagramId !== null) {
|
|
66
|
+
var found = findDiagramById(currentDiagramId, diagramsList);
|
|
67
|
+
if (found) return found;
|
|
68
|
+
}
|
|
69
|
+
return diagramsList[0] || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function updateBackBtn() {
|
|
73
|
+
var btn = document.getElementById("btnDiagBack");
|
|
74
|
+
if (!btn) return;
|
|
75
|
+
btn.style.display = diagNavStack.length > 0 ? "inline-flex" : "none";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function selectDiagramme(id, clearStack) {
|
|
79
|
+
if (clearStack) diagNavStack = [];
|
|
80
|
+
saveCurrentZoom();
|
|
81
|
+
saveCurrentLock();
|
|
82
|
+
currentDiagramId = String(id);
|
|
83
|
+
localStorage.setItem("current_diagram_id", String(id));
|
|
84
|
+
selectedId = null; selectedType = null;
|
|
85
|
+
selectedIds = [];
|
|
86
|
+
pendingNavDiagId = null;
|
|
87
|
+
restoreZoomForDiagram(id);
|
|
88
|
+
restoreLockForDiagram(id);
|
|
89
|
+
viewTransform.x = 60;
|
|
90
|
+
viewTransform.y = 60;
|
|
91
|
+
document.getElementById("colorPanel").style.display = "none";
|
|
92
|
+
renderAll();
|
|
93
|
+
updateLockBtn();
|
|
94
|
+
updateBackBtn();
|
|
95
|
+
document.getElementById("diagramListPanel").classList.remove("open");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function goBackDiagram() {
|
|
99
|
+
if (diagNavStack.length === 0) return;
|
|
100
|
+
var prevId = diagNavStack.pop();
|
|
101
|
+
selectDiagramme(prevId);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function creerDiagramme() {
|
|
105
|
+
pendingParentId = null;
|
|
106
|
+
pendingNewDiagram = true;
|
|
107
|
+
var input = document.getElementById("diagramTitle");
|
|
108
|
+
input.value = "";
|
|
109
|
+
input.placeholder = window.t ? window.t.diag_new_diagram : "Nouveau diagramme";
|
|
110
|
+
input.focus();
|
|
111
|
+
input.select();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function creerEnfantDiagramme(parentId) {
|
|
115
|
+
pendingParentId = String(parentId);
|
|
116
|
+
pendingNewDiagram = true;
|
|
117
|
+
diagExpandedIds[String(parentId)] = true;
|
|
118
|
+
var input = document.getElementById("diagramTitle");
|
|
119
|
+
input.value = "";
|
|
120
|
+
input.placeholder = window.t ? window.t.diag_new_diagram : "Nouveau diagramme";
|
|
121
|
+
input.focus();
|
|
122
|
+
input.select();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function confirmerNouveauDiagramme() {
|
|
126
|
+
if (!pendingNewDiagram) return;
|
|
127
|
+
pendingNewDiagram = false;
|
|
128
|
+
var input = document.getElementById("diagramTitle");
|
|
129
|
+
var titre = input.value.trim() || (window.t ? window.t.diag_new_diagram : "Nouveau diagramme");
|
|
130
|
+
input.placeholder = "";
|
|
131
|
+
var d = { id: Date.now(), titre: titre, shapes: [], arrows: [], children: [] };
|
|
132
|
+
if (pendingParentId) {
|
|
133
|
+
var parent = findDiagramById(pendingParentId, diagramsList);
|
|
134
|
+
if (parent) {
|
|
135
|
+
if (!parent.children) parent.children = [];
|
|
136
|
+
parent.children.push(d);
|
|
137
|
+
} else {
|
|
138
|
+
diagramsList.push(d);
|
|
139
|
+
}
|
|
140
|
+
pendingParentId = null;
|
|
141
|
+
} else {
|
|
142
|
+
diagramsList.push(d);
|
|
143
|
+
}
|
|
144
|
+
saveDiagrammes();
|
|
145
|
+
selectDiagramme(d.id);
|
|
146
|
+
document.getElementById("diagramTitle").blur();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function annulerNouveauDiagramme() {
|
|
150
|
+
if (!pendingNewDiagram) return;
|
|
151
|
+
pendingNewDiagram = false;
|
|
152
|
+
var diag = getCurrentDiagram();
|
|
153
|
+
var input = document.getElementById("diagramTitle");
|
|
154
|
+
input.value = diag ? diag.titre : "";
|
|
155
|
+
input.placeholder = "";
|
|
156
|
+
input.blur();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function supprimerDiagramme(id) {
|
|
160
|
+
var info = findParentListOf(id, diagramsList);
|
|
161
|
+
if (!info) return;
|
|
162
|
+
if (info.list === diagramsList && info.list.length <= 1) return;
|
|
163
|
+
pushHistory();
|
|
164
|
+
info.list.splice(info.index, 1);
|
|
165
|
+
if (!findDiagramById(currentDiagramId, diagramsList)) {
|
|
166
|
+
currentDiagramId = diagramsList[0] ? String(diagramsList[0].id) : null;
|
|
167
|
+
localStorage.setItem("current_diagram_id", currentDiagramId || "");
|
|
168
|
+
}
|
|
169
|
+
saveDiagrammes();
|
|
170
|
+
renderAll();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function toggleDiagramList() {
|
|
174
|
+
var panel = document.getElementById("diagramListPanel");
|
|
175
|
+
var isOpening = !panel.classList.contains("open");
|
|
176
|
+
panel.classList.toggle("open");
|
|
177
|
+
if (isOpening && currentDiagramId) {
|
|
178
|
+
var path = getAncestorPath(currentDiagramId, diagramsList);
|
|
179
|
+
if (path) {
|
|
180
|
+
path.forEach(function (id) { diagExpandedIds[id] = true; });
|
|
181
|
+
renderDiagramList();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function toggleDiagExpand(id) {
|
|
187
|
+
var key = String(id);
|
|
188
|
+
if (diagExpandedIds[key]) {
|
|
189
|
+
delete diagExpandedIds[key];
|
|
190
|
+
} else {
|
|
191
|
+
diagExpandedIds[key] = true;
|
|
192
|
+
}
|
|
193
|
+
renderDiagramList();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function renderDiagramListLevel(list, depth) {
|
|
197
|
+
return (list || []).map(function (d) {
|
|
198
|
+
var isActive = String(d.id) === String(currentDiagramId);
|
|
199
|
+
var isExpanded = !!diagExpandedIds[String(d.id)];
|
|
200
|
+
var hasChildren = d.children && d.children.length > 0;
|
|
201
|
+
var indent = 10 + depth * 14;
|
|
202
|
+
var childrenHtml = (isExpanded && hasChildren)
|
|
203
|
+
? '<div class="diagram-list-children">' + renderDiagramListLevel(d.children, depth + 1) + '</div>'
|
|
204
|
+
: '';
|
|
205
|
+
return (
|
|
206
|
+
'<div class="diagram-list-group">' +
|
|
207
|
+
'<div class="diagram-list-item' + (isActive ? ' active' : '') + '"' +
|
|
208
|
+
' style="padding-left:' + indent + 'px"' +
|
|
209
|
+
' onclick="selectDiagramme(\'' + d.id + '\', true)">' +
|
|
210
|
+
'<span class="diagram-list-expand" onclick="event.stopPropagation();toggleDiagExpand(\'' + d.id + '\')">' +
|
|
211
|
+
(hasChildren ? (isExpanded ? '▼' : '►') : '<span style="display:inline-block;width:0.7em"></span>') +
|
|
212
|
+
'</span>' +
|
|
213
|
+
'<span class="diagram-list-name">' + escDiag(d.titre) + '</span>' +
|
|
214
|
+
'<button class="diagram-list-add" onclick="event.stopPropagation();creerEnfantDiagramme(\'' + d.id + '\')" title="Ajouter un diagramme enfant">+</button>' +
|
|
215
|
+
(depth > 0 || list.length > 1
|
|
216
|
+
? '<button class="diagram-list-del" onclick="event.stopPropagation();supprimerDiagramme(\'' + d.id + '\')">×</button>'
|
|
217
|
+
: '') +
|
|
218
|
+
'</div>' +
|
|
219
|
+
childrenHtml +
|
|
220
|
+
'</div>'
|
|
221
|
+
);
|
|
222
|
+
}).join('');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function renderDiagramList() {
|
|
226
|
+
var el = document.getElementById("diagramList");
|
|
227
|
+
if (!el) return;
|
|
228
|
+
el.innerHTML = renderDiagramListLevel(diagramsList, 0);
|
|
229
|
+
updateSidebarWidth();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ── Renommer le diagramme ──
|
|
233
|
+
function onTitleChange() {
|
|
234
|
+
if (pendingNewDiagram) return;
|
|
235
|
+
var diag = getCurrentDiagram();
|
|
236
|
+
if (!diag) return;
|
|
237
|
+
diag.titre = document.getElementById("diagramTitle").value || "Diagramme";
|
|
238
|
+
saveDiagrammes();
|
|
239
|
+
renderDiagramList();
|
|
240
|
+
}
|