@yuneta/gobj-ui 7.23.132 → 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.
@@ -55080,7 +55080,7 @@ var NODE_SHAPES = [
55080
55080
  "hexagon",
55081
55081
  "star"
55082
55082
  ];
55083
- var DEFAULT_NODE_SHAPE = "square";
55083
+ var DEFAULT_NODE_SHAPE = "circle";
55084
55084
  /***************************************************************
55085
55085
  * Internal layout and operation mode definitions
55086
55086
  ***************************************************************/
@@ -55233,6 +55233,7 @@ var PRIVATE_DATA$4 = {
55233
55233
  _focus_topic: null,
55234
55234
  _focus_ids: [],
55235
55235
  _on_pointerdown_focus: null,
55236
+ _on_native_contextmenu: null,
55236
55237
  _uninstall_long_press: null,
55237
55238
  toolbar_collapsed: true,
55238
55239
  _toolbars_could_collapse: null,
@@ -55330,6 +55331,10 @@ function mt_destroy$4(gobj) {
55330
55331
  priv.$container.removeEventListener("focusout", priv._on_focusout_restore);
55331
55332
  priv._on_focusout_restore = null;
55332
55333
  }
55334
+ if (priv._on_native_contextmenu) {
55335
+ priv.$container.removeEventListener("contextmenu", priv._on_native_contextmenu, true);
55336
+ priv._on_native_contextmenu = null;
55337
+ }
55333
55338
  if (priv.theme_observer) {
55334
55339
  priv.theme_observer.disconnect();
55335
55340
  priv.theme_observer = null;
@@ -55533,6 +55538,13 @@ function configure_events(gobj) {
55533
55538
  if ($canvas && $canvas.isConnected && document.activeElement !== $canvas) $canvas.focus({ preventScroll: true });
55534
55539
  };
55535
55540
  priv.$container.addEventListener("focusout", priv._on_focusout_restore);
55541
+ if (priv._on_native_contextmenu) priv.$container.removeEventListener("contextmenu", priv._on_native_contextmenu, true);
55542
+ priv._on_native_contextmenu = (ev) => {
55543
+ let target = ev.target;
55544
+ if (target && typeof target.closest === "function" && target.closest("input, textarea, select, [contenteditable]")) return;
55545
+ ev.preventDefault();
55546
+ };
55547
+ priv.$container.addEventListener("contextmenu", priv._on_native_contextmenu, true);
55536
55548
  graph.on("keydown", (evt) => {
55537
55549
  let ctrl = !!(evt.ctrlKey || evt.metaKey);
55538
55550
  if (ctrl && (evt.key === "a" || evt.key === "A")) {
@@ -55566,7 +55578,8 @@ function configure_plugins(gobj) {
55566
55578
  }
55567
55579
  });
55568
55580
  let menu_enable = (e) => {
55569
- return e.targetType === "node" || e.targetType === "edge";
55581
+ if (e.targetType === "node") return true;
55582
+ return e.targetType === "edge" && !!priv.edit_mode;
55570
55583
  };
55571
55584
  graph_add_plugin(gobj, "contextmenu", {
55572
55585
  trigger: "contextmenu",
@@ -56402,11 +56415,8 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
56402
56415
  let paint = node_paint_of(gobj, desc, geometry);
56403
56416
  let fill = dark ? mix_colors(paint.fill, .25, "#2c3542") : mix_colors(paint.fill, .1, "#ffffff");
56404
56417
  let stroke = dark ? mix_colors(paint.fill, .85, "#ffffff") : paint.fill;
56405
- let line_width = 2;
56406
- if (paint.stroke !== getStrokeColor(paint.fill)) {
56407
- stroke = paint.stroke;
56408
- line_width = Math.max(paint.lineWidth, 2);
56409
- }
56418
+ let line_width = paint.lineWidth;
56419
+ if (paint.stroke !== getStrokeColor(paint.fill)) stroke = paint.stroke;
56410
56420
  if (f.selected) {
56411
56421
  stroke = SELECT_RING;
56412
56422
  line_width = 3;
@@ -56635,42 +56645,17 @@ function draw_link(gobj, child_topic, child_id, source_col, fkey, verbose) {
56635
56645
  return;
56636
56646
  }
56637
56647
  if (get_edge_by_link(gobj, parent_topic, parent_id, hook_name, child_topic, child_id, fkey_name)) return;
56638
- let dark = priv.theme === "dark";
56639
56648
  let is_tree = parent_topic === child_topic;
56640
- let saved_lineWidth = is_tree ? 2 : 1.6;
56641
- let saved_stroke = is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
56642
- let themed_default = true;
56643
- let topic_props = priv._graph_properties[parent_topic];
56644
- if (topic_props) {
56645
- if ((0, _yuneta_gobj_js.is_object)(topic_props.edges)) {
56646
- let edge_key = hook_name + ":" + parent_id + ":" + child_id;
56647
- let edge_props = topic_props.edges[edge_key];
56648
- if (edge_props) {
56649
- if (edge_props.lineWidth != null) saved_lineWidth = edge_props.lineWidth;
56650
- if (edge_props.stroke) {
56651
- saved_stroke = edge_props.stroke;
56652
- themed_default = false;
56653
- }
56654
- }
56655
- }
56656
- if (themed_default && (0, _yuneta_gobj_js.is_object)(topic_props.defaults)) {
56657
- let defs = topic_props.defaults;
56658
- if (defs.edge_styles && defs.edge_styles[hook_name]) {
56659
- let hook_style = defs.edge_styles[hook_name];
56660
- if (hook_style.lineWidth != null) saved_lineWidth = hook_style.lineWidth;
56661
- if (hook_style.stroke) {
56662
- saved_stroke = hook_style.stroke;
56663
- themed_default = false;
56664
- }
56665
- } else if (defs.edge_style) {
56666
- if (defs.edge_style.lineWidth != null) saved_lineWidth = defs.edge_style.lineWidth;
56667
- if (defs.edge_style.stroke) {
56668
- saved_stroke = defs.edge_style.stroke;
56669
- themed_default = false;
56670
- }
56671
- }
56672
- }
56673
- }
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;
56674
56659
  let edge = {
56675
56660
  id: build_edge_id(gobj),
56676
56661
  type: edge_type_for(gobj),
@@ -59358,6 +59343,7 @@ function show_node_popover(gobj) {
59358
59343
  };
59359
59344
  }));
59360
59345
  shapeSelect.value = nodeData.data && nodeData.data.desc ? node_figure_of(gobj, nodeData.data.desc, nodeData.data.graph_props || {}) : DEFAULT_NODE_SHAPE;
59346
+ let orig_figure = shapeSelect.value;
59361
59347
  create_form_label(popover, "apply to");
59362
59348
  let scopeSelect = create_form_select(popover, [
59363
59349
  {
@@ -59384,7 +59370,7 @@ function show_node_popover(gobj) {
59384
59370
  style: "flex:1;padding:6px;background:#1890ff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;",
59385
59371
  onClick: () => {
59386
59372
  drop_preview_undo(gobj, "_node_preview_undo");
59387
- apply_node_properties(gobj, node_id, fillInput.value, strokeInput.value, parseInt(lwInput.value) || 1, scopeSelect.value, shapeSelect.value);
59373
+ apply_node_properties(gobj, node_id, fillInput.value, strokeInput.value, parseInt(lwInput.value) || 1, scopeSelect.value, shapeSelect.value !== orig_figure ? shapeSelect.value : "");
59388
59374
  }
59389
59375
  }]);
59390
59376
  priv.$container.appendChild(popover);
@@ -60269,19 +60255,81 @@ function apply_edge_properties(gobj, edge_id, lineWidth, stroke, scope) {
60269
60255
  deselect_edge(gobj);
60270
60256
  }
60271
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
+ /************************************************************
60272
60310
  * Save edge styles into _graph_properties (called from
60273
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.
60274
60319
  ************************************************************/
60275
60320
  function update_edge_geometry(gobj, edge_id) {
60276
60321
  let priv = gobj.priv;
60277
60322
  let edgeData = priv.graph.getEdgeData(edge_id);
60278
60323
  if (!edgeData || !edgeData.data || !edgeData.data.parent_topic) return;
60279
60324
  let style = edgeData.style || {};
60280
- let lineWidth = style.lineWidth;
60281
- let stroke = style.stroke;
60282
- let parent_topic = edgeData.data.parent_topic;
60283
- let edge_key = edgeData.data.hook_name + ":" + edgeData.data.parent_id + ":" + edgeData.data.child_id;
60284
- 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) {
60285
60333
  let topic_props = priv._graph_properties[parent_topic];
60286
60334
  if (topic_props && (0, _yuneta_gobj_js.is_object)(topic_props.edges)) {
60287
60335
  delete topic_props.edges[edge_key];
@@ -60292,8 +60340,6 @@ function update_edge_geometry(gobj, edge_id) {
60292
60340
  if (!(0, _yuneta_gobj_js.is_object)(priv._graph_properties[parent_topic])) priv._graph_properties[parent_topic] = {};
60293
60341
  let topic_props = priv._graph_properties[parent_topic];
60294
60342
  if (!(0, _yuneta_gobj_js.is_object)(topic_props.edges)) topic_props.edges = {};
60295
- let edge_props = { lineWidth };
60296
- if (stroke) edge_props.stroke = stroke;
60297
60343
  topic_props.edges[edge_key] = edge_props;
60298
60344
  }
60299
60345
  /************************************************************
@@ -60317,7 +60363,7 @@ function build_context_menu_items(gobj, e) {
60317
60363
  let containerRect = priv.$container.getBoundingClientRect();
60318
60364
  let canvasPoint = graph.getCanvasByViewport([e.client.x - containerRect.left, e.client.y - containerRect.top]);
60319
60365
  let port_key = detect_port_click(gobj, node_id, canvasPoint[0], canvasPoint[1]);
60320
- if (port_key) {
60366
+ if (port_key && priv.edit_mode) {
60321
60367
  priv._context_port_key = port_key;
60322
60368
  return build_port_context_menu(gobj, node_id, port_key);
60323
60369
  } else return build_node_context_menu(gobj, node_id);
@@ -60347,8 +60393,11 @@ function build_node_context_menu(gobj, node_id) {
60347
60393
  if (gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
60348
60394
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize all"), "resize_all_nodes"));
60349
60395
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize topic nodes"), "resize_topic_nodes"));
60350
- items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset sizes"), "reset_all_sizes"));
60351
- 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"));
60352
60401
  }
60353
60402
  return items;
60354
60403
  }
@@ -60362,14 +60411,27 @@ function build_port_context_menu(gobj, node_id, port_key) {
60362
60411
  items.push(ctx_item("g6-icon-edit", (0, i18next.t)("port properties"), "port_properties"));
60363
60412
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize all ports"), "resize_all_ports"));
60364
60413
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize topic ports"), "resize_topic_ports"));
60414
+ items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset port"), "reset_port"));
60415
+ items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset topic ports"), "reset_topic_ports"));
60416
+ items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset all ports"), "reset_all_ports"));
60365
60417
  }
60366
60418
  return items;
60367
60419
  }
60368
60420
  /************************************************************
60369
- * Build edge context menu items (prepared for expansion).
60421
+ * Build edge context menu items: the two floating icons of a
60422
+ * selected edge, for a right click and for a finger.
60370
60423
  ************************************************************/
60371
60424
  function build_edge_context_menu(gobj) {
60372
- return [];
60425
+ let items = [];
60426
+ if (gobj.priv.edit_mode) {
60427
+ inject_svg_icons();
60428
+ items.push(ctx_item("g6-icon-edit", (0, i18next.t)("edge properties"), "edge_properties"));
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"));
60433
+ }
60434
+ return items;
60373
60435
  }
60374
60436
  /************************************************************
60375
60437
  * Handle context menu click: dispatch by value.
@@ -60386,11 +60448,23 @@ function handle_context_menu_click(gobj, value) {
60386
60448
  case "resize_topic_nodes":
60387
60449
  copy_size_to_nodes(gobj, true);
60388
60450
  break;
60389
- case "reset_all_sizes":
60390
- 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");
60456
+ break;
60457
+ case "reset_all_nodes":
60458
+ reset_nodes(gobj, "all");
60459
+ break;
60460
+ case "reset_edge":
60461
+ reset_edges(gobj, "this");
60391
60462
  break;
60392
- case "reset_topic_sizes":
60393
- reset_sizes(gobj, true);
60463
+ case "reset_same_type_edges":
60464
+ reset_edges(gobj, "same_type");
60465
+ break;
60466
+ case "reset_all_edges":
60467
+ reset_edges(gobj, "all");
60394
60468
  break;
60395
60469
  case "port_properties":
60396
60470
  if (priv._context_node_id && priv._context_port_key) {
@@ -60401,7 +60475,33 @@ function handle_context_menu_click(gobj, value) {
60401
60475
  case "resize_all_ports":
60402
60476
  copy_size_to_ports(gobj, false);
60403
60477
  break;
60404
- case "resize_topic_ports": copy_size_to_ports(gobj, true);
60478
+ case "resize_topic_ports":
60479
+ copy_size_to_ports(gobj, true);
60480
+ break;
60481
+ case "reset_port":
60482
+ reset_ports(gobj, "this");
60483
+ break;
60484
+ case "reset_topic_ports":
60485
+ reset_ports(gobj, "same_topic");
60486
+ break;
60487
+ case "reset_all_ports":
60488
+ reset_ports(gobj, "all");
60489
+ break;
60490
+ case "edge_properties":
60491
+ if (priv._context_edge_id) {
60492
+ deselect_node(gobj);
60493
+ select_edge(gobj, priv._context_edge_id);
60494
+ show_edge_popover(gobj);
60495
+ }
60496
+ break;
60497
+ case "unlink_edge":
60498
+ if (priv._context_edge_id) {
60499
+ deselect_node(gobj);
60500
+ select_edge(gobj, priv._context_edge_id);
60501
+ request_unlink_edge(gobj);
60502
+ }
60503
+ break;
60504
+ default: (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: unknown context menu item: ${value}`);
60405
60505
  }
60406
60506
  }
60407
60507
  /************************************************************
@@ -60458,53 +60558,177 @@ function copy_size_to_nodes(gobj, same_topic_only) {
60458
60558
  });
60459
60559
  }
60460
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
+ ];
60461
60574
  /************************************************************
60462
- * Forget every SAVED size: the card sizes, the port radii and the
60463
- * per-port radii, per node and as topic defaults (`resize all`),
60464
- * for one topic or for all of them. The cards go back to the
60465
- * library's defaults on the spot, and Save writes the cleared
60466
- * entries -- a size nobody chose is not written back (see
60467
- * update_geometry). Positions and edge styles are not touched:
60468
- * 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.
60469
60581
  ************************************************************/
60470
- function reset_sizes(gobj, same_topic_only) {
60582
+ function forget_saved_node_keys(gobj, nd, scope, keys) {
60471
60583
  let priv = gobj.priv;
60472
60584
  let graph = priv.graph;
60473
- let topic = "";
60474
- if (same_topic_only) {
60475
- let nd = priv._context_node_id ? graph.getNodeData(priv._context_node_id) : null;
60476
- if (!nd || !nd.data || !nd.data.topic_name) {
60477
- (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: reset topic sizes without a node`);
60478
- return;
60479
- }
60480
- topic = nd.data.topic_name;
60481
- }
60482
- const SIZE_KEYS = [
60483
- "size",
60484
- "portR",
60485
- "port_sizes"
60486
- ];
60487
60585
  let strip = (props) => {
60488
60586
  if (!(0, _yuneta_gobj_js.is_object)(props)) return;
60489
- for (let k of SIZE_KEYS) delete props[k];
60587
+ for (let k of keys) delete props[k];
60490
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 : "";
60491
60596
  for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
60492
60597
  if (topic && topic_name !== topic) continue;
60493
60598
  if ((0, _yuneta_gobj_js.is_object)(props.nodes)) for (let node_props of Object.values(props.nodes)) strip(node_props);
60494
60599
  strip(props.defaults);
60495
60600
  }
60496
60601
  let ids = [];
60497
- for (let nd of graph.getNodeData() || []) {
60498
- if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) continue;
60499
- if (topic && nd.data.topic_name !== topic) continue;
60500
- strip(nd.data.graph_props);
60501
- if (nd.data.record) strip(nd.data.record._geometry);
60502
- 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);
60503
60608
  }
60609
+ return ids;
60610
+ }
60611
+ function reshape_after_reset(gobj, ids) {
60612
+ let graph = gobj.priv.graph;
60504
60613
  reshape_nodes(gobj, ids);
60505
60614
  graph.draw().then(() => {
60506
60615
  update_resize_handles_position(gobj);
60507
60616
  update_port_resize_handles_position(gobj);
60617
+ update_port_icon_position(gobj);
60618
+ mark_graph_dirty(gobj);
60619
+ });
60620
+ }
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
+ /************************************************************
60637
+ * Forget the saved SHAPE and RADIUS of ports, back to the
60638
+ * library's own:
60639
+ * 'this' the port of the menu, on its node only
60640
+ * 'same_topic' every port of the node's topic, with the
60641
+ * topic's port defaults
60642
+ * 'all' every port of every topic, likewise
60643
+ * The node's own look is not touched: that is `reset node`.
60644
+ ************************************************************/
60645
+ function reset_ports(gobj, scope) {
60646
+ let priv = gobj.priv;
60647
+ let graph = priv.graph;
60648
+ let node_id = priv._context_node_id;
60649
+ let port_key = priv._context_port_key;
60650
+ let nd = node_id ? graph.getNodeData(node_id) : null;
60651
+ if (!nd || !nd.data || !nd.data.topic_name || !port_key) {
60652
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: reset ports without a port`);
60653
+ return;
60654
+ }
60655
+ if (scope !== "this") {
60656
+ reshape_after_reset(gobj, forget_saved_node_keys(gobj, nd, scope, PORT_STYLE_KEYS));
60657
+ return;
60658
+ }
60659
+ let strip_port = (props) => {
60660
+ if (!(0, _yuneta_gobj_js.is_object)(props)) return;
60661
+ for (let k of ["port_sizes", "port_shapes"]) if ((0, _yuneta_gobj_js.is_object)(props[k])) {
60662
+ delete props[k][port_key];
60663
+ if (Object.keys(props[k]).length === 0) delete props[k];
60664
+ }
60665
+ };
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;
60693
+ };
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;
60705
+ }
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
+ }
60714
+ }
60715
+ }
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);
60731
+ graph.draw().then(() => {
60508
60732
  mark_graph_dirty(gobj);
60509
60733
  });
60510
60734
  }