markmap-view 0.15.0-alpha.0 → 0.15.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/dist/index.mjs DELETED
@@ -1,1250 +0,0 @@
1
- /*! markmap-view v0.15.0-alpha.0 | MIT License */
2
- import { Hook, getId, addClass, walkTree, childSelector, noop } from 'markmap-common';
3
- export { loadCSS, loadJS } from 'markmap-common';
4
- import * as d3 from 'd3';
5
-
6
- function _extends() {
7
- _extends = Object.assign ? Object.assign.bind() : function (target) {
8
- for (var i = 1; i < arguments.length; i++) {
9
- var source = arguments[i];
10
- for (var key in source) {
11
- if (Object.prototype.hasOwnProperty.call(source, key)) {
12
- target[key] = source[key];
13
- }
14
- }
15
- }
16
- return target;
17
- };
18
- return _extends.apply(this, arguments);
19
- }
20
-
21
- function count(node) {
22
- var sum = 0,
23
- children = node.children,
24
- i = children && children.length;
25
- if (!i) sum = 1;else while (--i >= 0) sum += children[i].value;
26
- node.value = sum;
27
- }
28
- function node_count () {
29
- return this.eachAfter(count);
30
- }
31
-
32
- function node_each (callback) {
33
- var node = this,
34
- current,
35
- next = [node],
36
- children,
37
- i,
38
- n;
39
- do {
40
- current = next.reverse(), next = [];
41
- while (node = current.pop()) {
42
- callback(node), children = node.children;
43
- if (children) for (i = 0, n = children.length; i < n; ++i) {
44
- next.push(children[i]);
45
- }
46
- }
47
- } while (next.length);
48
- return this;
49
- }
50
-
51
- function node_eachBefore (callback) {
52
- var node = this,
53
- nodes = [node],
54
- children,
55
- i;
56
- while (node = nodes.pop()) {
57
- callback(node), children = node.children;
58
- if (children) for (i = children.length - 1; i >= 0; --i) {
59
- nodes.push(children[i]);
60
- }
61
- }
62
- return this;
63
- }
64
-
65
- function node_eachAfter (callback) {
66
- var node = this,
67
- nodes = [node],
68
- next = [],
69
- children,
70
- i,
71
- n;
72
- while (node = nodes.pop()) {
73
- next.push(node), children = node.children;
74
- if (children) for (i = 0, n = children.length; i < n; ++i) {
75
- nodes.push(children[i]);
76
- }
77
- }
78
- while (node = next.pop()) {
79
- callback(node);
80
- }
81
- return this;
82
- }
83
-
84
- function node_sum (value) {
85
- return this.eachAfter(function (node) {
86
- var sum = +value(node.data) || 0,
87
- children = node.children,
88
- i = children && children.length;
89
- while (--i >= 0) sum += children[i].value;
90
- node.value = sum;
91
- });
92
- }
93
-
94
- function node_sort (compare) {
95
- return this.eachBefore(function (node) {
96
- if (node.children) {
97
- node.children.sort(compare);
98
- }
99
- });
100
- }
101
-
102
- function node_path (end) {
103
- var start = this,
104
- ancestor = leastCommonAncestor(start, end),
105
- nodes = [start];
106
- while (start !== ancestor) {
107
- start = start.parent;
108
- nodes.push(start);
109
- }
110
- var k = nodes.length;
111
- while (end !== ancestor) {
112
- nodes.splice(k, 0, end);
113
- end = end.parent;
114
- }
115
- return nodes;
116
- }
117
- function leastCommonAncestor(a, b) {
118
- if (a === b) return a;
119
- var aNodes = a.ancestors(),
120
- bNodes = b.ancestors(),
121
- c = null;
122
- a = aNodes.pop();
123
- b = bNodes.pop();
124
- while (a === b) {
125
- c = a;
126
- a = aNodes.pop();
127
- b = bNodes.pop();
128
- }
129
- return c;
130
- }
131
-
132
- function node_ancestors () {
133
- var node = this,
134
- nodes = [node];
135
- while (node = node.parent) {
136
- nodes.push(node);
137
- }
138
- return nodes;
139
- }
140
-
141
- function node_descendants () {
142
- var nodes = [];
143
- this.each(function (node) {
144
- nodes.push(node);
145
- });
146
- return nodes;
147
- }
148
-
149
- function node_leaves () {
150
- var leaves = [];
151
- this.eachBefore(function (node) {
152
- if (!node.children) {
153
- leaves.push(node);
154
- }
155
- });
156
- return leaves;
157
- }
158
-
159
- function node_links () {
160
- var root = this,
161
- links = [];
162
- root.each(function (node) {
163
- if (node !== root) {
164
- // Don’t include the root’s parent, if any.
165
- links.push({
166
- source: node.parent,
167
- target: node
168
- });
169
- }
170
- });
171
- return links;
172
- }
173
-
174
- function hierarchy(data, children) {
175
- var root = new Node$1(data),
176
- valued = +data.value && (root.value = data.value),
177
- node,
178
- nodes = [root],
179
- child,
180
- childs,
181
- i,
182
- n;
183
- if (children == null) children = defaultChildren;
184
- while (node = nodes.pop()) {
185
- if (valued) node.value = +node.data.value;
186
- if ((childs = children(node.data)) && (n = childs.length)) {
187
- node.children = new Array(n);
188
- for (i = n - 1; i >= 0; --i) {
189
- nodes.push(child = node.children[i] = new Node$1(childs[i]));
190
- child.parent = node;
191
- child.depth = node.depth + 1;
192
- }
193
- }
194
- }
195
- return root.eachBefore(computeHeight);
196
- }
197
- function node_copy() {
198
- return hierarchy(this).eachBefore(copyData);
199
- }
200
- function defaultChildren(d) {
201
- return d.children;
202
- }
203
- function copyData(node) {
204
- node.data = node.data.data;
205
- }
206
- function computeHeight(node) {
207
- var height = 0;
208
- do node.height = height; while ((node = node.parent) && node.height < ++height);
209
- }
210
- function Node$1(data) {
211
- this.data = data;
212
- this.depth = this.height = 0;
213
- this.parent = null;
214
- }
215
- Node$1.prototype = hierarchy.prototype = {
216
- constructor: Node$1,
217
- count: node_count,
218
- each: node_each,
219
- eachAfter: node_eachAfter,
220
- eachBefore: node_eachBefore,
221
- sum: node_sum,
222
- sort: node_sort,
223
- path: node_path,
224
- ancestors: node_ancestors,
225
- descendants: node_descendants,
226
- leaves: node_leaves,
227
- links: node_links,
228
- copy: node_copy
229
- };
230
-
231
- var version = "2.1.1";
232
-
233
- const defaults = Object.freeze({
234
- children: data => data.children,
235
- nodeSize: node => node.data.size,
236
- spacing: 0
237
- });
238
-
239
- // Create a layout function with customizable options. Per D3-style, the
240
- // options can be set at any time using setter methods. The layout function
241
- // will compute the tree node positions based on the options in effect at the
242
- // time it is called.
243
- function flextree(options) {
244
- const opts = Object.assign({}, defaults, options);
245
- function accessor(name) {
246
- const opt = opts[name];
247
- return typeof opt === 'function' ? opt : () => opt;
248
- }
249
- function layout(tree) {
250
- const wtree = wrap(getWrapper(), tree, node => node.children);
251
- wtree.update();
252
- return wtree.data;
253
- }
254
- function getFlexNode() {
255
- const nodeSize = accessor('nodeSize');
256
- const spacing = accessor('spacing');
257
- return class FlexNode extends hierarchy.prototype.constructor {
258
- constructor(data) {
259
- super(data);
260
- }
261
- copy() {
262
- const c = wrap(this.constructor, this, node => node.children);
263
- c.each(node => node.data = node.data.data);
264
- return c;
265
- }
266
- get size() {
267
- return nodeSize(this);
268
- }
269
- spacing(oNode) {
270
- return spacing(this, oNode);
271
- }
272
- get nodes() {
273
- return this.descendants();
274
- }
275
- get xSize() {
276
- return this.size[0];
277
- }
278
- get ySize() {
279
- return this.size[1];
280
- }
281
- get top() {
282
- return this.y;
283
- }
284
- get bottom() {
285
- return this.y + this.ySize;
286
- }
287
- get left() {
288
- return this.x - this.xSize / 2;
289
- }
290
- get right() {
291
- return this.x + this.xSize / 2;
292
- }
293
- get root() {
294
- const ancs = this.ancestors();
295
- return ancs[ancs.length - 1];
296
- }
297
- get numChildren() {
298
- return this.hasChildren ? this.children.length : 0;
299
- }
300
- get hasChildren() {
301
- return !this.noChildren;
302
- }
303
- get noChildren() {
304
- return this.children === null;
305
- }
306
- get firstChild() {
307
- return this.hasChildren ? this.children[0] : null;
308
- }
309
- get lastChild() {
310
- return this.hasChildren ? this.children[this.numChildren - 1] : null;
311
- }
312
- get extents() {
313
- return (this.children || []).reduce((acc, kid) => FlexNode.maxExtents(acc, kid.extents), this.nodeExtents);
314
- }
315
- get nodeExtents() {
316
- return {
317
- top: this.top,
318
- bottom: this.bottom,
319
- left: this.left,
320
- right: this.right
321
- };
322
- }
323
- static maxExtents(e0, e1) {
324
- return {
325
- top: Math.min(e0.top, e1.top),
326
- bottom: Math.max(e0.bottom, e1.bottom),
327
- left: Math.min(e0.left, e1.left),
328
- right: Math.max(e0.right, e1.right)
329
- };
330
- }
331
- };
332
- }
333
- function getWrapper() {
334
- const FlexNode = getFlexNode();
335
- const nodeSize = accessor('nodeSize');
336
- const spacing = accessor('spacing');
337
- return class extends FlexNode {
338
- constructor(data) {
339
- super(data);
340
- Object.assign(this, {
341
- x: 0,
342
- y: 0,
343
- relX: 0,
344
- prelim: 0,
345
- shift: 0,
346
- change: 0,
347
- lExt: this,
348
- lExtRelX: 0,
349
- lThr: null,
350
- rExt: this,
351
- rExtRelX: 0,
352
- rThr: null
353
- });
354
- }
355
- get size() {
356
- return nodeSize(this.data);
357
- }
358
- spacing(oNode) {
359
- return spacing(this.data, oNode.data);
360
- }
361
- get x() {
362
- return this.data.x;
363
- }
364
- set x(v) {
365
- this.data.x = v;
366
- }
367
- get y() {
368
- return this.data.y;
369
- }
370
- set y(v) {
371
- this.data.y = v;
372
- }
373
- update() {
374
- layoutChildren(this);
375
- resolveX(this);
376
- return this;
377
- }
378
- };
379
- }
380
- function wrap(FlexClass, treeData, children) {
381
- const _wrap = (data, parent) => {
382
- const node = new FlexClass(data);
383
- Object.assign(node, {
384
- parent,
385
- depth: parent === null ? 0 : parent.depth + 1,
386
- height: 0,
387
- length: 1
388
- });
389
- const kidsData = children(data) || [];
390
- node.children = kidsData.length === 0 ? null : kidsData.map(kd => _wrap(kd, node));
391
- if (node.children) {
392
- Object.assign(node, node.children.reduce((hl, kid) => ({
393
- height: Math.max(hl.height, kid.height + 1),
394
- length: hl.length + kid.length
395
- }), node));
396
- }
397
- return node;
398
- };
399
- return _wrap(treeData, null);
400
- }
401
- Object.assign(layout, {
402
- nodeSize(arg) {
403
- return arguments.length ? (opts.nodeSize = arg, layout) : opts.nodeSize;
404
- },
405
- spacing(arg) {
406
- return arguments.length ? (opts.spacing = arg, layout) : opts.spacing;
407
- },
408
- children(arg) {
409
- return arguments.length ? (opts.children = arg, layout) : opts.children;
410
- },
411
- hierarchy(treeData, children) {
412
- const kids = typeof children === 'undefined' ? opts.children : children;
413
- return wrap(getFlexNode(), treeData, kids);
414
- },
415
- dump(tree) {
416
- const nodeSize = accessor('nodeSize');
417
- const _dump = i0 => node => {
418
- const i1 = i0 + ' ';
419
- const i2 = i0 + ' ';
420
- const {
421
- x,
422
- y
423
- } = node;
424
- const size = nodeSize(node);
425
- const kids = node.children || [];
426
- const kdumps = kids.length === 0 ? ' ' : `,${i1}children: [${i2}${kids.map(_dump(i2)).join(i2)}${i1}],${i0}`;
427
- return `{ size: [${size.join(', ')}],${i1}x: ${x}, y: ${y}${kdumps}},`;
428
- };
429
- return _dump('\n')(tree);
430
- }
431
- });
432
- return layout;
433
- }
434
- flextree.version = version;
435
- const layoutChildren = (w, y = 0) => {
436
- w.y = y;
437
- (w.children || []).reduce((acc, kid) => {
438
- const [i, lastLows] = acc;
439
- layoutChildren(kid, w.y + w.ySize);
440
- // The lowest vertical coordinate while extreme nodes still point
441
- // in current subtree.
442
- const lowY = (i === 0 ? kid.lExt : kid.rExt).bottom;
443
- if (i !== 0) separate(w, i, lastLows);
444
- const lows = updateLows(lowY, i, lastLows);
445
- return [i + 1, lows];
446
- }, [0, null]);
447
- shiftChange(w);
448
- positionRoot(w);
449
- return w;
450
- };
451
-
452
- // Resolves the relative coordinate properties - relX and prelim --
453
- // to set the final, absolute x coordinate for each node. This also sets
454
- // `prelim` to 0, so that `relX` for each node is its x-coordinate relative
455
- // to its parent.
456
- const resolveX = (w, prevSum, parentX) => {
457
- // A call to resolveX without arguments is assumed to be for the root of
458
- // the tree. This will set the root's x-coord to zero.
459
- if (typeof prevSum === 'undefined') {
460
- prevSum = -w.relX - w.prelim;
461
- parentX = 0;
462
- }
463
- const sum = prevSum + w.relX;
464
- w.relX = sum + w.prelim - parentX;
465
- w.prelim = 0;
466
- w.x = parentX + w.relX;
467
- (w.children || []).forEach(k => resolveX(k, sum, w.x));
468
- return w;
469
- };
470
-
471
- // Process shift and change for all children, to add intermediate spacing to
472
- // each child's modifier.
473
- const shiftChange = w => {
474
- (w.children || []).reduce((acc, child) => {
475
- const [lastShiftSum, lastChangeSum] = acc;
476
- const shiftSum = lastShiftSum + child.shift;
477
- const changeSum = lastChangeSum + shiftSum + child.change;
478
- child.relX += changeSum;
479
- return [shiftSum, changeSum];
480
- }, [0, 0]);
481
- };
482
-
483
- // Separates the latest child from its previous sibling
484
- /* eslint-disable complexity */
485
- const separate = (w, i, lows) => {
486
- const lSib = w.children[i - 1];
487
- const curSubtree = w.children[i];
488
- let rContour = lSib;
489
- let rSumMods = lSib.relX;
490
- let lContour = curSubtree;
491
- let lSumMods = curSubtree.relX;
492
- let isFirst = true;
493
- while (rContour && lContour) {
494
- if (rContour.bottom > lows.lowY) lows = lows.next;
495
- // How far to the left of the right side of rContour is the left side
496
- // of lContour? First compute the center-to-center distance, then add
497
- // the "spacing"
498
- const dist = rSumMods + rContour.prelim - (lSumMods + lContour.prelim) + rContour.xSize / 2 + lContour.xSize / 2 + rContour.spacing(lContour);
499
- if (dist > 0 || dist < 0 && isFirst) {
500
- lSumMods += dist;
501
- // Move subtree by changing relX.
502
- moveSubtree(curSubtree, dist);
503
- distributeExtra(w, i, lows.index, dist);
504
- }
505
- isFirst = false;
506
- // Advance highest node(s) and sum(s) of modifiers
507
- const rightBottom = rContour.bottom;
508
- const leftBottom = lContour.bottom;
509
- if (rightBottom <= leftBottom) {
510
- rContour = nextRContour(rContour);
511
- if (rContour) rSumMods += rContour.relX;
512
- }
513
- if (rightBottom >= leftBottom) {
514
- lContour = nextLContour(lContour);
515
- if (lContour) lSumMods += lContour.relX;
516
- }
517
- }
518
- // Set threads and update extreme nodes. In the first case, the
519
- // current subtree is taller than the left siblings.
520
- if (!rContour && lContour) setLThr(w, i, lContour, lSumMods);
521
- // In the next case, the left siblings are taller than the current subtree
522
- else if (rContour && !lContour) setRThr(w, i, rContour, rSumMods);
523
- };
524
- /* eslint-enable complexity */
525
-
526
- // Move subtree by changing relX.
527
- const moveSubtree = (subtree, distance) => {
528
- subtree.relX += distance;
529
- subtree.lExtRelX += distance;
530
- subtree.rExtRelX += distance;
531
- };
532
- const distributeExtra = (w, curSubtreeI, leftSibI, dist) => {
533
- const curSubtree = w.children[curSubtreeI];
534
- const n = curSubtreeI - leftSibI;
535
- // Are there intermediate children?
536
- if (n > 1) {
537
- const delta = dist / n;
538
- w.children[leftSibI + 1].shift += delta;
539
- curSubtree.shift -= delta;
540
- curSubtree.change -= dist - delta;
541
- }
542
- };
543
- const nextLContour = w => {
544
- return w.hasChildren ? w.firstChild : w.lThr;
545
- };
546
- const nextRContour = w => {
547
- return w.hasChildren ? w.lastChild : w.rThr;
548
- };
549
- const setLThr = (w, i, lContour, lSumMods) => {
550
- const firstChild = w.firstChild;
551
- const lExt = firstChild.lExt;
552
- const curSubtree = w.children[i];
553
- lExt.lThr = lContour;
554
- // Change relX so that the sum of modifier after following thread is correct.
555
- const diff = lSumMods - lContour.relX - firstChild.lExtRelX;
556
- lExt.relX += diff;
557
- // Change preliminary x coordinate so that the node does not move.
558
- lExt.prelim -= diff;
559
- // Update extreme node and its sum of modifiers.
560
- firstChild.lExt = curSubtree.lExt;
561
- firstChild.lExtRelX = curSubtree.lExtRelX;
562
- };
563
-
564
- // Mirror image of setLThr.
565
- const setRThr = (w, i, rContour, rSumMods) => {
566
- const curSubtree = w.children[i];
567
- const rExt = curSubtree.rExt;
568
- const lSib = w.children[i - 1];
569
- rExt.rThr = rContour;
570
- const diff = rSumMods - rContour.relX - curSubtree.rExtRelX;
571
- rExt.relX += diff;
572
- rExt.prelim -= diff;
573
- curSubtree.rExt = lSib.rExt;
574
- curSubtree.rExtRelX = lSib.rExtRelX;
575
- };
576
-
577
- // Position root between children, taking into account their modifiers
578
- const positionRoot = w => {
579
- if (w.hasChildren) {
580
- const k0 = w.firstChild;
581
- const kf = w.lastChild;
582
- const prelim = (k0.prelim + k0.relX - k0.xSize / 2 + kf.relX + kf.prelim + kf.xSize / 2) / 2;
583
- Object.assign(w, {
584
- prelim,
585
- lExt: k0.lExt,
586
- lExtRelX: k0.lExtRelX,
587
- rExt: kf.rExt,
588
- rExtRelX: kf.rExtRelX
589
- });
590
- }
591
- };
592
-
593
- // Make/maintain a linked list of the indexes of left siblings and their
594
- // lowest vertical coordinate.
595
- const updateLows = (lowY, index, lastLows) => {
596
- // Remove siblings that are hidden by the new subtree.
597
- while (lastLows !== null && lowY >= lastLows.lowY) lastLows = lastLows.next;
598
- // Prepend the new subtree.
599
- return {
600
- lowY,
601
- index,
602
- next: lastLows
603
- };
604
- };
605
-
606
- /*! @gera2ld/jsx-dom v2.1.1 | ISC License */
607
- var VTYPE_ELEMENT = 1;
608
- var VTYPE_FUNCTION = 2;
609
- var MOUNT_SINGLE = 1;
610
- var MOUNT_ARRAY = 4;
611
- var SVG_NS = 'http://www.w3.org/2000/svg';
612
- var XLINK_NS = 'http://www.w3.org/1999/xlink';
613
- var NS_ATTRS = {
614
- show: XLINK_NS,
615
- actuate: XLINK_NS,
616
- href: XLINK_NS
617
- };
618
- var isLeaf = function isLeaf(c) {
619
- return typeof c === 'string' || typeof c === 'number';
620
- };
621
- var isElement = function isElement(c) {
622
- return (c == null ? void 0 : c.vtype) === VTYPE_ELEMENT;
623
- };
624
- var isRenderFunction = function isRenderFunction(c) {
625
- return (c == null ? void 0 : c.vtype) === VTYPE_FUNCTION;
626
- };
627
- function jsx(type, props) {
628
- var vtype;
629
- if (typeof type === 'string') vtype = VTYPE_ELEMENT;else if (typeof type === 'function') vtype = VTYPE_FUNCTION;else throw new Error('Invalid VNode type');
630
- return {
631
- vtype: vtype,
632
- type: type,
633
- props: props
634
- };
635
- }
636
- function Fragment(props) {
637
- return props.children;
638
- }
639
- var DEFAULT_ENV = {
640
- isSvg: false
641
- };
642
- function insertDom(parent, ref) {
643
- if (ref.type === MOUNT_SINGLE) {
644
- if (ref.node != null) parent.append(ref.node);
645
- } else if (ref.type === MOUNT_ARRAY) {
646
- ref.children.forEach(function (ch) {
647
- insertDom(parent, ch);
648
- });
649
- } else {
650
- throw new Error("Unkown ref type " + JSON.stringify(ref));
651
- }
652
- }
653
- function mountAttributes(domElement, props, env) {
654
- for (var key in props) {
655
- if (key === 'key' || key === 'children' || key === 'ref') continue;
656
- if (key === 'dangerouslySetInnerHTML') {
657
- domElement.innerHTML = props[key].__html;
658
- } else if (key === 'innerHTML' || key === 'textContent' || key === 'innerText') {
659
- domElement[key] = props[key];
660
- } else if (key.startsWith('on')) {
661
- domElement[key.toLowerCase()] = props[key];
662
- } else {
663
- setDOMAttribute(domElement, key, props[key], env.isSvg);
664
- }
665
- }
666
- }
667
- var attrMap = {
668
- className: 'class',
669
- labelFor: 'for'
670
- };
671
- function setDOMAttribute(el, attr, value, isSVG) {
672
- attr = attrMap[attr] || attr;
673
- if (value === true) {
674
- el.setAttribute(attr, '');
675
- } else if (value === false) {
676
- el.removeAttribute(attr);
677
- } else {
678
- var namespace = isSVG ? NS_ATTRS[attr] : undefined;
679
- if (namespace !== undefined) {
680
- el.setAttributeNS(namespace, attr, value);
681
- } else {
682
- el.setAttribute(attr, value);
683
- }
684
- }
685
- }
686
- function mount(vnode, env) {
687
- if (env === void 0) {
688
- env = DEFAULT_ENV;
689
- }
690
- if (vnode == null || typeof vnode === 'boolean') {
691
- return {
692
- type: MOUNT_SINGLE,
693
- node: null
694
- };
695
- }
696
- if (vnode instanceof Node) {
697
- return {
698
- type: MOUNT_SINGLE,
699
- node: vnode
700
- };
701
- }
702
- if (isRenderFunction(vnode)) {
703
- var _ref = vnode,
704
- type = _ref.type,
705
- props = _ref.props;
706
- if (type === Fragment) {
707
- var node = document.createDocumentFragment();
708
- if (props.children) {
709
- var childrenRef = mount(props.children, env);
710
- insertDom(node, childrenRef);
711
- }
712
- return {
713
- type: MOUNT_SINGLE,
714
- node: node
715
- };
716
- }
717
- var childVNode = type(props);
718
- return mount(childVNode, env);
719
- }
720
- if (isLeaf(vnode)) {
721
- return {
722
- type: MOUNT_SINGLE,
723
- node: document.createTextNode("" + vnode)
724
- };
725
- }
726
- if (isElement(vnode)) {
727
- var _node;
728
- var _ref2 = vnode,
729
- _type = _ref2.type,
730
- _props = _ref2.props;
731
- if (!env.isSvg && _type === 'svg') {
732
- env = Object.assign({}, env, {
733
- isSvg: true
734
- });
735
- }
736
- if (!env.isSvg) {
737
- _node = document.createElement(_type);
738
- } else {
739
- _node = document.createElementNS(SVG_NS, _type);
740
- }
741
- mountAttributes(_node, _props, env);
742
- var _childrenRef;
743
- if (_props.children) {
744
- var childEnv = env;
745
- if (env.isSvg && _type === 'foreignObject') {
746
- childEnv = Object.assign({}, childEnv, {
747
- isSvg: false
748
- });
749
- }
750
- _childrenRef = mount(_props.children, childEnv);
751
- }
752
- if (_childrenRef != null) insertDom(_node, _childrenRef);
753
- var ref = _props.ref;
754
- if (typeof ref === 'function') ref(_node);
755
- return {
756
- type: MOUNT_SINGLE,
757
- node: _node
758
- };
759
- }
760
- if (Array.isArray(vnode)) {
761
- return {
762
- type: MOUNT_ARRAY,
763
- children: vnode.map(function (child) {
764
- return mount(child, env);
765
- })
766
- };
767
- }
768
- throw new Error('mount: Invalid Vnode!');
769
- }
770
- function flattenWithoutNull(array) {
771
- var result = [];
772
- for (var i = 0; i < array.length; i += 1) {
773
- var item = array[i];
774
- if (Array.isArray(item)) result = result.concat(flattenWithoutNull(item));else if (item != null) result.push(item);
775
- }
776
- return result;
777
- }
778
- function asDom(result) {
779
- if (result.type === MOUNT_SINGLE) {
780
- return result.node;
781
- }
782
- return result.children.map(asDom);
783
- }
784
- /**
785
- * Mount vdom as real DOM nodes.
786
- */
787
-
788
- function mountDom(vnode) {
789
- if (Array.isArray(vnode)) {
790
- return flattenWithoutNull(vnode.map(mountDom));
791
- }
792
- return asDom(mount(vnode));
793
- }
794
-
795
- var css_248z$1 = ".markmap{font:300 16px/20px sans-serif}.markmap-link{fill:none}.markmap-node>circle{cursor:pointer}.markmap-foreign{display:inline-block}.markmap-foreign a{color:#0097e6}.markmap-foreign a:hover{color:#00a8ff}.markmap-foreign code{background-color:#f0f0f0;border-radius:2px;color:#555;font-size:calc(1em - 2px)}.markmap-foreign :not(pre)>code{padding:.2em .4em}.markmap-foreign del{text-decoration:line-through}.markmap-foreign em{font-style:italic}.markmap-foreign strong{font-weight:700}.markmap-foreign mark{background:#ffeaa7}.markmap-foreign pre,.markmap-foreign pre[class*=language-]{margin:0;padding:.2em .4em}";
796
-
797
- var css_248z = ".markmap-container{height:0;left:-100px;overflow:hidden;position:absolute;top:-100px;width:0}.markmap-container>.markmap-foreign{display:inline-block}.markmap-container>.markmap-foreign>div:last-child{white-space:nowrap}";
798
-
799
- const globalCSS = css_248z$1;
800
- function linkWidth(nodeData) {
801
- const data = nodeData.data;
802
- return Math.max(4 - 2 * data.depth, 1.5);
803
- }
804
- function adjustSpacing(tree, spacing) {
805
- walkTree(tree, (d, next) => {
806
- d.ySizeInner = d.ySize - spacing;
807
- d.y += spacing;
808
- next();
809
- }, 'children');
810
- }
811
- function minBy(numbers, by) {
812
- const index = d3.minIndex(numbers, by);
813
- return numbers[index];
814
- }
815
- function stopPropagation(e) {
816
- e.stopPropagation();
817
- }
818
- function createViewHooks() {
819
- return {
820
- transformHtml: new Hook()
821
- };
822
- }
823
-
824
- /**
825
- * A global hook to refresh all markmaps when called.
826
- */
827
- const refreshHook = new Hook();
828
- const defaultColorFn = d3.scaleOrdinal(d3.schemeCategory10);
829
- const isMacintosh = typeof navigator !== 'undefined' && navigator.userAgent.includes('Macintosh');
830
- class Markmap {
831
- constructor(svg, opts) {
832
- this.revokers = [];
833
- ['handleZoom', 'handleClick', 'handlePan'].forEach(key => {
834
- this[key] = this[key].bind(this);
835
- });
836
- this.viewHooks = createViewHooks();
837
- this.svg = svg.datum ? svg : d3.select(svg);
838
- this.styleNode = this.svg.append('style');
839
- this.zoom = d3.zoom().filter(event => {
840
- if (this.options.scrollForPan) {
841
- // Pan with wheels, zoom with ctrl+wheels
842
- if (event.type === 'wheel') return event.ctrlKey && !event.button;
843
- }
844
- return (!event.ctrlKey || event.type === 'wheel') && !event.button;
845
- }).on('zoom', this.handleZoom);
846
- this.setOptions(opts);
847
- this.state = {
848
- id: this.options.id || this.svg.attr('id') || getId()
849
- };
850
- this.g = this.svg.append('g');
851
- this.revokers.push(refreshHook.tap(() => {
852
- this.setData();
853
- }));
854
- }
855
- getStyleContent() {
856
- const {
857
- style
858
- } = this.options;
859
- const {
860
- id
861
- } = this.state;
862
- const styleText = typeof style === 'function' ? style(id) : '';
863
- return [this.options.embedGlobalCSS && css_248z$1, styleText].filter(Boolean).join('\n');
864
- }
865
- updateStyle() {
866
- this.svg.attr('class', addClass(this.svg.attr('class'), 'markmap', this.state.id));
867
- const style = this.getStyleContent();
868
- this.styleNode.text(style);
869
- }
870
- handleZoom(e) {
871
- const {
872
- transform
873
- } = e;
874
- this.g.attr('transform', transform);
875
- }
876
- handlePan(e) {
877
- e.preventDefault();
878
- const transform = d3.zoomTransform(this.svg.node());
879
- const newTransform = transform.translate(-e.deltaX / transform.k, -e.deltaY / transform.k);
880
- this.svg.call(this.zoom.transform, newTransform);
881
- }
882
- toggleNode(data, recursive = false) {
883
- var _data$payload;
884
- const fold = (_data$payload = data.payload) != null && _data$payload.fold ? 0 : 1;
885
- if (recursive) {
886
- // recursively
887
- walkTree(data, (item, next) => {
888
- item.payload = _extends({}, item.payload, {
889
- fold
890
- });
891
- next();
892
- });
893
- } else {
894
- var _data$payload2;
895
- data.payload = _extends({}, data.payload, {
896
- fold: (_data$payload2 = data.payload) != null && _data$payload2.fold ? 0 : 1
897
- });
898
- }
899
- this.renderData(data);
900
- }
901
- handleClick(e, d) {
902
- this.toggleNode(d.data, e.ctrlKey);
903
- }
904
- initializeData(node) {
905
- let nodeId = 0;
906
- const {
907
- color,
908
- nodeMinHeight,
909
- maxWidth,
910
- initialExpandLevel
911
- } = this.options;
912
- const {
913
- id
914
- } = this.state;
915
- const container = mountDom(jsx("div", {
916
- className: `markmap-container markmap ${id}-g`
917
- }));
918
- const style = mountDom(jsx("style", {
919
- children: [this.getStyleContent(), css_248z].join('\n')
920
- }));
921
- document.body.append(container, style);
922
- const groupStyle = maxWidth ? `max-width: ${maxWidth}px` : '';
923
- let foldRecursively = 0;
924
- walkTree(node, (item, next, parent) => {
925
- var _item$children, _parent$state, _item$payload;
926
- item.children = (_item$children = item.children) == null ? void 0 : _item$children.map(child => _extends({}, child));
927
- nodeId += 1;
928
- const group = mountDom(jsx("div", {
929
- className: "markmap-foreign",
930
- style: groupStyle,
931
- children: jsx("div", {
932
- dangerouslySetInnerHTML: {
933
- __html: item.content
934
- }
935
- })
936
- }));
937
- container.append(group);
938
- item.state = _extends({}, item.state, {
939
- id: nodeId,
940
- el: group.firstChild
941
- });
942
- item.state.path = [parent == null || (_parent$state = parent.state) == null ? void 0 : _parent$state.path, item.state.id].filter(Boolean).join('.');
943
- color(item); // preload colors
944
-
945
- const isFoldRecursively = ((_item$payload = item.payload) == null ? void 0 : _item$payload.fold) === 2;
946
- if (isFoldRecursively) {
947
- foldRecursively += 1;
948
- } else if (foldRecursively || initialExpandLevel >= 0 && item.depth >= initialExpandLevel) {
949
- item.payload = _extends({}, item.payload, {
950
- fold: 1
951
- });
952
- }
953
- next();
954
- if (isFoldRecursively) foldRecursively -= 1;
955
- });
956
- const nodes = Array.from(container.childNodes).map(group => group.firstChild);
957
- this.viewHooks.transformHtml.call(this, nodes);
958
- // Clone the rendered HTML and set `white-space: nowrap` to it to detect its max-width.
959
- // The parent node will have a width of the max-width and the original content without
960
- // `white-space: nowrap` gets re-layouted, then we will get the expected layout, with
961
- // content in one line as much as possible, and subjecting to the given max-width.
962
- nodes.forEach(node => {
963
- node.parentNode.append(node.cloneNode(true));
964
- });
965
- walkTree(node, (item, next, parent) => {
966
- var _parent$state2;
967
- const rect = item.state.el.getBoundingClientRect();
968
- item.content = item.state.el.innerHTML;
969
- item.state.size = [Math.ceil(rect.width) + 1, Math.max(Math.ceil(rect.height), nodeMinHeight)];
970
- item.state.key = [parent == null || (_parent$state2 = parent.state) == null ? void 0 : _parent$state2.id, item.state.id].filter(Boolean).join('.') +
971
- // FIXME: find a way to check content hash
972
- item.content;
973
- next();
974
- });
975
- container.remove();
976
- style.remove();
977
- }
978
- setOptions(opts) {
979
- this.options = _extends({}, Markmap.defaultOptions, opts);
980
- if (this.options.zoom) {
981
- this.svg.call(this.zoom);
982
- } else {
983
- this.svg.on('.zoom', null);
984
- }
985
- this.svg.on('wheel', this.options.pan ? this.handlePan : null);
986
- }
987
- setData(data, opts) {
988
- if (data) this.state.data = data;
989
- if (opts) this.setOptions(opts);
990
- this.initializeData(this.state.data);
991
- this.updateStyle();
992
- this.renderData();
993
- }
994
- renderData(originData) {
995
- var _origin$data$state$x, _origin$data$state$y;
996
- if (!this.state.data) return;
997
- const {
998
- spacingHorizontal,
999
- paddingX,
1000
- spacingVertical,
1001
- autoFit,
1002
- color
1003
- } = this.options;
1004
- const layout = flextree().children(d => {
1005
- var _d$payload;
1006
- return !((_d$payload = d.payload) != null && _d$payload.fold) && d.children;
1007
- }).nodeSize(d => {
1008
- const [width, height] = d.data.state.size;
1009
- return [height, width + (width ? paddingX * 2 : 0) + spacingHorizontal];
1010
- }).spacing((a, b) => {
1011
- return a.parent === b.parent ? spacingVertical : spacingVertical * 2;
1012
- });
1013
- const tree = layout.hierarchy(this.state.data);
1014
- layout(tree);
1015
- adjustSpacing(tree, spacingHorizontal);
1016
- const descendants = tree.descendants().reverse();
1017
- const links = tree.links();
1018
- const linkShape = d3.linkHorizontal();
1019
- const minX = d3.min(descendants, d => d.x - d.xSize / 2);
1020
- const maxX = d3.max(descendants, d => d.x + d.xSize / 2);
1021
- const minY = d3.min(descendants, d => d.y);
1022
- const maxY = d3.max(descendants, d => d.y + d.ySizeInner);
1023
- Object.assign(this.state, {
1024
- minX,
1025
- maxX,
1026
- minY,
1027
- maxY
1028
- });
1029
- if (autoFit) this.fit();
1030
- const origin = originData && descendants.find(item => item.data === originData) || tree;
1031
- const x0 = (_origin$data$state$x = origin.data.state.x0) != null ? _origin$data$state$x : origin.x;
1032
- const y0 = (_origin$data$state$y = origin.data.state.y0) != null ? _origin$data$state$y : origin.y;
1033
-
1034
- // Update the nodes
1035
- const node = this.g.selectAll(childSelector('g')).data(descendants, d => d.data.state.key);
1036
- const nodeEnter = node.enter().append('g').attr('data-depth', d => d.data.depth).attr('data-path', d => d.data.state.path).attr('transform', d => `translate(${y0 + origin.ySizeInner - d.ySizeInner},${x0 + origin.xSize / 2 - d.xSize})`);
1037
- const nodeExit = this.transition(node.exit());
1038
- nodeExit.select('line').attr('x1', d => d.ySizeInner).attr('x2', d => d.ySizeInner);
1039
- nodeExit.select('foreignObject').style('opacity', 0);
1040
- nodeExit.attr('transform', d => `translate(${origin.y + origin.ySizeInner - d.ySizeInner},${origin.x + origin.xSize / 2 - d.xSize})`).remove();
1041
- const nodeMerge = node.merge(nodeEnter).attr('class', d => {
1042
- var _d$data$payload;
1043
- return ['markmap-node', ((_d$data$payload = d.data.payload) == null ? void 0 : _d$data$payload.fold) && 'markmap-fold'].filter(Boolean).join(' ');
1044
- });
1045
- this.transition(nodeMerge).attr('transform', d => `translate(${d.y},${d.x - d.xSize / 2})`);
1046
-
1047
- // Update lines under the content
1048
- const line = nodeMerge.selectAll(childSelector('line')).data(d => [d], d => d.data.state.key).join(enter => {
1049
- return enter.append('line').attr('x1', d => d.ySizeInner).attr('x2', d => d.ySizeInner);
1050
- }, update => update, exit => exit.remove());
1051
- this.transition(line).attr('x1', -1).attr('x2', d => d.ySizeInner + 2).attr('y1', d => d.xSize).attr('y2', d => d.xSize).attr('stroke', d => color(d.data)).attr('stroke-width', linkWidth);
1052
-
1053
- // Circle to link to children of the node
1054
- const circle = nodeMerge.selectAll(childSelector('circle')).data(d => d.data.children ? [d] : [], d => d.data.state.key).join(enter => {
1055
- return enter.append('circle').attr('stroke-width', '1.5').attr('cx', d => d.ySizeInner).attr('cy', d => d.xSize).attr('r', 0).on('click', (e, d) => this.handleClick(e, d)).on('mousedown', stopPropagation);
1056
- }, update => update, exit => exit.remove());
1057
- this.transition(circle).attr('r', 6).attr('cx', d => d.ySizeInner).attr('cy', d => d.xSize).attr('stroke', d => color(d.data)).attr('fill', d => {
1058
- var _d$data$payload2;
1059
- return (_d$data$payload2 = d.data.payload) != null && _d$data$payload2.fold && d.data.children ? color(d.data) : '#fff';
1060
- });
1061
- const foreignObject = nodeMerge.selectAll(childSelector('foreignObject')).data(d => [d], d => d.data.state.key).join(enter => {
1062
- const fo = enter.append('foreignObject').attr('class', 'markmap-foreign').attr('x', paddingX).attr('y', 0).style('opacity', 0).on('mousedown', stopPropagation).on('dblclick', stopPropagation);
1063
- fo.append('xhtml:div').select(function select(d) {
1064
- const clone = d.data.state.el.cloneNode(true);
1065
- this.replaceWith(clone);
1066
- return clone;
1067
- }).attr('xmlns', 'http://www.w3.org/1999/xhtml');
1068
- return fo;
1069
- }, update => update, exit => exit.remove()).attr('width', d => Math.max(0, d.ySizeInner - paddingX * 2)).attr('height', d => d.xSize);
1070
- this.transition(foreignObject).style('opacity', 1);
1071
-
1072
- // Update the links
1073
- const path = this.g.selectAll(childSelector('path')).data(links, d => d.target.data.state.key).join(enter => {
1074
- const source = [y0 + origin.ySizeInner, x0 + origin.xSize / 2];
1075
- return enter.insert('path', 'g').attr('class', 'markmap-link').attr('data-depth', d => d.target.data.depth).attr('data-path', d => d.target.data.state.path).attr('d', linkShape({
1076
- source,
1077
- target: source
1078
- }));
1079
- }, update => update, exit => {
1080
- const source = [origin.y + origin.ySizeInner, origin.x + origin.xSize / 2];
1081
- return this.transition(exit).attr('d', linkShape({
1082
- source,
1083
- target: source
1084
- })).remove();
1085
- });
1086
- this.transition(path).attr('stroke', d => color(d.target.data)).attr('stroke-width', d => linkWidth(d.target)).attr('d', d => {
1087
- const source = [d.source.y + d.source.ySizeInner, d.source.x + d.source.xSize / 2];
1088
- const target = [d.target.y, d.target.x + d.target.xSize / 2];
1089
- return linkShape({
1090
- source,
1091
- target
1092
- });
1093
- });
1094
- descendants.forEach(d => {
1095
- d.data.state.x0 = d.x;
1096
- d.data.state.y0 = d.y;
1097
- });
1098
- }
1099
- transition(sel) {
1100
- const {
1101
- duration
1102
- } = this.options;
1103
- return sel.transition().duration(duration);
1104
- }
1105
-
1106
- /**
1107
- * Fit the content to the viewport.
1108
- */
1109
- async fit() {
1110
- const svgNode = this.svg.node();
1111
- const {
1112
- width: offsetWidth,
1113
- height: offsetHeight
1114
- } = svgNode.getBoundingClientRect();
1115
- const {
1116
- fitRatio
1117
- } = this.options;
1118
- const {
1119
- minX,
1120
- maxX,
1121
- minY,
1122
- maxY
1123
- } = this.state;
1124
- const naturalWidth = maxY - minY;
1125
- const naturalHeight = maxX - minX;
1126
- const scale = Math.min(offsetWidth / naturalWidth * fitRatio, offsetHeight / naturalHeight * fitRatio, 2);
1127
- const initialZoom = d3.zoomIdentity.translate((offsetWidth - naturalWidth * scale) / 2 - minY * scale, (offsetHeight - naturalHeight * scale) / 2 - minX * scale).scale(scale);
1128
- return this.transition(this.svg).call(this.zoom.transform, initialZoom).end().catch(noop);
1129
- }
1130
-
1131
- /**
1132
- * Pan the content to make the provided node visible in the viewport.
1133
- */
1134
- async ensureView(node, padding) {
1135
- let itemData;
1136
- this.g.selectAll(childSelector('g')).each(function walk(d) {
1137
- if (d.data === node) {
1138
- itemData = d;
1139
- }
1140
- });
1141
- if (!itemData) return;
1142
- const svgNode = this.svg.node();
1143
- const relRect = svgNode.getBoundingClientRect();
1144
- const transform = d3.zoomTransform(svgNode);
1145
- const [left, right] = [itemData.y, itemData.y + itemData.ySizeInner + 2].map(x => x * transform.k + transform.x);
1146
- const [top, bottom] = [itemData.x - itemData.xSize / 2, itemData.x + itemData.xSize / 2].map(y => y * transform.k + transform.y);
1147
- // Skip if the node includes or is included in the container.
1148
- const pd = _extends({
1149
- left: 0,
1150
- right: 0,
1151
- top: 0,
1152
- bottom: 0
1153
- }, padding);
1154
- const dxs = [pd.left - left, relRect.width - pd.right - right];
1155
- const dys = [pd.top - top, relRect.height - pd.bottom - bottom];
1156
- const dx = dxs[0] * dxs[1] > 0 ? minBy(dxs, Math.abs) / transform.k : 0;
1157
- const dy = dys[0] * dys[1] > 0 ? minBy(dys, Math.abs) / transform.k : 0;
1158
- if (dx || dy) {
1159
- const newTransform = transform.translate(dx, dy);
1160
- return this.transition(this.svg).call(this.zoom.transform, newTransform).end().catch(noop);
1161
- }
1162
- }
1163
-
1164
- /**
1165
- * Scale content with it pinned at the center of the viewport.
1166
- */
1167
- async rescale(scale) {
1168
- const svgNode = this.svg.node();
1169
- const {
1170
- width: offsetWidth,
1171
- height: offsetHeight
1172
- } = svgNode.getBoundingClientRect();
1173
- const halfWidth = offsetWidth / 2;
1174
- const halfHeight = offsetHeight / 2;
1175
- const transform = d3.zoomTransform(svgNode);
1176
- const newTransform = transform.translate((halfWidth - transform.x) * (1 - scale) / transform.k, (halfHeight - transform.y) * (1 - scale) / transform.k).scale(scale);
1177
- return this.transition(this.svg).call(this.zoom.transform, newTransform).end().catch(noop);
1178
- }
1179
- destroy() {
1180
- this.svg.on('.zoom', null);
1181
- this.svg.html(null);
1182
- this.revokers.forEach(fn => {
1183
- fn();
1184
- });
1185
- }
1186
- static create(svg, opts, data) {
1187
- const mm = new Markmap(svg, opts);
1188
- if (data) {
1189
- mm.setData(data);
1190
- mm.fit(); // always fit for the first render
1191
- }
1192
-
1193
- return mm;
1194
- }
1195
- }
1196
- Markmap.defaultOptions = {
1197
- autoFit: false,
1198
- color: node => defaultColorFn(`${node.state.path}`),
1199
- duration: 500,
1200
- embedGlobalCSS: true,
1201
- fitRatio: 0.95,
1202
- maxWidth: 0,
1203
- nodeMinHeight: 16,
1204
- paddingX: 8,
1205
- scrollForPan: isMacintosh,
1206
- spacingHorizontal: 80,
1207
- spacingVertical: 5,
1208
- initialExpandLevel: -1,
1209
- zoom: true,
1210
- pan: true
1211
- };
1212
- function deriveOptions(jsonOptions) {
1213
- const opts = {};
1214
- jsonOptions || (jsonOptions = {});
1215
- const {
1216
- color,
1217
- colorFreezeLevel
1218
- } = jsonOptions;
1219
- if ((color == null ? void 0 : color.length) === 1) {
1220
- const solidColor = color[0];
1221
- opts.color = () => solidColor;
1222
- } else if (color != null && color.length) {
1223
- const colorFn = d3.scaleOrdinal(color);
1224
- opts.color = node => colorFn(`${node.state.path}`);
1225
- }
1226
- if (colorFreezeLevel) {
1227
- const color = opts.color || Markmap.defaultOptions.color;
1228
- opts.color = node => {
1229
- node = _extends({}, node, {
1230
- state: _extends({}, node.state, {
1231
- path: node.state.path.split('.').slice(0, colorFreezeLevel).join('.')
1232
- })
1233
- });
1234
- return color(node);
1235
- };
1236
- }
1237
- const numberKeys = ['duration', 'maxWidth', 'initialExpandLevel'];
1238
- numberKeys.forEach(key => {
1239
- const value = jsonOptions[key];
1240
- if (typeof value === 'number') opts[key] = value;
1241
- });
1242
- const booleanKeys = ['zoom', 'pan'];
1243
- booleanKeys.forEach(key => {
1244
- const value = jsonOptions[key];
1245
- if (value != null) opts[key] = !!value;
1246
- });
1247
- return opts;
1248
- }
1249
-
1250
- export { Markmap, defaultColorFn, deriveOptions, globalCSS, refreshHook };