markmap-view 0.18.4 → 0.18.5-alpha.7

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.
@@ -47,18 +47,6 @@
47
47
  });
48
48
  return classList.join(" ");
49
49
  }
50
- function childSelector(filter) {
51
- if (typeof filter === "string") {
52
- const tagName = filter;
53
- filter = (el) => el.tagName === tagName;
54
- }
55
- const filterFn = filter;
56
- return function selector() {
57
- let nodes = Array.from(this.childNodes);
58
- if (filterFn) nodes = nodes.filter((node) => filterFn(node));
59
- return nodes;
60
- };
61
- }
62
50
  function defer() {
63
51
  const obj = {};
64
52
  obj.promise = new Promise((resolve, reject) => {
@@ -413,6 +401,18 @@
413
401
  }
414
402
  return (hash >>> 0).toString(36);
415
403
  }
404
+ function childSelector(filter) {
405
+ if (typeof filter === "string") {
406
+ const selector = filter;
407
+ filter = (el) => el.matches(selector);
408
+ }
409
+ const filterFn = filter;
410
+ return function selector() {
411
+ let nodes = Array.from(this.childNodes);
412
+ if (filterFn) nodes = nodes.filter((node) => filterFn(node));
413
+ return nodes;
414
+ };
415
+ }
416
416
  function count(node) {
417
417
  var sum = 0, children = node.children, i = children && children.length;
418
418
  if (!i) sum = 1;
@@ -942,8 +942,11 @@
942
942
  next: lastLows
943
943
  };
944
944
  };
945
- const css = ".markmap {\n --markmap-max-width: 9999px;\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 --markmap-circle-open-bg: #fff;\n --markmap-text-color: #333;\n\n font: var(--markmap-font);\n color: var(--markmap-text-color);\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 p {\n margin: 0;\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 svg {\n fill: currentColor;\n }\n\n .markmap-foreign > div {\n width: var(--markmap-max-width);\n text-align: left;\n }\n\n .markmap-foreign > div > div {\n display: inline-block;\n }\n\n.markmap-dark .markmap {\n --markmap-code-bg: #1a1b26;\n --markmap-code-color: #ddd;\n --markmap-circle-open-bg: #444;\n --markmap-text-color: #eee;\n}\n";
945
+ const css = ".markmap {\n --markmap-max-width: 9999px;\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 --markmap-circle-open-bg: #fff;\n --markmap-text-color: #333;\n --markmap-highlight-node-bg: #ff02;\n\n font: var(--markmap-font);\n color: var(--markmap-text-color);\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 p {\n margin: 0;\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 svg {\n fill: currentColor;\n }\n\n .markmap-foreign > div {\n width: var(--markmap-max-width);\n text-align: left;\n }\n\n .markmap-foreign > div > div {\n display: inline-block;\n }\n\n .markmap-highlight rect {\n fill: var(--markmap-highlight-node-bg);\n }\n\n.markmap-dark .markmap {\n --markmap-code-bg: #1a1b26;\n --markmap-code-color: #ddd;\n --markmap-circle-open-bg: #444;\n --markmap-text-color: #eee;\n}\n";
946
946
  const globalCSS = css;
947
+ const SELECTOR_NODE = "g.markmap-node";
948
+ const SELECTOR_LINK = "path.markmap-link";
949
+ const SELECTOR_HIGHLIGHT = "g.markmap-highlight";
947
950
  const linkShape = d32.linkHorizontal();
