markmap-view 0.15.8 → 0.15.9-alpha.5

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.
@@ -35,13 +35,11 @@
35
35
  item,
36
36
  () => {
37
37
  var _a;
38
- (_a = item.children) == null ? void 0 : _a.forEach((child) => {
39
- walk(child, item);
40
- });
38
+ return (_a = item.children) == null ? void 0 : _a.map((child) => walk(child, item));
41
39
  },
42
40
  parent
43
41
  );
44
- walk(tree);
42
+ return walk(tree);
45
43
  }
46
44
  function addClass(className, ...rest) {
47
45
  const classList = (className || "").split(" ").filter(Boolean);
@@ -86,6 +84,28 @@
86
84
  return data.value;
87
85
  };
88
86
  }
87
+ function debounce(fn, time) {
88
+ const state = {
89
+ timer: 0
90
+ };
91
+ function reset() {
92
+ if (state.timer) {
93
+ window.clearTimeout(state.timer);
94
+ state.timer = 0;
95
+ }
96
+ }
97
+ function run() {
98
+ reset();
99
+ if (state.args)
100
+ state.result = fn(...state.args);
101
+ }
102
+ return function debounced(...args) {
103
+ reset();
104
+ state.args = args;
105
+ state.timer = window.setTimeout(run, time);
106
+ return state.result;
107
+ };
108
+ }
89
109
  /*! @gera2ld/jsx-dom v2.2.2 | ISC License */
90
110
  const VTYPE_ELEMENT$1 = 1;
91
111
  const VTYPE_FUNCTION$1 = 2;
@@ -332,6 +352,66 @@
332
352
  async function loadCSS(items) {
333
353
  await Promise.all(items.map((item) => loadCSSItem(item)));
334
354
  }
355
+ const isMacintosh = typeof navigator !== "undefined" && navigator.userAgent.includes("Macintosh");
356
+ const defaultColorFn = d32.scaleOrdinal(d32.schemeCategory10);
357
+ const defaultOptions = {
358
+ autoFit: false,
359
+ color: (node) => {
360
+ var _a;
361
+ return defaultColorFn(`${((_a = node.state) == null ? void 0 : _a.path) || ""}`);
362
+ },
363
+ duration: 500,
364
+ embedGlobalCSS: true,
365
+ fitRatio: 0.95,
366
+ maxWidth: 0,
367
+ nodeMinHeight: 16,
368
+ paddingX: 8,
369
+ scrollForPan: isMacintosh,
370
+ spacingHorizontal: 80,
371
+ spacingVertical: 5,
372
+ initialExpandLevel: -1,
373
+ zoom: true,
374
+ pan: true,
375
+ toggleRecursively: false
376
+ };
377
+ function deriveOptions(jsonOptions) {
378
+ const derivedOptions = {};
379
+ const options = { ...jsonOptions };
380
+ const { color, colorFreezeLevel } = options;
381
+ if ((color == null ? void 0 : color.length) === 1) {
382
+ const solidColor = color[0];
383
+ derivedOptions.color = () => solidColor;
384
+ } else if (color == null ? void 0 : color.length) {
385
+ const colorFn = d32.scaleOrdinal(color);
386
+ derivedOptions.color = (node) => colorFn(`${node.state.path}`);
387
+ }
388
+ if (colorFreezeLevel) {
389
+ const color2 = derivedOptions.color || defaultOptions.color;
390
+ derivedOptions.color = (node) => {
391
+ node = {
392
+ ...node,
393
+ state: {
394
+ ...node.state,
395
+ path: node.state.path.split(".").slice(0, colorFreezeLevel).join(".")
396
+ }
397
+ };
398
+ return color2(node);
399
+ };
400
+ }
401
+ const numberKeys = ["duration", "maxWidth", "initialExpandLevel"];
402
+ numberKeys.forEach((key) => {
403
+ const value = options[key];
404
+ if (typeof value === "number")
405
+ derivedOptions[key] = value;
406
+ });
407
+ const booleanKeys = ["zoom", "pan"];
408
+ booleanKeys.forEach((key) => {
409
+ const value = options[key];
410
+ if (value != null)
411
+ derivedOptions[key] = !!value;
412
+ });
413
+ return derivedOptions;
414
+ }
335
415
  /*! @gera2ld/jsx-dom v2.2.2 | ISC License */
336
416
  const VTYPE_ELEMENT = 1;
337
417
  const VTYPE_FUNCTION = 2;
@@ -1073,12 +1153,12 @@
1073
1153
  next: lastLows
1074
1154
  };
1075
1155
  };
