basant307/AI_Governance_Project
048
1import * as util from'./util/index.mjs';2import define from './define/index.mjs';3import Collection from './collection/index.mjs';4import Core from './core/index.mjs';5import incExts from './extensions/index.mjs';6import * as is from './is.mjs';7import Emitter from './emitter.mjs';8 9// registered extensions to cytoscape, indexed by name10let extensions = {};11 12// registered modules for extensions, indexed by name13let modules = {};14 15function setExtension( type, name, registrant ){16 17 let ext = registrant;18 19 let overrideErr = function( field ){20 util.warn( 'Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden' );21 };22 23 if( type === 'core' ){24 if( Core.prototype[ name ] ){25 return overrideErr( name );26 } else {27 Core.prototype[ name ] = registrant;28 }29 30 } else if( type === 'collection' ){31 if( Collection.prototype[ name ] ){32 return overrideErr( name );33 } else {34 Collection.prototype[ name ] = registrant;35 }36 37 } else if( type === 'layout' ){38 // fill in missing layout functions in the prototype39 40 let Layout = function( options ){41 this.options = options;42 43 registrant.call( this, options );44 45 // make sure layout has _private for use w/ std apis like .on()46 if( !is.plainObject( this._private ) ){47 this._private = {};48 }49 50 this._private.cy = options.cy;51 this._private.listeners = [];52 53 this.createEmitter();54 };55 56 let layoutProto = Layout.prototype = Object.create( registrant.prototype );57 58 let optLayoutFns = [];59 60 for( let i = 0; i < optLayoutFns.length; i++ ){61 let fnName = optLayoutFns[ i ];62 63 layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };64 }65 66 // either .start() or .run() is defined, so autogen the other67 if( layoutProto.start && !layoutProto.run ){68 layoutProto.run = function(){ this.start(); return this; };69 } else if( !layoutProto.start && layoutProto.run ){70 layoutProto.start = function(){ this.run(); return this; };71 }72 73 let regStop = registrant.prototype.stop;74 layoutProto.stop = function(){75 let opts = this.options;76 77 if( opts && opts.animate ){78 let anis = this.animations;79 80 if( anis ){81 for( let i = 0; i < anis.length; i++ ){82 anis[ i ].stop();83 }84 }85 }86 87 if( regStop ){88 regStop.call( this );89 } else {90 this.emit( 'layoutstop' );91 }92 93 return this;94 };95 96 if( !layoutProto.destroy ){97 layoutProto.destroy = function(){98 return this;99 };100 }101 102 layoutProto.cy = function(){103 return this._private.cy;104 };105 106 let getCy = layout => layout._private.cy;107 108 let emitterOpts = {109 addEventFields: function( layout, evt ){110 evt.layout = layout;111 evt.cy = getCy(layout);112 evt.target = layout;113 },114 bubble: function(){ return true; },115 parent: function( layout ){ return getCy(layout); }116 };117 118 util.assign( layoutProto, {119 createEmitter: function(){120 this._private.emitter = new Emitter( emitterOpts, this );121 122 return this;123 },124 emitter: function(){ return this._private.emitter; },125 on: function( evt, cb ){ this.emitter().on( evt, cb ); return this; },126 one: function( evt, cb ){ this.emitter().one( evt, cb ); return this; },127 once: function( evt, cb ){ this.emitter().one( evt, cb ); return this; },128 removeListener: function( evt, cb ){ this.emitter().removeListener( evt, cb ); return this; },129 removeAllListeners: function(){ this.emitter().removeAllListeners(); return this; },130 emit: function( evt, params ){ this.emitter().emit( evt, params ); return this; }131 } );132 133 define.eventAliasesOn( layoutProto );134 135 ext = Layout; // replace with our wrapped layout136 137 } else if( type === 'renderer' && name !== 'null' && name !== 'base' ){138 // user registered renderers inherit from base139 140 let BaseRenderer = getExtension( 'renderer', 'base' );141 let bProto = BaseRenderer.prototype;142 let RegistrantRenderer = registrant;143 let rProto = registrant.prototype;144 145 let Renderer = function(){146 BaseRenderer.apply( this, arguments );147 RegistrantRenderer.apply( this, arguments );148 };149 150 let proto = Renderer.prototype;151 152 for( let pName in bProto ){153 let pVal = bProto[ pName ];154 let existsInR = rProto[ pName ] != null;155 156 if( existsInR ){157 return overrideErr( pName );158 }159 160 proto[ pName ] = pVal; // take impl from base161 }162 163 for( let pName in rProto ){164 proto[ pName ] = rProto[ pName ]; // take impl from registrant165 }166 167 bProto.clientFunctions.forEach( function( name ){168 proto[ name ] = proto[ name ] || function(){169 util.error( 'Renderer does not implement `renderer.' + name + '()` on its prototype' );170 };171 } );172 173 ext = Renderer;174 175 } else if (type === '__proto__' || type === 'constructor' || type === 'prototype'){176 // to avoid potential prototype pollution177 return util.error( type + ' is an illegal type to be registered, possibly lead to prototype pollutions' );178 }179 180 return util.setMap( {181 map: extensions,182 keys: [ type, name ],183 value: ext184 } );185}186 187function getExtension( type, name ){188 return util.getMap( {189 map: extensions,190 keys: [ type, name ]191 } );192}193 194function setModule( type, name, moduleType, moduleName, registrant ){195 return util.setMap( {196 map: modules,197 keys: [ type, name, moduleType, moduleName ],198 value: registrant199 } );200}201 202function getModule( type, name, moduleType, moduleName ){203 return util.getMap( {204 map: modules,205 keys: [ type, name, moduleType, moduleName ]206 } );207}208 209let extension = function(){210 // e.g. extension('renderer', 'svg')211 if( arguments.length === 2 ){212 return getExtension.apply( null, arguments );213 }214 215 // e.g. extension('renderer', 'svg', { ... })216 else if( arguments.length === 3 ){217 return setExtension.apply( null, arguments );218 }219 220 // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')221 else if( arguments.length === 4 ){222 return getModule.apply( null, arguments );223 }224 225 // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })226 else if( arguments.length === 5 ){227 return setModule.apply( null, arguments );228 }229 230 else {231 util.error( 'Invalid extension access syntax' );232 }233 234};235 236// allows a core instance to access extensions internally237Core.prototype.extension = extension;238 239// included extensions240incExts.forEach( function( group ){241 group.extensions.forEach( function( ext ){242 setExtension( group.type, ext.name, ext.impl );243 } );244} );245 246export default extension;247 