@@ -14,7 +14,7 @@ const PortData = function(model) {
1414
1515 const clonedData = util . cloneDeep ( model . get ( 'ports' ) ) || { } ;
1616 this . ports = [ ] ;
17- this . portsMap = { } ;
17+ this . portsMap = new Map ( ) ;
1818 this . groups = { } ;
1919 this . portLayoutNamespace = portLayoutNamespace ;
2020 this . portLabelLayoutNamespace = portLabelLayoutNamespace ;
@@ -27,11 +27,11 @@ const PortData = function(model) {
2727PortData . prototype = {
2828
2929 hasPort : function ( id ) {
30- return id in this . portsMap ;
30+ return this . portsMap . has ( id ) ;
3131 } ,
3232
3333 getPort : function ( id ) {
34- const port = this . portsMap [ id ] ;
34+ const port = this . portsMap . get ( id ) ;
3535 if ( port ) return port ;
3636 throw new Error ( 'Element: unable to find port with id ' + id ) ;
3737 } ,
@@ -100,22 +100,22 @@ PortData.prototype = {
100100
101101 const accumulator = {
102102 ports : ports ,
103- result : { }
103+ result : new Map ( )
104104 } ;
105105
106106 // For each individual port transformation, find the information necessary to calculate SVG transformations:
107107 util . toArray ( groupPortTransformations ) . reduce ( ( res , portTransformation , index ) => {
108108 const port = res . ports [ index ] ;
109109 const portId = port . id ;
110- res . result [ portId ] = {
110+ res . result . set ( portId , {
111111 index,
112112 portId,
113113 portTransformation : portTransformation ,
114114 labelTransformation : this . _getPortLabelTransformation ( port , Point ( portTransformation ) , elBBox ) ,
115115 portAttrs : port . attrs ,
116116 portSize : port . size ,
117117 labelSize : port . label . size
118- } ;
118+ } ) ;
119119 return res ;
120120 } , accumulator ) ;
121121
@@ -160,7 +160,7 @@ PortData.prototype = {
160160 for ( var j = 0 , m = ports . length ; j < m ; j ++ ) {
161161 const resolvedPort = this . _evaluatePort ( ports [ j ] ) ;
162162 this . ports . push ( resolvedPort ) ;
163- this . portsMap [ resolvedPort . id ] = resolvedPort ;
163+ this . portsMap . set ( resolvedPort . id , resolvedPort ) ;
164164 }
165165 } ,
166166
@@ -376,34 +376,34 @@ export const elementPortPrototype = {
376376 _processRemovedPort : function ( ) {
377377
378378 var current = this . get ( 'ports' ) || { } ;
379- var currentItemsMap = { } ;
379+ var currentIds = new Set ( ) ;
380380
381381 util . toArray ( current . items ) . forEach ( function ( item ) {
382- currentItemsMap [ item . id ] = true ;
382+ currentIds . add ( item . id ) ;
383383 } ) ;
384384
385385 var previous = this . previous ( 'ports' ) || { } ;
386- var removed = { } ;
386+ var removed = new Set ( ) ;
387387
388388 util . toArray ( previous . items ) . forEach ( function ( item ) {
389- if ( ! currentItemsMap [ item . id ] ) {
390- removed [ item . id ] = true ;
389+ if ( ! currentIds . has ( item . id ) ) {
390+ removed . add ( item . id ) ;
391391 }
392392 } ) ;
393393
394394 var graph = this . graph ;
395- if ( graph && ! util . isEmpty ( removed ) ) {
395+ if ( graph && removed . size > 0 ) {
396396
397397 var inboundLinks = graph . getConnectedLinks ( this , { inbound : true } ) ;
398398 inboundLinks . forEach ( function ( link ) {
399399
400- if ( removed [ link . get ( 'target' ) . port ] ) link . remove ( ) ;
400+ if ( removed . has ( link . get ( 'target' ) . port ) ) link . remove ( ) ;
401401 } ) ;
402402
403403 var outboundLinks = graph . getConnectedLinks ( this , { outbound : true } ) ;
404404 outboundLinks . forEach ( function ( link ) {
405405
406- if ( removed [ link . get ( 'source' ) . port ] ) link . remove ( ) ;
406+ if ( removed . has ( link . get ( 'source' ) . port ) ) link . remove ( ) ;
407407 } ) ;
408408 }
409409 } ,
@@ -417,7 +417,7 @@ export const elementPortPrototype = {
417417 } ,
418418
419419 /**
420- * @param {string } id
420+ * @param {string|number } id
421421 * @returns {boolean }
422422 */
423423 hasPort : function ( id ) {
@@ -442,11 +442,11 @@ export const elementPortPrototype = {
442442 } ,
443443
444444 /**
445- * @param {string } id
445+ * @param {string|number } id
446446 * @returns {object }
447447 */
448448 getPort : function ( id ) {
449- const port = util . toArray ( this . prop ( 'ports/items' ) ) . find ( port => port . id && port . id === id ) ;
449+ const port = util . toArray ( this . prop ( 'ports/items' ) ) . find ( port => port . id != null && port . id === id ) ;
450450 return util . cloneDeep ( port ) ;
451451 } ,
452452
@@ -461,11 +461,14 @@ export const elementPortPrototype = {
461461 getPortsPositions : function ( groupName ) {
462462
463463 const portsMetrics = this . getGroupPortsMetrics ( groupName ) ;
464+ // TODO: Return a `Map` keyed by the port id in the next major version.
465+ // A plain object keys the ports by the id as a string, so ports whose
466+ // ids differ only in type (`5` and `'5'`) overwrite each other here.
464467 const portsPosition = { } ;
465- for ( const portId in portsMetrics ) {
468+ for ( const [ portId , metrics ] of portsMetrics ) {
466469 const {
467470 portTransformation : { x, y, angle } ,
468- } = portsMetrics [ portId ] ;
471+ } = metrics ;
469472 portsPosition [ portId ] = {
470473 x : x ,
471474 y : y ,
@@ -477,7 +480,7 @@ export const elementPortPrototype = {
477480
478481 getPortMetrics : function ( portId ) {
479482 const port = this . _portSettingsData . getPort ( portId ) ;
480- return this . getGroupPortsMetrics ( port . group ) [ portId ] ;
483+ return this . getGroupPortsMetrics ( port . group ) . get ( portId ) ;
481484 } ,
482485
483486 getGroupPortsMetrics : function ( groupName ) {
@@ -505,7 +508,7 @@ export const elementPortPrototype = {
505508 } ,
506509
507510 /**
508- * @param {string } portId
511+ * @param {string|number } portId
509512 * @returns {Point }
510513 * @description Returns the port center in the graph coordinate system.
511514 * The port center is in the graph coordinate system, and the position
@@ -521,7 +524,7 @@ export const elementPortPrototype = {
521524 } ,
522525
523526 /**
524- * @param {string } portId
527+ * @param {string|number } portId
525528 * @param {object } [opt]
526529 * @param {boolean } [opt.rotate] - If true, the port bounding box is rotated
527530 * around the port center.
@@ -547,7 +550,7 @@ export const elementPortPrototype = {
547550 } ,
548551
549552 /**
550- * @param {string|Port } port port id or port
553+ * @param {string|number| Port } port port id or port
551554 * @returns {number } port index
552555 */
553556 getPortIndex : function ( port ) {
@@ -602,7 +605,7 @@ export const elementPortPrototype = {
602605 } ,
603606
604607 /**
605- * @param {string } portId
608+ * @param {string|number } portId
606609 * @param {string|object= } path
607610 * @param {*= } value
608611 * @param {object= } opt
@@ -794,7 +797,7 @@ export const elementViewPortPrototype = {
794797 'fill' : '#000000'
795798 }
796799 } ] ,
797- /** @type {Object <string, {portElement: Vectorizer, portLabelElement: Vectorizer}> } */
800+ /** @type {Map <string|number , {portElement: Vectorizer, portLabelElement: Vectorizer}> } */
798801 _portElementsCache : null ,
799802
800803 /**
@@ -826,7 +829,7 @@ export const elementViewPortPrototype = {
826829 } ,
827830
828831 _cleanPortsCache : function ( ) {
829- this . _portElementsCache = { } ;
832+ this . _portElementsCache = new Map ( ) ;
830833 } ,
831834
832835 /**
@@ -899,14 +902,15 @@ export const elementViewPortPrototype = {
899902 */
900903 _getPortElement : function ( port ) {
901904
902- if ( this . _portElementsCache [ port . id ] ) {
903- return this . _portElementsCache [ port . id ] . portElement ;
905+ const portCache = this . _portElementsCache . get ( port . id ) ;
906+ if ( portCache ) {
907+ return portCache . portElement ;
904908 }
905909 return this . _createPortElement ( port ) ;
906910 } ,
907911
908912 findPortNodes : function ( portId , selector ) {
909- const portCache = this . _portElementsCache [ portId ] ;
913+ const portCache = this . _portElementsCache . get ( portId ) ;
910914 if ( ! portCache ) return [ ] ;
911915 if ( ! selector ) return [ portCache . portContentElement . node ] ;
912916 const portRoot = portCache . portElement . node ;
@@ -935,7 +939,7 @@ export const elementViewPortPrototype = {
935939 * @private
936940 */
937941 _removePorts : function ( ) {
938- util . invoke ( this . _portElementsCache , ' portElement.remove' ) ;
942+ this . _portElementsCache . forEach ( portCache => portCache . portElement . remove ( ) ) ;
939943 } ,
940944
941945 /**
@@ -1047,14 +1051,14 @@ export const elementViewPortPrototype = {
10471051 portContainerElement . append ( labelElement . addClass ( 'joint-port-label' ) ) ;
10481052 }
10491053
1050- this . _portElementsCache [ port . id ] = {
1054+ this . _portElementsCache . set ( port . id , {
10511055 portElement : portContainerElement ,
10521056 portLabelElement : labelElement ,
10531057 portSelectors : portContainerSelectors ,
10541058 portLabelSelectors : labelSelectors ,
10551059 portContentElement : portElement ,
10561060 portContentSelectors : portSelectors
1057- } ;
1061+ } ) ;
10581062
10591063 return portContainerElement ;
10601064 } ,
@@ -1066,12 +1070,9 @@ export const elementViewPortPrototype = {
10661070 _updatePortGroup : function ( groupName ) {
10671071
10681072 const portsMetrics = this . model . getGroupPortsMetrics ( groupName ) ;
1069- const portsIds = Object . keys ( portsMetrics ) ;
10701073
1071- for ( let i = 0 , n = portsIds . length ; i < n ; i ++ ) {
1072- const portId = portsIds [ i ] ;
1073- const metrics = portsMetrics [ portId ] ;
1074- const cached = this . _portElementsCache [ portId ] || { } ;
1074+ for ( const [ portId , metrics ] of portsMetrics ) {
1075+ const cached = this . _portElementsCache . get ( portId ) || { } ;
10751076 const portTransformation = metrics . portTransformation ;
10761077 const labelTransformation = metrics . labelTransformation ;
10771078 if ( labelTransformation && cached . portLabelElement ) {
0 commit comments