1076
- const css = ".markmap {\n font: 300 16px/20px sans-serif;\n}\n\n .markmap-link {\n fill: none;\n }\n\n .markmap-node > circle {\n cursor: pointer;\n }\n\n .markmap-foreign {\n display: inline-block;\n }\n\n .markmap-foreign a {\n color: #0097e6;\n }\n\n .markmap-foreign a:hover {\n color: #00a8ff;\n }\n\n .markmap-foreign code {\n padding: 0.25em;\n font-size: calc(1em - 2px);\n color: #555;\n background-color: #f0f0f0;\n border-radius: 2px;\n }\n\n .markmap-foreign pre {\n margin: 0;\n }\n\n .markmap-foreign pre > code {\n display: block;\n }\n\n .markmap-foreign del {\n text-decoration: line-through;\n }\n\n .markmap-foreign em {\n font-style: italic;\n }\n\n .markmap-foreign strong {\n font-weight: bold;\n }\n\n .markmap-foreign mark {\n background: #ffeaa7;\n }\n";
1077
1156
  const containerCSS = "/* used for pre-rendering to get the size of each node */\n.markmap-container {\n position: absolute;\n width: 0;\n height: 0;\n top: -100px;\n left: -100px;\n overflow: hidden;\n}\n.markmap-container > .markmap-foreign {\n display: inline-block;\n }\n/* first-child for line wrapping, last-child for max-width detection */\n.markmap-container > .markmap-foreign > div:last-child,\n \n .markmap-container > .markmap-foreign > div:last-child :not(pre) {\n white-space: nowrap;\n }\n.markmap-container > .markmap-foreign > div:last-child code {\n white-space: inherit;\n }\n";
1157
+ const css = ".markmap {\n --markmap-max-width: none;\n --markmap-a-color: #0097e6;\n --markmap-a-hover-color: #00a8ff;\n --markmap-code-bg: #f0f0f0;\n --markmap-code-color: #555;\n --markmap-highlight-bg: #ffeaa7;\n --markmap-table-border: 1px solid currentColor;\n --markmap-font: 300 16px/20px sans-serif;\n\n font: var(--markmap-font);\n}\n\n .markmap-link {\n fill: none;\n }\n\n .markmap-node > circle {\n cursor: pointer;\n }\n\n .markmap-foreign {\n display: inline-block;\n }\n\n .markmap-foreign a {\n color: var(--markmap-a-color);\n }\n\n .markmap-foreign a:hover {\n color: var(--markmap-a-hover-color);\n }\n\n .markmap-foreign code {\n padding: 0.25em;\n font-size: calc(1em - 2px);\n color: var(--markmap-code-color);\n background-color: var(--markmap-code-bg);\n border-radius: 2px;\n }\n\n .markmap-foreign pre {\n margin: 0;\n }\n\n .markmap-foreign pre > code {\n display: block;\n }\n\n .markmap-foreign del {\n text-decoration: line-through;\n }\n\n .markmap-foreign em {\n font-style: italic;\n }\n\n .markmap-foreign strong {\n font-weight: bold;\n }\n\n .markmap-foreign mark {\n background: var(--markmap-highlight-bg);\n }\n\n .markmap-foreign table,\n .markmap-foreign th,\n .markmap-foreign td {\n border-collapse: collapse;\n border: var(--markmap-table-border);\n }\n\n .markmap-foreign img {\n display: inline-block;\n }\n\n .markmap-foreign-testing-max {\n max-width: var(--markmap-max-width);\n }\n\n .markmap-foreign-testing-max img {\n max-width: var(--markmap-max-width);\n max-height: none;\n }\n";
1078
1158
  const globalCSS = css;
1079
1159
  function linkWidth(nodeData) {
1080
1160
  const data = nodeData.data;
1081
- return Math.max(4 - 2 * data.depth, 1.5);
1161
+ return Math.max(4 - 2 * data.state.depth, 1.5);
1082
1162
  }
