@elyra/canvas 13.36.0 → 13.37.0

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.
Files changed (59) hide show
  1. package/README.md +3 -3
  2. package/dist/canvas-controller-63cc6a02.js +2 -0
  3. package/dist/canvas-controller-63cc6a02.js.map +1 -0
  4. package/dist/canvas-controller-db4fe63c.js +2 -0
  5. package/dist/canvas-controller-db4fe63c.js.map +1 -0
  6. package/dist/common-canvas-c3348938.js +2 -0
  7. package/dist/common-canvas-c3348938.js.map +1 -0
  8. package/dist/common-canvas-edd4c0e8.js +2 -0
  9. package/dist/common-canvas-edd4c0e8.js.map +1 -0
  10. package/dist/common-canvas.es.js +1 -1
  11. package/dist/common-canvas.js +1 -1
  12. package/dist/{common-properties-da4cf4b7.js → common-properties-7b2bc583.js} +2 -2
  13. package/dist/common-properties-7b2bc583.js.map +1 -0
  14. package/dist/{common-properties-d98e7ae0.js → common-properties-a17c37e0.js} +2 -2
  15. package/dist/common-properties-a17c37e0.js.map +1 -0
  16. package/dist/{context-menu-wrapper-b0796e40.js → context-menu-wrapper-0481138e.js} +2 -2
  17. package/dist/{context-menu-wrapper-b0796e40.js.map → context-menu-wrapper-0481138e.js.map} +1 -1
  18. package/dist/{context-menu-wrapper-2339cf43.js → context-menu-wrapper-b9f37df0.js} +2 -2
  19. package/dist/{context-menu-wrapper-2339cf43.js.map → context-menu-wrapper-b9f37df0.js.map} +1 -1
  20. package/dist/keyboard-utils-91fe9377.js +2 -0
  21. package/dist/keyboard-utils-91fe9377.js.map +1 -0
  22. package/dist/keyboard-utils-ebb1278f.js +2 -0
  23. package/dist/keyboard-utils-ebb1278f.js.map +1 -0
  24. package/dist/lib/canvas-controller.es.js +1 -1
  25. package/dist/lib/canvas-controller.js +1 -1
  26. package/dist/lib/canvas.es.js +1 -1
  27. package/dist/lib/canvas.js +1 -1
  28. package/dist/lib/context-menu.es.js +1 -1
  29. package/dist/lib/context-menu.js +1 -1
  30. package/dist/lib/properties.es.js +1 -1
  31. package/dist/lib/properties.js +1 -1
  32. package/dist/{toolbar-9fe1c131.js → toolbar-14d981ca.js} +2 -2
  33. package/dist/{toolbar-9fe1c131.js.map → toolbar-14d981ca.js.map} +1 -1
  34. package/dist/{toolbar-20e9d272.js → toolbar-5b743909.js} +2 -2
  35. package/dist/{toolbar-20e9d272.js.map → toolbar-5b743909.js.map} +1 -1
  36. package/package.json +1 -1
  37. package/src/common-canvas/canvas-controller.js +3 -2
  38. package/src/common-canvas/cc-contents.jsx +8 -4
  39. package/src/common-canvas/keyboard-utils.js +11 -4
  40. package/src/common-canvas/svg-canvas-renderer.js +17 -13
  41. package/src/common-canvas/svg-canvas-utils-comments.js +21 -23
  42. package/src/object-model/layout-dimensions.js +8 -0
  43. package/src/object-model/redux/reducers/comments.js +1 -2
  44. package/stats.html +1 -1
  45. package/types/canvas-controller.ts +5 -4
  46. package/dist/canvas-controller-9fe978a8.js +0 -2
  47. package/dist/canvas-controller-9fe978a8.js.map +0 -1
  48. package/dist/canvas-controller-a25c4c1a.js +0 -2
  49. package/dist/canvas-controller-a25c4c1a.js.map +0 -1
  50. package/dist/common-canvas-2cfd5339.js +0 -2
  51. package/dist/common-canvas-2cfd5339.js.map +0 -1
  52. package/dist/common-canvas-e26eed05.js +0 -2
  53. package/dist/common-canvas-e26eed05.js.map +0 -1
  54. package/dist/common-properties-d98e7ae0.js.map +0 -1
  55. package/dist/common-properties-da4cf4b7.js.map +0 -1
  56. package/dist/keyboard-utils-2d0cea74.js +0 -2
  57. package/dist/keyboard-utils-2d0cea74.js.map +0 -1
  58. package/dist/keyboard-utils-d34ad679.js +0 -2
  59. package/dist/keyboard-utils-d34ad679.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elyra/canvas",