948
951
  function linkWidth(data) {
949
952
  return Math.max(4 - 2 * data.state.depth, 1.5);
@@ -959,7 +962,7 @@
959
962
  class Markmap {
960
963
  constructor(svg, opts) {
961
964
  this.options = defaultOptions;
962
- this.revokers = [];
965
+ this._disposeList = [];
963
966
  this.handleZoom = (e) => {
964
967
  const { transform } = e;
965
968
  this.g.attr("transform", transform);
@@ -993,16 +996,17 @@
993
996
  rect: { x1: 0, y1: 0, x2: 0, y2: 0 }
994
997
  };
995
998
  this.g = this.svg.append("g");
996
- this.observer = new ResizeObserver(
999
+ this.g.append("g").attr("class", "markmap-highlight");
1000
+ this._observer = new ResizeObserver(
997
1001
  debounce(() => {
998
1002
  this.renderData();
999
1003
  }, 100)
1000
1004
  );
1001
- this.revokers.push(
1005
+ this._disposeList.push(
1002
1006
  refreshHook.tap(() => {
1003
1007
  this.setData();
1004
1008
  }),
1005
- () => this.observer.disconnect()
1009
+ () => this._observer.disconnect()
1006
1010
  );
1007
1011
  }
1008
1012
  getStyleContent() {
@@ -1073,10 +1077,11 @@
1073
1077
  if (isFoldRecursively) foldRecursively -= 1;
1074
1078
  depth -= 1;
1075
1079
  });
1080
+ return node;
1076
1081
  }
1077
1082
  _relayout() {
1078
1083
  if (!this.state.data) return;
1079
- this.g.selectAll(childSelector("g")).selectAll(
1084
+ this.g.selectAll(childSelector(SELECTOR_NODE)).selectAll(
1080
1085
  childSelector("foreignObject")
1081
1086
  ).each(function(d) {
1082
1087
  var _a;
@@ -1137,12 +1142,28 @@
1137
1142
  }
1138
1143
  async setData(data, opts) {
1139
1144
  if (opts) this.setOptions(opts);
1140
- if (data) this.state.data = data;
1145
+ if (data) this.state.data = this._initializeData(data);
1141
1146
  if (!this.state.data) return;
1142
- this._initializeData(this.state.data);
1143
1147
  this.updateStyle();
1144
1148
  await this.renderData();
1145
1149
  }
1150
+ async setHighlight(node) {
1151
+ this.state.highlight = node || void 0;
1152
+ await this.renderData();
1153
+ }
1154
+ _getHighlightRect(highlight) {
1155
+ const svgNode = this.svg.node();
1156
+ const transform = d32.zoomTransform(svgNode);
1157
+ const padding = 4 / transform.k;
1158
+ const rect = {
1159
+ ...highlight.state.rect
1160
+ };
1161
+ rect.x -= padding;
1162
+ rect.y -= padding;
1163
+ rect.width += 2 * padding;
1164
+ rect.height += 2 * padding;
1165
+ return rect;
1166
+ }
1146
1167
  async renderData(originData) {
1147
1168
  const { paddingX, autoFit, color, maxWidth } = this.options;
1148
1169
  const rootNode = this.state.data;
@@ -1173,7 +1194,9 @@
1173
1194
  const getOriginTargetRect = (node) => (nodeMap[originMap[node.state.id]] || rootNode).state.rect;
1174
1195
  sourceRectMap[rootNode.state.id] = rootNode.state.rect;
1175
1196
  if (originData) setOriginNode(originData);
1176
- const mmG = this.g.selectAll(childSelector("g")).each((d) => {
1197
+ const { highlight } = this.state;
1198
+ let highlightNodes = this.g.selectAll(childSelector(SELECTOR_HIGHLIGHT)).selectAll(childSelector("rect")).data(highlight ? [this._getHighlightRect(highlight)] : []).join("rect").attr("x", (d) => d.x).attr("y", (d) => d.y).attr("width", (d) => d.width).attr("height", (d) => d.height);
1199
+ const mmG = this.g.selectAll(childSelector(SELECTOR_NODE)).each((d) => {
1177
1200
  sourceRectMap[d.state.id] = d.state.rect;
1178
1201
  }).data(nodes, (d) => d.state.key);
1179
1202
  const mmGEnter = mmG.enter().append("g").attr("data-depth", (d) => d.state.depth).attr("data-path", (d) => d.state.path).each((d) => {
@@ -1210,7 +1233,7 @@
1210
1233
  return ((_a = d.payload) == null ? void 0 : _a.fold) && d.children ? color(d) : "var(--markmap-circle-open-bg)";
1211
1234
  }
1212
1235
  );
1213
- const observer = this.observer;
1236
+ const observer = this._observer;
1214
1237
  const mmFo = mmGMerge.selectAll(childSelector("foreignObject")).data(
1215
1238
  (d) => [d],
1216
1239
  (d) => d.state.key
@@ -1237,7 +1260,7 @@
1237
1260
  return ((_a = node.payload) == null ? void 0 : _a.fold) ? [] : node.children.map((child) => ({ source: node, target: child }));
1238
1261
  }
1239
1262
  );
1240
- const mmPath = this.g.selectAll(childSelector("path")).data(links, (d) => d.target.state.key);
1263
+ const mmPath = this.g.selectAll(childSelector(SELECTOR_LINK)).data(links, (d) => d.target.state.key);
1241
1264
  const mmPathExit = mmPath.exit();
1242
1265
  const mmPathEnter = mmPath.enter().insert("path", "g").attr("class", "markmap-link").attr("data-depth", (d) => d.target.state.depth).attr("data-path", (d) => d.target.state.path).attr("d", (d) => {
1243
1266
  const originRect = getOriginSourceRect(d.target);
@@ -1254,6 +1277,8 @@
1254
1277
  );
1255
1278
  await new Promise(requestAnimationFrame);
1256
1279
  this._relayout();
1280
+ highlightNodes = highlightNodes.data(highlight ? [this._getHighlightRect(highlight)] : []).join("rect");
1281
+ this.transition(highlightNodes).attr("x", (d) => d.x).attr("y", (d) => d.y).attr("width", (d) => d.width).attr("height", (d) => d.height);
1257
1282
  mmGEnter.attr("transform", (d) => {
1258
1283
  const originRect = getOriginSourceRect(d);
1259
1284
  return `translate(${originRect.x + originRect.width - d.state.rect.width},${originRect.y + originRect.height - d.state.rect.height})`;
@@ -1334,7 +1359,7 @@
1334
1359
  }
1335
1360
  findElement(node) {
1336
1361
  let result;
1337
- this.g.selectAll(childSelector("g")).each(function walk(d) {
1362
+ this.g.selectAll(childSelector(SELECTOR_NODE)).each(function walk(d) {
1338
1363
  if (d === node) {
1339
1364
  result = {
1340
1365
  data: d,
@@ -1421,7 +1446,7 @@
1421
1446
  destroy() {
1422
1447
  this.svg.on(".zoom", null);
1423
1448
  this.svg.html(null);
1424
- this.revokers.forEach((fn) => {
1449
+ this._disposeList.forEach((fn) => {
1425
1450
  fn();
1426
1451
  });
1427
1452
  }
@@ -1436,6 +1461,7 @@
1436
1461
  }
1437
1462
  }
1438
1463
  exports.Markmap = Markmap;
1464
+ exports.childSelector = childSelector;
1439
1465
  exports.defaultColorFn = defaultColorFn;
1440
1466
  exports.defaultOptions = defaultOptions;
1441
1467
  exports.deriveOptions = deriveOptions;