1083
1163
  function minBy(numbers, by) {
1084
1164
  const index = d32.minIndex(numbers, by);
@@ -1087,18 +1167,12 @@
1087
1167
  function stopPropagation(e) {
1088
1168
  e.stopPropagation();
1089
1169
  }
1090
- function createViewHooks() {
1091
- return {
1092
- transformHtml: new Hook()
1093
- };
1094
- }
1095
1170
  const refreshHook = new Hook();
1096
- const defaultColorFn = d32.scaleOrdinal(d32.schemeCategory10);
1097
- const isMacintosh = typeof navigator !== "undefined" && navigator.userAgent.includes("Macintosh");
1098
- const _Markmap = class _Markmap {
1171
+ class Markmap {
1099
1172
  constructor(svg, opts) {
1100
- this.options = _Markmap.defaultOptions;
1173
+ this.options = defaultOptions;
1101
1174
  this.revokers = [];
1175
+ this.imgCache = {};
1102
1176
  this.handleZoom = (e) => {
1103
1177
  const { transform } = e;
1104
1178
  this.g.attr("transform", transform);
@@ -1118,7 +1192,6 @@
1118
1192
  recursive = !recursive;
1119
1193
  this.toggleNode(d.data, recursive);
1120
1194
  };
1121
- this.viewHooks = createViewHooks();
1122
1195
  this.svg = svg.datum ? svg : d32.select(svg);
1123
1196
  this.styleNode = this.svg.append("style");
1124
1197
  this.zoom = d32.zoom().filter((event) => {
@@ -1137,6 +1210,7 @@
1137
1210
  maxY: 0
1138
1211
  };
1139
1212
  this.g = this.svg.append("g");
1213
+ this.debouncedRefresh = debounce(() => this.setData(), 200);
1140
1214
  this.revokers.push(
1141
1215
  refreshHook.tap(() => {
1142
1216
  this.setData();
@@ -1187,18 +1261,28 @@
1187
1261
  /* @__PURE__ */ jsx("style", { children: [this.getStyleContent(), containerCSS].join("\n") })
1188
1262
  );
1189
1263
  document.body.append(container, style);
1190
- const groupStyle = maxWidth ? `max-width: ${maxWidth}px` : "";
1264
+ const groupStyle = maxWidth ? `--markmap-max-width: ${maxWidth}px` : "";
1191
1265
  let foldRecursively = 0;
1266
+ let depth = 0;
1192
1267
  walkTree(node, (item, next, parent) => {
1193
1268
  var _a, _b, _c;
1269
+ depth += 1;
1194
1270
  item.children = (_a = item.children) == null ? void 0 : _a.map((child) => ({ ...child }));
1195
1271
  nodeId += 1;
1196
1272
  const group = mountDom(
1197
- /* @__PURE__ */ jsx("div", { className: "markmap-foreign", style: groupStyle, children: /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: item.content } }) })
1273
+ /* @__PURE__ */ jsx(
1274
+ "div",
1275
+ {
1276
+ className: "markmap-foreign markmap-foreign-testing-max",
1277
+ style: groupStyle,
1278
+ children: /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: item.content } })
1279
+ }
1280
+ )
1198
1281
  );
1199
1282
  container.append(group);
1200
1283
  item.state = {
1201
1284
  ...item.state,
1285
+ depth,
1202
1286
  id: nodeId,
1203
1287
  el: group.firstChild
1204
1288
  };
@@ -1207,17 +1291,18 @@
1207
1291
  const isFoldRecursively = ((_c = item.payload) == null ? void 0 : _c.fold) === 2;
1208
1292
  if (isFoldRecursively) {
1209
1293
  foldRecursively += 1;
1210
- } else if (foldRecursively || initialExpandLevel >= 0 && item.depth >= initialExpandLevel) {
1294
+ } else if (foldRecursively || initialExpandLevel >= 0 && item.state.depth >= initialExpandLevel) {
1211
1295
  item.payload = { ...item.payload, fold: 1 };
1212
1296
  }
1213
1297
  next();
1214
1298
  if (isFoldRecursively)
1215
1299
  foldRecursively -= 1;
1300
+ depth -= 1;
1216
1301
  });
1217
1302
  const nodes = Array.from(container.childNodes).map(
1218
1303
  (group) => group.firstChild
1219
1304
  );
1220
- this.viewHooks.transformHtml.call(this, nodes);
1305
+ this._checkImages(container);
1221
1306
  nodes.forEach((node2) => {
1222
1307
  var _a;
1223
1308
  (_a = node2.parentNode) == null ? void 0 : _a.append(node2.cloneNode(true));
@@ -1238,6 +1323,27 @@
1238
1323
  container.remove();
1239
1324
  style.remove();
1240
1325
  }
1326
+ _checkImages(container) {
1327
+ container.querySelectorAll("img").forEach((img) => {
1328
+ if (img.width)
1329
+ return;
1330
+ const size = this.imgCache[img.src];
1331
+ if (size == null ? void 0 : size[0]) {
1332
+ [img.width, img.height] = size;
1333
+ } else if (!size) {
1334
+ this._loadImage(img.src);
1335
+ }
1336
+ });
1337
+ }
1338
+ _loadImage(src) {
1339
+ this.imgCache[src] = [0, 0];
1340
+ const img = new Image();
1341
+ img.src = src;
1342
+ img.onload = () => {
1343
+ this.imgCache[src] = [img.naturalWidth, img.naturalHeight];
1344
+ this.debouncedRefresh();
1345
+ };
1346
+ }
1241
1347
  setOptions(opts) {
1242
1348
  this.options = {
1243
1349
  ...this.options,
@@ -1302,7 +1408,7 @@
1302
1408
  const node = this.g.selectAll(
1303
1409
  childSelector("g")
1304
1410
  ).data(descendants, (d) => d.data.state.key);
1305
- const nodeEnter = node.enter().append("g").attr("data-depth", (d) => d.data.depth).attr("data-path", (d) => d.data.state.path).attr(
1411
+ const nodeEnter = node.enter().append("g").attr("data-depth", (d) => d.data.state.depth).attr("data-path", (d) => d.data.state.path).attr(
1306
1412
  "transform",
1307
1413
  (d) => `translate(${y0 + origin.ySize - d.ySize},${x0 + origin.xSize / 2 - d.xSize})`
1308
1414
  );
@@ -1389,7 +1495,7 @@
1389
1495
  y0 + origin.ySize - spacingHorizontal,
1390
1496
  x0 + origin.xSize / 2
1391
1497
  ];
1392
- 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({ source, target: source }));
1498
+ return enter.insert("path", "g").attr("class", "markmap-link").attr("data-depth", (d) => d.target.data.state.depth).attr("data-path", (d) => d.target.data.state.path).attr("d", linkShape({ source, target: source }));
1393
1499
  },
1394
1500
  (update) => update,
1395
1501
  (exit) => {
@@ -1508,77 +1614,20 @@
1508
1614
  });
1509
1615
  }
