@yuneta/gobj-ui 7.23.133 → 7.23.135

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