@yuneta/gobj-ui 7.23.133 → 7.23.134

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.
@@ -56640,42 +56640,17 @@ function draw_link(gobj, child_topic, child_id, source_col, fkey, verbose) {
56640
56640
  return;
56641
56641
  }
56642
56642
  if (get_edge_by_link(gobj, parent_topic, parent_id, hook_name, child_topic, child_id, fkey_name)) return;
56643
- let dark = priv.theme === "dark";
56644
56643
  let is_tree = parent_topic === child_topic;
56645
- let saved_lineWidth = is_tree ? 2 : 1.6;
56646
- let saved_stroke = is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
56647
- let themed_default = true;
56648
- let topic_props = priv._graph_properties[parent_topic];
56649
- if (topic_props) {
56650
- if (is_object(topic_props.edges)) {
56651
- let edge_key = hook_name + ":" + parent_id + ":" + child_id;
56652
- let edge_props = topic_props.edges[edge_key];
56653
- if (edge_props) {
56654
- if (edge_props.lineWidth != null) saved_lineWidth = edge_props.lineWidth;
56655
- if (edge_props.stroke) {
56656
- saved_stroke = edge_props.stroke;
56657
- themed_default = false;
56658
- }
56659
- }
56660
- }
56661
- if (themed_default && is_object(topic_props.defaults)) {
56662
- let defs = topic_props.defaults;
56663
- if (defs.edge_styles && defs.edge_styles[hook_name]) {
56664
- let hook_style = defs.edge_styles[hook_name];
56665
- if (hook_style.lineWidth != null) saved_lineWidth = hook_style.lineWidth;
56666
- if (hook_style.stroke) {
56667
- saved_stroke = hook_style.stroke;
56668
- themed_default = false;
56669
- }
56670
- } else if (defs.edge_style) {
56671
- if (defs.edge_style.lineWidth != null) saved_lineWidth = defs.edge_style.lineWidth;
56672
- if (defs.edge_style.stroke) {
56673
- saved_stroke = defs.edge_style.stroke;
56674
- themed_default = false;
56675
- }
56676
- }
56677
- }
56678
- }
56644
+ let edge_style = edge_style_of(gobj, {
56645
+ parent_topic,
56646
+ parent_id,
56647
+ hook_name,
56648
+ child_id,
56649
+ is_tree
56650
+ });
56651
+ let saved_lineWidth = edge_style.lineWidth;
56652
+ let saved_stroke = edge_style.stroke;
56653
+ let themed_default = edge_style.themed_default;
56679
56654
  let edge = {
56680
56655
  id: build_edge_id(gobj),
56681
56656
  type: edge_type_for(gobj),
@@ -60275,19 +60250,81 @@ function apply_edge_properties(gobj, edge_id, lineWidth, stroke, scope) {
60275
60250
  deselect_edge(gobj);
60276
60251
  }
60277
60252
  /************************************************************
60253
+ * The style an edge INHERITS, before anything saved for the
60254
+ * edge itself: its hook's default in the parent topic, else the
60255
+ * parent topic's default for every edge, else the library's.
60256
+ *
60257
+ * The library's: neutral grey, teal for the containment/tree
60258
+ * relation (parent and child of the same topic, a
60259
+ * self-hierarchy). `themed_default` says the colour is still the
60260
+ * library's, so a theme toggle re-themes it and leaves a chosen
60261
+ * one alone.
60262
+ ************************************************************/
60263
+ function edge_inherited_style_of(gobj, d) {
60264
+ let dark = gobj.priv.theme === "dark";
60265
+ let style = {
60266
+ lineWidth: d.is_tree ? 2 : 1.6,
60267
+ stroke: d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280",
60268
+ themed_default: true
60269
+ };
60270
+ let defs = topic_defaults_of(gobj, d.parent_topic);
60271
+ if (!defs) return style;
60272
+ let chosen = null;
60273
+ if (is_object(defs.edge_styles) && is_object(defs.edge_styles[d.hook_name])) chosen = defs.edge_styles[d.hook_name];
60274
+ else if (is_object(defs.edge_style)) chosen = defs.edge_style;
60275
+ if (chosen) {
60276
+ if (chosen.lineWidth != null) style.lineWidth = chosen.lineWidth;
60277
+ if (chosen.stroke) {
60278
+ style.stroke = chosen.stroke;
60279
+ style.themed_default = false;
60280
+ }
60281
+ }
60282
+ return style;
60283
+ }
60284
+ function edge_key_of(d) {
60285
+ return d.hook_name + ":" + d.parent_id + ":" + d.child_id;
60286
+ }
60287
+ /************************************************************
60288
+ * The style an edge WEARS: what it inherits, with what was saved
60289
+ * for the edge itself on top.
60290
+ ************************************************************/
60291
+ function edge_style_of(gobj, d) {
60292
+ let style = edge_inherited_style_of(gobj, d);
60293
+ let topic_props = gobj.priv._graph_properties[d.parent_topic];
60294
+ let own = is_object(topic_props) && is_object(topic_props.edges) ? topic_props.edges[edge_key_of(d)] : null;
60295
+ if (is_object(own)) {
60296
+ if (own.lineWidth != null) style.lineWidth = own.lineWidth;
60297
+ if (own.stroke) {
60298
+ style.stroke = own.stroke;
60299
+ style.themed_default = false;
60300
+ }
60301
+ }
60302
+ return style;
60303
+ }
60304
+ /************************************************************
60278
60305
  * Save edge styles into _graph_properties (called from
60279
60306
  * save_geometry).
60307
+ *
60308
+ * Only what differs from what the edge INHERITS is written. It
60309
+ * used to be "any line width but 2", and the library's own width
60310
+ * for an edge between two topics is 1.6: every Save wrote every
60311
+ * such edge down with its width and its theme's colour, so the
60312
+ * default was frozen on it -- a theme toggle no longer re-themed
60313
+ * it after a reload, and a topic default never reached it.
60280
60314
  ************************************************************/
60281
60315
  function update_edge_geometry(gobj, edge_id) {
60282
60316
  let priv = gobj.priv;
60283
60317
  let edgeData = priv.graph.getEdgeData(edge_id);
60284
60318
  if (!edgeData || !edgeData.data || !edgeData.data.parent_topic) return;
60285
60319
  let style = edgeData.style || {};
60286
- let lineWidth = style.lineWidth;
60287
- let stroke = style.stroke;
60288
- let parent_topic = edgeData.data.parent_topic;
60289
- let edge_key = edgeData.data.hook_name + ":" + edgeData.data.parent_id + ":" + edgeData.data.child_id;
60290
- if (!(lineWidth != null && lineWidth !== 2)) {
60320
+ let d = edgeData.data;
60321
+ let inherited = edge_inherited_style_of(gobj, d);
60322
+ let parent_topic = d.parent_topic;
60323
+ let edge_key = edge_key_of(d);
60324
+ let edge_props = {};
60325
+ if (style.lineWidth != null && style.lineWidth !== inherited.lineWidth) edge_props.lineWidth = style.lineWidth;
60326
+ if (style.stroke && style.stroke !== inherited.stroke) edge_props.stroke = style.stroke;
60327
+ if (Object.keys(edge_props).length === 0) {
60291
60328
  let topic_props = priv._graph_properties[parent_topic];
60292
60329
  if (topic_props && is_object(topic_props.edges)) {
60293
60330
  delete topic_props.edges[edge_key];
@@ -60298,8 +60335,6 @@ function update_edge_geometry(gobj, edge_id) {
60298
60335
  if (!is_object(priv._graph_properties[parent_topic])) priv._graph_properties[parent_topic] = {};
60299
60336
  let topic_props = priv._graph_properties[parent_topic];
60300
60337
  if (!is_object(topic_props.edges)) topic_props.edges = {};
60301
- let edge_props = { lineWidth };
60302
- if (stroke) edge_props.stroke = stroke;
60303
60338
  topic_props.edges[edge_key] = edge_props;
60304
60339
  }
60305
60340
  /************************************************************
@@ -60353,8 +60388,11 @@ function build_node_context_menu(gobj, node_id) {
60353
60388
  if (gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
60354
60389
  items.push(ctx_item("g6-icon-resize", t("resize all"), "resize_all_nodes"));
60355
60390
  items.push(ctx_item("g6-icon-resize", t("resize topic nodes"), "resize_topic_nodes"));
60356
- items.push(ctx_item("g6-icon-undo", t("reset sizes"), "reset_all_sizes"));
60357
- items.push(ctx_item("g6-icon-undo", t("reset topic sizes"), "reset_topic_sizes"));
60391
+ }
60392
+ if (gobj.priv.edit_mode) {
60393
+ items.push(ctx_item("g6-icon-undo", t("reset node"), "reset_node"));
60394
+ items.push(ctx_item("g6-icon-undo", t("reset topic nodes"), "reset_topic_nodes"));
60395
+ items.push(ctx_item("g6-icon-undo", t("reset all nodes"), "reset_all_nodes"));
60358
60396
  }
60359
60397
  return items;
60360
60398
  }
@@ -60384,6 +60422,9 @@ function build_edge_context_menu(gobj) {
60384
60422
  inject_svg_icons();
60385
60423
  items.push(ctx_item("g6-icon-edit", t("edge properties"), "edge_properties"));
60386
60424
  items.push(ctx_item("g6-icon-delete", t("unlink"), "unlink_edge"));
60425
+ items.push(ctx_item("g6-icon-undo", t("reset edge"), "reset_edge"));
60426
+ items.push(ctx_item("g6-icon-undo", t("reset same type edges"), "reset_same_type_edges"));
60427
+ items.push(ctx_item("g6-icon-undo", t("reset all edges"), "reset_all_edges"));
60387
60428
  }
60388
60429
  return items;
60389
60430
  }
@@ -60402,11 +60443,23 @@ function handle_context_menu_click(gobj, value) {
60402
60443
  case "resize_topic_nodes":
60403
60444
  copy_size_to_nodes(gobj, true);
60404
60445
  break;
60405
- case "reset_all_sizes":
60406
- reset_sizes(gobj, false);
60446
+ case "reset_node":
60447
+ reset_nodes(gobj, "this");
60448
+ break;
60449
+ case "reset_topic_nodes":
60450
+ reset_nodes(gobj, "same_topic");
60407
60451
  break;
60408
- case "reset_topic_sizes":
60409
- reset_sizes(gobj, true);
60452
+ case "reset_all_nodes":
60453
+ reset_nodes(gobj, "all");
60454
+ break;
60455
+ case "reset_edge":
60456
+ reset_edges(gobj, "this");
60457
+ break;
60458
+ case "reset_same_type_edges":
60459
+ reset_edges(gobj, "same_type");
60460
+ break;
60461
+ case "reset_all_edges":
60462
+ reset_edges(gobj, "all");
60410
60463
  break;
60411
60464
  case "port_properties":
60412
60465
  if (priv._context_node_id && priv._context_port_key) {
@@ -60500,64 +60553,89 @@ function copy_size_to_nodes(gobj, same_topic_only) {
60500
60553
  });
60501
60554
  }
60502
60555
  }
60556
+ var NODE_STYLE_KEYS = [
60557
+ "size",
60558
+ "fill",
60559
+ "stroke",
60560
+ "lineWidth",
60561
+ "node_shape"
60562
+ ];
60563
+ var PORT_STYLE_KEYS = [
60564
+ "portR",
60565
+ "port_sizes",
60566
+ "port_shapes",
60567
+ "port_shape"
60568
+ ];
60503
60569
  /************************************************************
60504
- * Forget every SAVED size: the card sizes, the port radii and the
60505
- * per-port radii, per node and as topic defaults (`resize all`),
60506
- * for one topic or for all of them. The cards go back to the
60507
- * library's defaults on the spot, and Save writes the cleared
60508
- * entries -- a size nobody chose is not written back (see
60509
- * update_geometry). Positions and edge styles are not touched:
60510
- * they are a different choice.
60570
+ * Forget these saved keys -- on the node of the menu alone
60571
+ * ('this'), or on every node of its topic and in the topic's
60572
+ * defaults ('same_topic'), or everywhere ('all'). Both copies of
60573
+ * an entry are stripped: the one in `_graph_properties` (which
60574
+ * Save writes, folded nodes included) and the one the node
60575
+ * carries. Returns the ids of the nodes on screen to reshape.
60511
60576
  ************************************************************/
60512
- function reset_sizes(gobj, same_topic_only) {
60577
+ function forget_saved_node_keys(gobj, nd, scope, keys) {
60513
60578
  let priv = gobj.priv;
60514
60579
  let graph = priv.graph;
60515
- let topic = "";
60516
- if (same_topic_only) {
60517
- let nd = priv._context_node_id ? graph.getNodeData(priv._context_node_id) : null;
60518
- if (!nd || !nd.data || !nd.data.topic_name) {
60519
- log_error(`${gobj_short_name(gobj)}: reset topic sizes without a node`);
60520
- return;
60521
- }
60522
- topic = nd.data.topic_name;
60523
- }
60524
- const SIZE_KEYS = [
60525
- "size",
60526
- "portR",
60527
- "port_sizes"
60528
- ];
60529
60580
  let strip = (props) => {
60530
60581
  if (!is_object(props)) return;
60531
- for (let k of SIZE_KEYS) delete props[k];
60582
+ for (let k of keys) delete props[k];
60532
60583
  };
60584
+ if (scope === "this") {
60585
+ strip(node_props_entry(gobj, nd));
60586
+ strip(nd.data.graph_props);
60587
+ if (nd.data.record) strip(nd.data.record._geometry);
60588
+ return [nd.id];
60589
+ }
60590
+ let topic = scope === "same_topic" ? nd.data.topic_name : "";
60533
60591
  for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
60534
60592
  if (topic && topic_name !== topic) continue;
60535
60593
  if (is_object(props.nodes)) for (let node_props of Object.values(props.nodes)) strip(node_props);
60536
60594
  strip(props.defaults);
60537
60595
  }
60538
60596
  let ids = [];
60539
- for (let nd of graph.getNodeData() || []) {
60540
- if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) continue;
60541
- if (topic && nd.data.topic_name !== topic) continue;
60542
- strip(nd.data.graph_props);
60543
- if (nd.data.record) strip(nd.data.record._geometry);
60544
- ids.push(nd.id);
60597
+ for (let n of graph.getNodeData() || []) {
60598
+ if (!n || !n.data || !n.data.desc || is_more_node(n)) continue;
60599
+ if (topic && n.data.topic_name !== topic) continue;
60600
+ strip(n.data.graph_props);
60601
+ if (n.data.record) strip(n.data.record._geometry);
60602
+ ids.push(n.id);
60545
60603
  }
60604
+ return ids;
60605
+ }
60606
+ function reshape_after_reset(gobj, ids) {
60607
+ let graph = gobj.priv.graph;
60546
60608
  reshape_nodes(gobj, ids);
60547
60609
  graph.draw().then(() => {
60548
60610
  update_resize_handles_position(gobj);
60549
60611
  update_port_resize_handles_position(gobj);
60612
+ update_port_icon_position(gobj);
60550
60613
  mark_graph_dirty(gobj);
60551
60614
  });
60552
60615
  }
60553
60616
  /************************************************************
60617
+ * Forget the saved look of nodes (NODE_STYLE_KEYS), back to the
60618
+ * library's: this node, its topic's, or all of them. A figure
60619
+ * saved as a square before the circle became the default goes
60620
+ * back to the default this way.
60621
+ ************************************************************/
60622
+ function reset_nodes(gobj, scope) {
60623
+ let priv = gobj.priv;
60624
+ let nd = priv._context_node_id ? priv.graph.getNodeData(priv._context_node_id) : null;
60625
+ if (!nd || !nd.data || !nd.data.topic_name) {
60626
+ log_error(`${gobj_short_name(gobj)}: reset nodes without a node`);
60627
+ return;
60628
+ }
60629
+ reshape_after_reset(gobj, forget_saved_node_keys(gobj, nd, scope, NODE_STYLE_KEYS));
60630
+ }
60631
+ /************************************************************
60554
60632
  * Forget the saved SHAPE and RADIUS of ports, back to the
60555
60633
  * library's own:
60556
60634
  * 'this' the port of the menu, on its node only
60557
60635
  * 'same_topic' every port of the node's topic, with the
60558
60636
  * topic's port defaults
60559
60637
  * 'all' every port of every topic, likewise
60560
- * The node sizes are not touched: that is `reset sizes`.
60638
+ * The node's own look is not touched: that is `reset node`.
60561
60639
  ************************************************************/
60562
60640
  function reset_ports(gobj, scope) {
60563
60641
  let priv = gobj.priv;
@@ -60569,12 +60647,10 @@ function reset_ports(gobj, scope) {
60569
60647
  log_error(`${gobj_short_name(gobj)}: reset ports without a port`);
60570
60648
  return;
60571
60649
  }
60572
- const PORT_KEYS = [
60573
- "portR",
60574
- "port_sizes",
60575
- "port_shapes",
60576
- "port_shape"
60577
- ];
60650
+ if (scope !== "this") {
60651
+ reshape_after_reset(gobj, forget_saved_node_keys(gobj, nd, scope, PORT_STYLE_KEYS));
60652
+ return;
60653
+ }
60578
60654
  let strip_port = (props) => {
60579
60655
  if (!is_object(props)) return;
60580
60656
  for (let k of ["port_sizes", "port_shapes"]) if (is_object(props[k])) {
@@ -60582,35 +60658,72 @@ function reset_ports(gobj, scope) {
60582
60658
  if (Object.keys(props[k]).length === 0) delete props[k];
60583
60659
  }
60584
60660
  };
60585
- let strip_all = (props) => {
60586
- if (!is_object(props)) return;
60587
- for (let k of PORT_KEYS) delete props[k];
60661
+ strip_port(node_props_entry(gobj, nd));
60662
+ strip_port(nd.data.graph_props);
60663
+ if (nd.data.record) strip_port(nd.data.record._geometry);
60664
+ reshape_after_reset(gobj, [node_id]);
60665
+ }
60666
+ /************************************************************
60667
+ * Forget the saved style of edges, back to what they inherit:
60668
+ * 'this' the edge of the menu, its own entry
60669
+ * 'same_type' every edge of its hook in its parent topic,
60670
+ * with that hook's default
60671
+ * 'all' every edge, with every edge default
60672
+ * The same three scopes as the edge properties popover.
60673
+ ************************************************************/
60674
+ function reset_edges(gobj, scope) {
60675
+ let priv = gobj.priv;
60676
+ let graph = priv.graph;
60677
+ let ed = priv._context_edge_id ? graph.getEdgeData(priv._context_edge_id) : null;
60678
+ if (!ed || !ed.data || !ed.data.parent_topic) {
60679
+ log_error(`${gobj_short_name(gobj)}: reset edges without an edge`);
60680
+ return;
60681
+ }
60682
+ let src = ed.data;
60683
+ let hits = (d) => {
60684
+ if (!d || !d.parent_topic) return false;
60685
+ if (scope === "this") return edge_key_of(d) === edge_key_of(src) && d.parent_topic === src.parent_topic;
60686
+ if (scope === "same_type") return d.parent_topic === src.parent_topic && d.hook_name === src.hook_name;
60687
+ return true;
60588
60688
  };
60589
- let ids = [];
60590
- if (scope === "this") {
60591
- strip_port(node_props_entry(gobj, nd));
60592
- strip_port(nd.data.graph_props);
60593
- if (nd.data.record) strip_port(nd.data.record._geometry);
60594
- ids.push(node_id);
60595
- } else {
60596
- let topic = scope === "same_topic" ? nd.data.topic_name : "";
60597
- for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
60598
- if (topic && topic_name !== topic) continue;
60599
- if (is_object(props.nodes)) for (let node_props of Object.values(props.nodes)) strip_all(node_props);
60600
- strip_all(props.defaults);
60689
+ for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
60690
+ if (!is_object(props)) continue;
60691
+ if (scope !== "all" && topic_name !== src.parent_topic) continue;
60692
+ if (is_object(props.edges)) {
60693
+ for (let key of Object.keys(props.edges)) {
60694
+ let hook_name = key.split(":")[0];
60695
+ if (scope === "this" && key !== edge_key_of(src)) continue;
60696
+ if (scope === "same_type" && hook_name !== src.hook_name) continue;
60697
+ delete props.edges[key];
60698
+ }
60699
+ if (Object.keys(props.edges).length === 0) delete props.edges;
60601
60700
  }
60602
- for (let n of graph.getNodeData() || []) {
60603
- if (!n || !n.data || !n.data.desc || is_more_node(n)) continue;
60604
- if (topic && n.data.topic_name !== topic) continue;
60605
- strip_all(n.data.graph_props);
60606
- if (n.data.record) strip_all(n.data.record._geometry);
60607
- ids.push(n.id);
60701
+ if (is_object(props.defaults)) {
60702
+ if (scope === "same_type" && is_object(props.defaults.edge_styles)) {
60703
+ delete props.defaults.edge_styles[src.hook_name];
60704
+ if (Object.keys(props.defaults.edge_styles).length === 0) delete props.defaults.edge_styles;
60705
+ } else if (scope === "all") {
60706
+ delete props.defaults.edge_styles;
60707
+ delete props.defaults.edge_style;
60708
+ }
60608
60709
  }
60609
60710
  }
60610
- reshape_nodes(gobj, ids);
60711
+ let updates = [];
60712
+ for (let e of graph.getEdgeData() || []) {
60713
+ if (!e || !hits(e.data)) continue;
60714
+ let style = edge_style_of(gobj, e.data);
60715
+ updates.push({
60716
+ id: e.id,
60717
+ style: {
60718
+ lineWidth: style.lineWidth,
60719
+ stroke: style.stroke
60720
+ },
60721
+ data: Object.assign({}, e.data, { themed_default: style.themed_default })
60722
+ });
60723
+ }
60724
+ deselect_edge(gobj);
60725
+ if (updates.length > 0) graph.updateEdgeData(updates);
60611
60726
  graph.draw().then(() => {
60612
- update_port_resize_handles_position(gobj);
60613
- update_port_icon_position(gobj);
60614
60727
  mark_graph_dirty(gobj);
60615
60728
  });
60616
60729
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.133",
3
+ "version": "7.23.134",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",