1510
1616
  static create(svg, opts, data = null) {
1511
- const mm = new _Markmap(svg, opts);
1617
+ const mm = new Markmap(svg, opts);
1512
1618
  if (data) {
1513
1619
  mm.setData(data);
1514
1620
  mm.fit();
1515
1621
  }
1516
1622
  return mm;
1517
1623
  }
1518
- };
1519
- _Markmap.defaultOptions = {
1520
- autoFit: false,
1521
- color: (node) => {
1522
- var _a;
1523
- return defaultColorFn(`${((_a = node.state) == null ? void 0 : _a.path) || ""}`);
1524
- },
1525
- duration: 500,
1526
- embedGlobalCSS: true,
1527
- fitRatio: 0.95,
1528
- maxWidth: 0,
1529
- nodeMinHeight: 16,
1530
- paddingX: 8,
1531
- scrollForPan: isMacintosh,
1532
- spacingHorizontal: 80,
1533
- spacingVertical: 5,
1534
- initialExpandLevel: -1,
1535
- zoom: true,
1536
- pan: true,
1537
- toggleRecursively: false
1538
- };
1539
- let Markmap = _Markmap;
1540
- function deriveOptions(jsonOptions) {
1541
- const derivedOptions = {};
1542
- const options = { ...jsonOptions };
1543
- const { color, colorFreezeLevel } = options;
1544
- if ((color == null ? void 0 : color.length) === 1) {
1545
- const solidColor = color[0];
1546
- derivedOptions.color = () => solidColor;
1547
- } else if (color == null ? void 0 : color.length) {
1548
- const colorFn = d32.scaleOrdinal(color);
1549
- derivedOptions.color = (node) => colorFn(`${node.state.path}`);
1550
- }
1551
- if (colorFreezeLevel) {
1552
- const color2 = derivedOptions.color || Markmap.defaultOptions.color;
1553
- derivedOptions.color = (node) => {
1554
- node = {
1555
- ...node,
1556
- state: {
1557
- ...node.state,
1558
- path: node.state.path.split(".").slice(0, colorFreezeLevel).join(".")
1559
- }
1560
- };
1561
- return color2(node);
1562
- };
1563
- }
1564
- const numberKeys = ["duration", "maxWidth", "initialExpandLevel"];
1565
- numberKeys.forEach((key) => {
1566
- const value = options[key];
1567
- if (typeof value === "number")
1568
- derivedOptions[key] = value;
1569
- });
1570
- const booleanKeys = ["zoom", "pan"];
1571
- booleanKeys.forEach((key) => {
1572
- const value = options[key];
1573
- if (value != null)
1574
- derivedOptions[key] = !!value;
1575
- });
1576
- return derivedOptions;
1577
1624
  }
1578
1625
  exports.Markmap = Markmap;
1579
1626
  exports.defaultColorFn = defaultColorFn;
1627
+ exports.defaultOptions = defaultOptions;
1580
1628
  exports.deriveOptions = deriveOptions;
1581
1629
  exports.globalCSS = globalCSS;
1630
+ exports.isMacintosh = isMacintosh;
1582
1631
  exports.loadCSS = loadCSS;
1583
1632
  exports.loadJS = loadJS;
1584
1633
  exports.refreshHook = refreshHook;
@@ -0,0 +1,4 @@
1
+ import { IMarkmapOptions } from 'markmap-common';
2
+ export declare const isMacintosh: boolean;
3
+ export declare const defaultColorFn: import("d3-scale").ScaleOrdinal<string, string, never>;
4
+ export declare const defaultOptions: IMarkmapOptions;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { loadJS, loadCSS } from 'markmap-common';
2
2
  export * from './types';
3
+ export * from './constants';
4
+ export * from './util';
3
5
  export * from './view';