3
- "version": "13.36.0",
3
+ "version": "13.37.0",
4
4
  "description": "Elyra common-canvas",
5
5
  "main": "dist/common-canvas.js",
6
6
  "module": "dist/common-canvas.es.js",
@@ -1260,8 +1260,9 @@ export default class CanvasController {
1260
1260
  return this.objectModel.isHidingComments();
1261
1261
  }
1262
1262
 
1263
- // Sets text to be highlighted in the comments identified by the commentIds array passed in.
1264
- // pipelineId is optional. If highlightText is null or undefined the highlighting text will
1263
+ // Sets text to be highlighted in the comments identified by the commentIds array passed in
1264
+ // or, if set to a falsy value, the highlight text will be applied to all comments. The
1265
+ // pipelineId is optional. If highlightText is a falsy value, the highlighting will
1265
1266
  // be removed from the comments.
1266
1267
  setCommentHighlightText(commentIds, highlightText, pipelineId) {
1267
1268
  this.objectModel.getAPIPipeline(pipelineId).setCommentHighlighText(commentIds, highlightText);
@@ -104,10 +104,14 @@ class CanvasContents extends React.Component {
104
104
 
105
105
  componentDidMount() {
106
106
  this.logger.log("componentDidMount");
107
- this.svgCanvasD3 =
108
- new SVGCanvasD3(this.props.canvasInfo.id,
109
- this.svgCanvasDivSelector,
110
- this.props.canvasController);
107
+ // componentDidMount may be called twice in StrictMode so only
108
+ // create the svgCanvasD3 when necessary.
109
+ if (!this.svgCanvasD3) {
110
+ this.svgCanvasD3 =
111
+ new SVGCanvasD3(this.props.canvasInfo.id,
112
+ this.svgCanvasDivSelector,
113
+ this.props.canvasController);
114
+ }
111
115
  this.setCanvasInfo();
112
116
 
113
117
  if (this.props.canvasConfig.enableBrowserEditMenu) {
@@ -30,6 +30,10 @@ const SPACE_KEY = "Space";
30
30
  const SPACE_CHAR_KEY = " ";
31
31
  const COMMA_CHAR_KEY = ",";
32
32
 
33
+ // WARNING when adding a new letter constant below: If the shortcut requires the Meta
34
+ // key AND Shift key to be pressed, on Windows, if the user presses 'Ctrl' as the Meta
35
+ // key, the Shift will cause an upper case letter to be returned. See code below where
36
+ // toLowerCase() is called before comparison.
33
37
  const A_KEY = "a";
34
38
  const B_KEY = "b";
35
39
  const C_KEY = "c";
@@ -247,7 +251,8 @@ export default class KeyboardUtils {
247
251
  /* Link creation */
248
252
 
249
253
  static createLink(d3Event) {
250
- return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key === L_KEY;
254
+ // When meta key is 'Ctrl' on Windows, shift key will cause 'key' property to contain uppercase 'L' - so lowercase it!
255
+ return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key?.toLowerCase() === L_KEY;
251
256
  }
252
257
 
253
258
  /* Comment display */
@@ -293,7 +298,8 @@ export default class KeyboardUtils {
293
298
  }
294
299
 
295
300
  static strikethroughCommand(d3Event) {
296
- return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key === X_KEY;
301
+ // When meta key is 'Ctrl' on Windows, shift key will cause 'key' property to contain uppercase 'X' - so lowercase it!
302
+ return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key?.toLowerCase() === X_KEY;
297
303
  }
298
304
 
299
305
  static numberedListCommand(d3Event) {
@@ -313,7 +319,8 @@ export default class KeyboardUtils {
313
319
  }
314
320
 
315
321
  static quoteCommand(d3Event) {
316
- return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key === I_KEY;
322
+ // When meta key is 'Ctrl' on Windows, shift key will cause 'key' property to contain uppercase 'I' - so lowercase it!
323
+ return this.isMetaKey(d3Event) && d3Event.shiftKey && d3Event.key?.toLowerCase() === I_KEY;
317
324
  }
318
325
 
319
326
  static incHashesCommand(d3Event) {
@@ -479,7 +486,7 @@ export default class KeyboardUtils {
479
486
 
480
487
  // Returns true if either the 'Command Key' on Mac or
481
488
  // 'Control Key' or 'Windows key' on Windows is pressed.
482
- // evnt can be either a regular event object OR the
489
+ // evt can be either a regular event object OR the
483
490
  // d3event object provided by d3.
484
491
  static isMetaKey(evt) {
485
492
  if (CanvasUtils.isMacintosh()) {
@@ -68,7 +68,7 @@ import SVGCanvasPipeline from "./svg-canvas-pipeline";
68
68
  export default class SVGCanvasRenderer {
69
69
  constructor(pipelineId, canvasDiv, canvasController, canvasInfo, selectionInfo, breadcrumbs, nodeLayout, canvasLayout, config, supernodeInfo = {}) {
70
70
  this.logger = new Logger(["SVGCanvasRenderer", "PipeId", pipelineId]);
71
- this.logger.logStartTimer("constructor" + pipelineId.substring(0, 5));
71
+ this.logger.logStartTimer("constructor - " + pipelineId.substring(0, 5));
72
72
  this.pipelineId = pipelineId;
73
73
  this.supernodeInfo = supernodeInfo; // Contents will be 'empty object' in case of primary pipeline renderer
74
74
  this.canvasDiv = canvasDiv;
@@ -188,7 +188,7 @@ export default class SVGCanvasRenderer {
188
188
  this.supernodeInfo.d3Selection.selectAll(".d3-node-port-output").raise();
189
189
  }
190
190
 
191
- this.logger.logEndTimer("constructor" + pipelineId.substring(0, 5));
191
+ this.logger.logEndTimer("constructor - " + pipelineId.substring(0, 5));
192
192
  }
193
193
 
194
194
  // Sets the pressed state of the space bar. This is called
@@ -1886,7 +1886,6 @@ export default class SVGCanvasRenderer {
1886
1886
  // Optional foreign object to contain a React object
1887
1887
  nonBindingNodeGrps
1888
1888
  .selectChildren(".d3-foreign-object-external-node")
1889
- .attr("tabindex", -1)
1890
1889
  .data((d) => (d.layout.nodeExternalObject ? [d] : []), (d) => d.id)
1891
1890
  .join(
1892
1891
  (enter) =>
@@ -1901,6 +1900,7 @@ export default class SVGCanvasRenderer {
1901
1900
  }
1902
1901
  )
1903
1902
  .datum((d) => this.activePipeline.getNode(d.id))
1903
+ .attr("tabindex", -1)
1904
1904
  .attr("width", (d) => d.width)
1905
1905
  .attr("height", (d) => d.height)
1906
1906
  .attr("x", 0)
@@ -2298,7 +2298,6 @@ export default class SVGCanvasRenderer {
2298
2298
  linkInfosAll.forEach((li) => (li.link.navObject = d));
2299
2299
  this.setFocusObject(linkInfos[0].link, d3Event);
2300
2300
  }
2301
- CanvasUtils.stopPropagationAndPreventDefault(d3Event);
2302
2301
 
2303
2302
  } else if (KeyboardUtils.previousObjectInGroup(d3Event)) {
2304
2303
  const linkInfos = this.activePipeline.getPreviousLinksToNode(d);
@@ -2467,9 +2466,7 @@ export default class SVGCanvasRenderer {
2467
2466
  this.svgCanvasTextArea.completeEditing(d3Event);
2468
2467
  }
2469
2468
  if (!this.config.enableDragWithoutSelect) {
2470
- if (this.config.enableKeyboardNavigation) {
2471
- this.setFocusObject(d, d3Event);
2472
- }
2469
+ this.setFocusObject(d, d3Event, d.layout.onFocusAllowDefaultAction);
2473
2470
  const clickType = d3Event.button === 2 ? SINGLE_CLICK_CONTEXTMENU : SINGLE_CLICK;
2474
2471
  this.selectObjectD3Event(d3Event, d, clickType);
2475
2472
  }
@@ -4910,17 +4907,14 @@ export default class SVGCanvasRenderer {
4910
4907
  if (d.type === NODE_LINK) {
4911
4908
  const node = this.activePipeline.getNextNodeFromDataLink(d);
4912
4909
  this.setFocusObject(node, d3Event);
4913
- CanvasUtils.stopPropagationAndPreventDefault(d3Event);
4914
4910
 
4915
4911
  } else if (d.type === ASSOCIATION_LINK) {
4916
4912
  const node = this.activePipeline.getNextNodeFromAssocLink(d);
4917
4913
  this.setFocusObject(node, d3Event);
4918
- CanvasUtils.stopPropagationAndPreventDefault(d3Event);
4919
4914
 
4920
4915
  } else if (d.type === COMMENT_LINK) {
4921
4916
  const obj = this.activePipeline.getNextObjectFromCommentLink(d);
4922
4917
  this.setFocusObject(obj, d3Event);
4923
- CanvasUtils.stopPropagationAndPreventDefault(d3Event);
4924
4918
  }
4925
4919
 
4926
4920
  } else if (KeyboardUtils.previousObjectInGroup(d3Event)) {
@@ -5218,7 +5212,7 @@ export default class SVGCanvasRenderer {
5218
5212
  this.setFocusPreviousSubObject(link, d3Event);
5219
5213
 
5220
5214
  } else if (KeyboardUtils.cancelFocusOnSubObject(d3Event)) {
5221
- this.canvasController.setFocusObject(link);
5215
+ this.canvasController.restoreFocus();
5222
5216
 
5223
5217
  } else if (KeyboardUtils.moveLinkHandleUp(d3Event)) {
5224
5218
  if (this.config.enableEditingActions) {
@@ -6370,12 +6364,22 @@ export default class SVGCanvasRenderer {
6370
6364
  return objElement;
6371
6365
  }
6372
6366
 
6373
- setFocusObject(focusObj, evt) {
6367
+ // Sets the focus object passed in.
6368
+ setFocusObject(focusObj, evt, allowDefaultAction = false) {
6374
6369
  if (!this.config.enableKeyboardNavigation) {
6375
6370
  return;
6376
6371
  }
6377
6372
 
6378
- CanvasUtils.stopPropagationAndPreventDefault(evt);
6373
+ // If allowDefaultAction is specified as true, we do not 'preventDefault'
6374
+ // only stop propagation. Setting allowDefaultAction to true is useful for
6375
+ // applications that provide a React object for the node body and they want
6376
+ // the default action to go through to the React, perhaps to initiate a drag event.
6377
+ if (allowDefaultAction) {
6378
+ evt.stopPropagation();
6379
+
6380
+ } else {
6381
+ CanvasUtils.stopPropagationAndPreventDefault(evt);
6382
+ }
6379
6383
 
6380
6384
  this.canvasController.setFocusObject(focusObj, evt);
6381
6385
  }
@@ -34,19 +34,23 @@ export default class SvgCanvasUtilsComments {
34
34
  // Parse the HTML string.
35
35
  const parser = new DOMParser();
36
36
  const doc = parser.parseFromString(htmlString, "text/html");
37
+
38
+ // Get the raw text from the body element.
37
39
  const bodies = doc.getElementsByTagName("body");
38
40
  const body = bodies[0];
39
-
40
- // Look for the search string in the text only (no HTML tags) version of
41
- // the text.
42
- const searchStart = body?.innerText?.indexOf(searchStr);
43
-
44
- // If the search string was found, insert the <mark> tags
45
- if (searchStart > -1) {
46
- const elementInfos = [];
47
- this.searchForElementInfos(body, searchStart, searchStart + searchStr.length, 0, elementInfos);
48
- this.insertMarkElements(elementInfos);
49
-
41
+ const innerText = body?.innerText || "";
42
+
43
+ // Search for all matches of the search string.
44
+ const regex = new RegExp(searchStr, "gi");
45
+ const matches = innerText.matchAll(regex);
46
+
47
+ // If any matches of the search string were found, insert the <mark> tags
48
+ if (matches) {
49
+ for (const match of matches) {
50
+ const elementInfos = [];
51
+ this.searchForElementInfos(body, match.index, match.index + searchStr.length, 0, elementInfos);
52
+ this.insertMarkElements(elementInfos);
53
+ }
50
54
  return body.outerHTML;
51
55
  }
52
56
 
@@ -64,28 +68,22 @@ export default class SvgCanvasUtilsComments {
64
68
  let textStart = runStart;
65
69
  let textEnd = runStart;
66
70
 
67
- for (let i = 0; i < element.childNodes.length; i++) {
68
- const node = element.childNodes[i];
69
-
71
+ for (const node of element.childNodes) {
70
72
  if (node.nodeType === Node.TEXT_NODE) {
71
73
  const textLen = node?.textContent?.length;
72
74
  textEnd = textStart + textLen;
73
75
 
74
- if (!(textStart >= searchEnd || textEnd <= searchStart)) {
75
- let splitStart = 0;
76
- let splitEnd = textLen;
77
- if (searchStart > textStart) {
78
- splitStart = searchStart - textStart;
79
- }
80
- if (searchEnd < textEnd) {
81
- splitEnd = searchEnd - textStart;
82
- }
76
+ if (textStart < searchEnd && textEnd > searchStart) {
77
+ // Calculate split positions **within** the text node.
78
+ const splitStart = (searchStart > textStart) ? searchStart - textStart : 0;
79
+ const splitEnd = (searchEnd < textEnd) ? searchEnd - textStart : textLen;
83
80
 
84
81
  elementInfos.push({ splitStart, splitEnd, node });
85
82
  }
86
83
 
87
84
  } else if (node.nodeType === Node.ELEMENT_NODE) {
88
85
  textStart = this.searchForElementInfos(node, searchStart, searchEnd, textEnd, elementInfos);
86
+ textEnd = textStart;
89
87
  }
90
88
  }
91
89
  return textEnd;
@@ -53,6 +53,10 @@ const horizontalDefaultLayout = {
53
53
  // Displays the external object specified, as the body of the node
54
54
  nodeExternalObject: false,
55
55
 
56
+ // When set to true and the focus is being set on the node, the event
57
+ // is allowed to perform the default action on the node.
58
+ onFocusAllowDefaultAction: false,
59
+
56
60
  // Display image
57
61
  imageDisplay: true,
58
62
 
@@ -543,6 +547,10 @@ const verticalDefaultLayout = {
543
547
  // Displays the external object specified, as the body of the node
544
548
  nodeExternalObject: false,
545
549
 
550
+ // When set to true and the focus is being set on the node, the event
551
+ // is allowed to perform the default action on the node.
552
+ onFocusAllowDefaultAction: false,
553
+
546
554
  // Display image
547
555
  imageDisplay: true,
548
556
 
@@ -165,8 +165,7 @@ export default (state = [], action) => {
165
165
 
166
166
  case "SET_COMMENT_HIGHLIGHT_TEXT":
167
167
  return state.map((comment) => {
168
- const idx = action.data.commentIds.indexOf(comment.id);
169
- if (idx > -1) {
168
+ if (!action.data.commentIds || action.data.commentIds.indexOf(comment.id) > -1) {
170
169
  const newComment = { ...comment };
171
170
  if (action.data.highlightText) {
172
171
  newComment.highlightText = action.data.highlightText;