123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731 |
- "use strict";
- define( [ "module", "vwf/model", "vwf/kernel/utility", "vwf/utility", "vwf/configuration" ],
- function( module, model, kutility, utility, configuration ) {
- var exports = model.load( module, {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- initialize: function() {
- this.nodes = {};
- this.protoNode = undefined;
- this.creatingNode( undefined, 0 );
- },
-
-
- creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
- childSource, childType, childIndex, childName, callback /* ( ready ) */ ) {
- var self = this;
-
- var prototype = this.nodes[childExtendsID] || Object.prototype;
-
- var behaviors = ( childImplementsIDs || [] ).map( function( childImplementsID ) {
- return self.nodes[childImplementsID];
- } );
-
-
- behaviors.forEach( function( behavior ) {
- prototype = proxiedBehavior.call( self, prototype, behavior );
- } );
-
-
- var node = this.nodes[childID] = Object.create( prototype );
- if ( childID === kutility.protoNodeURI ) {
- this.protoNode = node;
- }
- Object.defineProperty( node, "private", {
- value: {}
- } );
- Object.defineProperty( node, "id", {
- value: childID,
- enumerable: true,
- } );
- Object.defineProperty( node, "uri", {
- get: function() {
- return self.kernel.uri( this.id );
- },
- enumerable: true,
- } );
- node.name = childName;
- node.parent = undefined;
- Object.defineProperty( node, "parent_", {
- get: function() {
- return this.parent;
- },
- set: function( value ) {
- var childIndex;
- if ( this.parent ) {
- var oldParent = this.parent;
- self.kernel.removeChild( this.parent.id, this.id );
- childIndex = oldParent.children.indexOf( this );
- if ( childIndex != -1 )
- oldParent.children.splice( childIndex, 1 );
- }
- self.kernel.addChild( value.id, this.id, this.name );
- this.parent = value;
- childIndex = this.parent.children.indexOf( this );
- if ( childIndex == -1 )
- this.parent.children.push( this );
- },
- } );
- node.source = childSource;
- node.type = childType;
- Object.defineProperty( node, "logger", {
- value: this.logger.for( "#" + ( childName || childIndex || childID ), node ),
- enumerable: true,
- } );
-
- node.properties = Object.create( prototype.properties || Object.prototype, {
- node: { value: node }
- } );
- Object.defineProperty( node.properties, "create", {
- value: function( name, value, get, set ) {
- return self.kernel.createProperty( this.node.id, name, value, get, set );
- }
- } );
- // Attach the property meta events to `node.properties.{created,initialized,deleted}`.
- createEventAccessor.call( this, node.properties, "created", "properties" );
- createEventAccessor.call( this, node.properties, "initialized", "properties" );
- createEventAccessor.call( this, node.properties, "deleted", "properties" );
- node.private.getters = Object.create( prototype.private ?
- prototype.private.getters : Object.prototype
- );
- node.private.setters = Object.create( prototype.private ?
- prototype.private.setters : Object.prototype
- );
- // Methods.
- node.methods = Object.create( prototype.methods || Object.prototype, {
- node: { value: node } // for node.methods accessors (non-enumerable) // TODO: hide this better
- } );
- Object.defineProperty( node.methods, "create", {
- value: function( name, parameters, body ) { // "this" is node.methods // TODO: also accept create( name, body )
- return self.kernel.createMethod( this.node.id, name, parameters, body );
- }
- } );
- // Attach the method meta events to `node.methods.{created,deleted}`.
- createEventAccessor.call( this, node.methods, "created", "methods" );
- createEventAccessor.call( this, node.methods, "deleted", "methods" );
- node.private.bodies = Object.create( prototype.private ?
- prototype.private.bodies : Object.prototype
- );
- // Events.
- node.events = Object.create( prototype.events || Object.prototype, {
- node: { value: node }, // for node.events accessors (non-enumerable) // TODO: hide this better
- } );
- // TODO: these only need to be on the base node's events object
- Object.defineProperty( node.events, "create", {
- value: function( name, parameters ) { // "this" is node.events
- return self.kernel.createEvent( this.node.id, name, parameters );
- }
- } );
- // Attach the event meta events to `node.events.{created,deleted}`.
- createEventAccessor.call( this, node.events, "created", "events" );
- createEventAccessor.call( this, node.events, "deleted", "events" );
- // Provide helper functions to create the directives for adding, removing and flushing
- // event handlers.
- // Add: `node.events.*eventName* =
-
- Object.defineProperty( node.events, "add", {
- value: function( handler, phases, context, callback /* listenerID */ ) {
-
-
- if ( typeof context === "function" || context instanceof Function ) {
- callback = context;
- context = undefined;
- } else if ( typeof phases === "function" || phases instanceof Function ) {
- callback = phases;
- context = phases = undefined;
- }
-
- if ( valueIsNode.call( self, phases ) ) {
- context = phases;
- phases = undefined;
- }
- return { add: true, handler: handler, phases: phases, context: context, callback: callback };
- }
- } );
-
- Object.defineProperty( node.events, "remove", {
- value: function( listenerID ) {
-
-
-
-
- if ( typeof listenerID === "function" || listenerID instanceof Function ) {
- return { remove: true, handler: listenerID };
- } else {
- return { remove: true, id: listenerID };
- }
- }
- } );
-
- Object.defineProperty( node.events, "flush", {
- value: function( context ) {
- return { flush: true, context: context };
- }
- } );
- node.private.listeners = {};
-
- node.children = [];
- Object.defineProperty( node.children, "node", {
- value: node
- } );
- Object.defineProperty( node.children, "create", {
- value: function( name, component, callback /* ( child ) */ ) {
-
-
- if ( typeof component === "function" || component instanceof Function ) {
- callback = component;
- component = undefined;
- }
-
-
- component = component || {};
-
-
- if ( callback ) {
- self.kernel.createChild( this.node.id, name, componentKernelFromJS.call( self, component ), undefined, undefined, function( childID ) {
- callback.call( node, self.nodes[childID] );
- } );
- } else {
- return self.kernel.createChild( this.node.id, name, componentKernelFromJS.call( self, component ) );
- }
- }
- } );
- Object.defineProperty( node.children, "delete", {
- value: function( child ) {
- if ( typeof child === "string" ) {
- child = this.node.children[ child ];
- }
- return self.kernel.deleteNode( child.id );
- }
- } );
-
- createEventAccessor.call( this, node.children, "added", "children" );
- createEventAccessor.call( this, node.children, "removed", "children" );
-
- Object.defineProperty( node, "random", {
- value: function() {
- return self.kernel.random( this.id );
- }
- } );
- Object.defineProperty( node, "seed", {
- value: function( seed ) {
- return self.kernel.seed( this.id, seed );
- }
- } );
-
- Object.defineProperty( node, "time", {
- get: function() {
- return self.kernel.time();
- },
- enumerable: true,
- } );
- Object.defineProperty( node, "client", {
- get: function() {
- return self.kernel.client();
- },
- enumerable: true,
- } );
- Object.defineProperty( node, "moniker", {
- get: function() {
- return self.kernel.moniker();
- },
- enumerable: true,
- } );
- Object.defineProperty( node, "find", {
- value: function( matchPattern, callback /* ( match ) */ ) {
- if ( callback ) {
- self.kernel.find( this.id, matchPattern, true, function( matchID ) {
- callback.call( node, self.nodes[matchID] );
- } );
- } else {
- var findResults = self.kernel.find( this.id, matchPattern, true );
- if ( findResults )
- return findResults.map( function( matchID ) {
- return self.nodes[matchID];
- } );
- }
- }
- } );
- Object.defineProperty( node, "test", {
- value: function( matchPattern, testNode ) {
- return self.kernel.test( this.id, matchPattern, testNode.id, true );
- }
- } );
-
-
-
- Object.defineProperty( node, "in", {
- value: function( when, callback ) {
- return refreshedFuture.call( self, this, -when, callback );
- },
- enumerable: true,
- } );
- Object.defineProperty( node, "at", {
- value: function( when, callback ) {
- return refreshedFuture.call( self, this, when, callback );
- },
- enumerable: true,
- } );
- Object.defineProperty( node, "future", {
- get: function() {
- return this.in;
- },
- enumerable: true,
- } );
- node.private.future = Object.create( prototype.private ?
- prototype.private.future : Object.prototype
- );
- Object.defineProperty( node.private.future, "private", {
- value: {
- when: 0,
- callback: undefined,
- change: 0,
- }
- } );
- node.private.change = 1;
- },
-
-
- initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
- childSource, childType, childIndex, childName ) {
- var node = this.nodes[nodeID];
- var child = this.nodes[childID];
- var scriptText =
- "this.hasOwnProperty( 'initialize' ) && " +
- "( typeof this.initialize === 'function' || this.initialize instanceof Function ) && " +
- "this.initialize()";
-
- try {
- ( function( scriptText ) { return eval( scriptText ) } ).call( child, scriptText );
- } catch ( e ) {
- this.logger.warnx( "initializingNode", childID,
- "exception in initialize:", utility.exceptionMessage( e ) );
- }
-
-
-
-
-
-
-
-
-
-
- child.parent = node;
- if ( node ) {
- node.children[childIndex] = child;
- if ( parseInt( childName ).toString() !== childName ) {
- node.children[childName] = child;
- }
- node.hasOwnProperty( childName ) ||
- ( node[childName] = child );
- }
- return undefined;
- },
-
-
- initializingNodeFromPrototype: function( nodeID, childID, childInitializingNodeID ) {
- var child = this.nodes[childID];
- var initializer = this.nodes[childInitializingNodeID];
-
- try {
- var prototypeHasInitialize = ( initializer.hasOwnProperty( 'initialize' ) &&
- ( typeof initializer.initialize === 'function' ||
- initializer.initialize instanceof Function ) );
- if ( prototypeHasInitialize ) {
- return initializer.initialize.call( child );
- }
- } catch ( e ) {
- this.logger.warnx( "initializingNodeFromPrototype", childID,
- "exception in initialize:", utility.exceptionMessage( e ) );
- }
- return undefined;
- },
-
- deletingNode: function( nodeID ) {
- var child = this.nodes[nodeID];
- var node = child.parent;
- if ( node ) {
- var index = node.children.indexOf( child );
- if ( index >= 0 ) {
- node.children.splice( index, 1 );
- }
- delete node.children[child.name];
- if ( node[child.name] === child ) {
- delete node[child.name];
- }
- child.parent = undefined;
- }
- delete this.nodes[nodeID];
- },
-
- addingChild: function( nodeID, childID, childName ) {
- },
-
- removingChild: function( nodeID, childID ) {
- var node = this.nodes[nodeID];
- var child = this.nodes[childID];
- child.parent = undefined;
- if ( node ) {
- node.children.splice( node.children.indexOf( child ), 1 );
- delete node.children[child.name];
- delete node[child.name];
- }
- },
-
- creatingProperty: function( nodeID, propertyName, propertyValue, propertyGet, propertySet ) {
- var node = this.nodes[nodeID];
- var self = this;
- var getter = propertyGet &&
- functionFromHandler( { body: propertyGet, type: scriptMediaType },
- logGetterException );
- if ( getter ) {
- node.private.getters[ propertyName ] = getter;
- } else {
- node.private.getters[ propertyName ] = true;
- }
-
- var setter = propertySet &&
- functionFromHandler( { parameters: [ "value" ], body: propertySet, type: scriptMediaType },
- logSetterException );
- if ( setter ) {
- node.private.setters[ propertyName ] = setter;
- } else {
- node.private.setters[ propertyName ] = true;
- }
- function logGetterException( exception ) {
- self.logger.warnx( "creatingProperty", nodeID, propertyName, propertyValue,
- "exception evaluating getter:", utility.exceptionMessage( exception ) );
- }
- function logSetterException( exception ) {
- self.logger.warnx( "creatingProperty", nodeID, propertyName, propertyValue,
- "exception evaluating setter:", utility.exceptionMessage( exception ) );
- }
- return this.initializingProperty( nodeID, propertyName, propertyValue );
- },
-
- initializingProperty: function( nodeID, propertyName, propertyValue ) {
- var node = this.nodes[nodeID];
- createPropertyAccessor.call( this, node.properties, propertyName );
- node.hasOwnProperty( propertyName ) ||
- createPropertyAccessor.call( this, node, propertyName );
-
- node.private.change++;
- return propertyValue !== undefined ?
- this.settingProperty( nodeID, propertyName, propertyValue ) : undefined;
- },
-
-
- settingProperty: function( nodeID, propertyName, propertyValue ) {
- var node = this.nodes[nodeID];
- if ( ! node ) return;
- var setter = node.private.setters && node.private.setters[propertyName];
- if ( setter && setter !== true ) {
- try {
- var valueJS = valueJSFromKernel.call( this, propertyValue );
- var resultJS = setter.call( node, valueJS );
- return valueKernelFromJS.call( this, resultJS );
- } catch ( e ) {
- this.logger.warnx( "settingProperty", nodeID, propertyName, propertyValue,
- "exception in setter:", utility.exceptionMessage( e ) );
- }
- }
- return undefined;
- },
-
- gettingProperty: function( nodeID, propertyName, propertyValue ) {
- var node = this.nodes[nodeID];
- var getter = node.private.getters && node.private.getters[propertyName];
- if ( getter && getter !== true ) {
- try {
- var resultJS = getter.call( node );
- return valueKernelFromJS.call( this, resultJS );
- } catch ( e ) {
- this.logger.warnx( "gettingProperty", nodeID, propertyName, propertyValue,
- "exception in getter:", utility.exceptionMessage( e ) );
- }
- }
- return undefined;
- },
-
- creatingMethod: function( nodeID, methodName, methodParameters, methodBody ) {
- var node = this.nodes[nodeID];
- createMethodAccessor.call( this, node.methods, methodName );
- node.hasOwnProperty( methodName ) ||
- createMethodAccessor.call( this, node, methodName );
-
- node.private.change++;
-
- return this.settingMethod( nodeID, methodName, {
- parameters: methodParameters,
- body: methodBody,
- type: typeof methodBody === "string" || methodBody instanceof String ?
- scriptMediaType : undefined,
- } );
- },
-
-
- settingMethod: function( nodeID, methodName, methodHandler ) {
- var node = this.nodes[nodeID];
- var self = this;
- var body = functionFromHandler( methodHandler, logException,
- configuration.active[ "preserve-script-closures" ] );
- if ( body ) {
- node.private.bodies[ methodName ] = body;
- return handlerFromFunction( body );
- } else {
- delete node.private.bodies[ methodName ];
- }
- function logException( exception ) {
- self.logger.warnx( "settingMethod", nodeID, methodName, methodHandler.parameters,
- "exception evaluating body:", utility.exceptionMessage( exception ) );
- }
- return undefined;
- },
-
- gettingMethod: function( nodeID, methodName ) {
- var node = this.nodes[nodeID];
- var body = node.private.bodies && node.private.bodies[methodName];
- if ( body ) {
- return handlerFromFunction( body );
- }
- return undefined;
- },
-
- callingMethod: function( nodeID, methodName, methodParameters ) {
- var node = this.nodes[nodeID];
- var body = node.private.bodies && node.private.bodies[methodName];
- if ( body ) {
- try {
- var parametersJS = parametersJSFromKernel.call( this, methodParameters );
- var resultJS = body.apply( node, parametersJS );
- return valueKernelFromJS.call( this, resultJS );
- } catch ( e ) {
- this.logger.warnx( "callingMethod", nodeID, methodName, methodParameters,
- "exception:", utility.exceptionMessage( e ) );
- }
- }
- return undefined;
- },
-
- creatingEvent: function( nodeID, eventName, eventParameters ) {
- var node = this.nodes[nodeID];
- createEventAccessor.call( this, node.events, eventName );
- node.hasOwnProperty( eventName ) ||
- createEventAccessor.call( this, node, eventName );
-
- node.private.change++;
- },
-
- addingEventListener: function( nodeID, eventName, eventListenerID, eventHandler, eventContextID, eventPhases ) {
- var node = this.nodes[nodeID];
-
-
- if ( ! node.private.listeners[eventName] ) {
- node.private.listeners[eventName] = [];
- }
-
- var eventListener = utility.merge( eventHandler, {
- context: eventContextID,
- phases: eventPhases,
- } );
-
- return this.settingEventListener( nodeID, eventName, eventListenerID, eventListener ) ?
- true : undefined;
- },
-
- removingEventListener: function( nodeID, eventName, eventListenerID ) {
- var node = this.nodes[nodeID];
- var listeners = node.private.listeners[eventName];
- if ( listeners && listeners[ eventListenerID ] ) {
- delete listeners[ eventListenerID ];
- return true;
- }
- return undefined;
- },
-
- settingEventListener: function( nodeID, eventName, eventListenerID, eventListener ) {
- var node = this.nodes[nodeID];
- var self = this;
- var listeners = node.private.listeners[eventName];
- var handler = functionFromHandler( eventListener, logException,
- configuration.active[ "preserve-script-closures" ] );
- if ( handler ) {
- listeners[ eventListenerID ] = {
- handler: handler,
- context: eventListener.context,
- phases: eventListener.phases,
- };
-
-
-
-
-
-
-
-
-
-
-
- return eventListener;
- } else {
- delete listeners[ eventListenerID ];
- }
- function logException( exception ) {
- self.logger.warnx( "settingEventListener", nodeID, eventName, eventListenerID,
- "exception evaluating listener:", utility.exceptionMessage( exception ) );
- }
- return undefined;
- },
-
- gettingEventListener: function( nodeID, eventName, eventListenerID ) {
- var node = this.nodes[nodeID];
- var listeners = node.private.listeners[eventName];
- if ( listeners ) {
- var listener = listeners[ eventListenerID ];
- return utility.merge( handlerFromFunction( listener.handler ), {
- context: listener.context,
- phases: listener.phases,
- } );
- }
- return undefined;
- },
-
- flushingEventListeners: function( nodeID, eventName, eventContextID ) {
-
- var removedListenerIDs = [];
-
- var node = this.nodes[ nodeID ];
- var listeners = node.private.listeners[ eventName ];
-
-
- if ( listeners ) {
- listeners.forEach( function( listener, listenerID ) {
- if ( listener.context === eventContextID ) {
- delete listeners[ listenerID ];
- removedListenerIDs.push( listenerID );
- }
- } );
- }
- return removedListenerIDs;
- },
-
- firingEvent: function( nodeID, eventName, eventParameters ) {
- var phase = eventParameters && eventParameters.phase;
- var node = this.nodes[nodeID];
- var listeners = findListeners( node, eventName );
- var parametersJS = parametersJSFromKernel.call( this, eventParameters );
- var self = this;
-
-
-
-
- var handled = listeners && listeners.reduce( function( handled, listener ) {
-
-
- try {
- if ( ! phase || listener.phases && listener.phases.indexOf( phase ) >= 0 ) {
- var contextNode = self.nodes[ listener.context ] || self.nodes[ 0 ];
- var resultJS = listener.handler.apply( contextNode, parametersJS );
- var result = valueKernelFromJS.call( self, resultJS );
- return handled || result || result === undefined;
- }
- } catch ( e ) {
- self.logger.warnx( "firingEvent", nodeID, eventName, eventParameters,
- "exception:", utility.exceptionMessage( e ) );
- }
- return handled;
- }, false );
- return handled;
- },
-
- executing: function( nodeID, scriptText, scriptType ) {
- var node = this.nodes[nodeID];
- if ( scriptType == scriptMediaType ) {
- try {
- var resultJS = ( function( scriptText ) { return eval( scriptText ) } ).call( node, scriptText || "" );
- return valueKernelFromJS.call( this, resultJS );
- } catch ( e ) {
- this.logger.warnx( "executing", nodeID,
- ( scriptText || "" ).replace( /\s+/g, " " ).substring( 0, 100 ), scriptType, "exception:", utility.exceptionMessage( e ) );
- }
- }
- return undefined;
- },
- } );
-
-
- function proxiedBehavior( prototype, behavior ) {
- var self = this;
- var proxy = Object.create( prototype );
- Object.defineProperty( proxy, "private", {
- value: {}
- } );
- proxy.private.origin = behavior;
- Object.defineProperty( proxy, "id", {
- value: behavior.id,
- enumerable: true,
- } );
- proxy.name = behavior.name;
- proxy.parent = behavior.parent;
- proxy.source = behavior.source;
- proxy.type = behavior.type;
- proxy.initialize = behavior.initialize;
- proxy.properties = Object.create( prototype.properties || Object.prototype, {
- node: { value: proxy }
- } );
- proxy.private.getters = Object.create( prototype.private ?
- prototype.private.getters : Object.prototype
- );
- proxy.private.setters = Object.create( prototype.private ?
- prototype.private.setters : Object.prototype
- );
- for ( var propertyName in behavior.properties ) {
- if ( behavior.properties.hasOwnProperty( propertyName ) ) {
- ( function( propertyName ) {
- createPropertyAccessor.call( self, proxy.properties, propertyName );
- proxy.hasOwnProperty( propertyName ) ||
- createPropertyAccessor.call( self, proxy, propertyName );
- } )( propertyName );
-
- if ( behavior.private.getters.hasOwnProperty( propertyName ) ) {
- proxy.private.getters[propertyName] = behavior.private.getters[propertyName];
- }
- if ( behavior.private.setters.hasOwnProperty( propertyName ) ) {
- proxy.private.setters[propertyName] = behavior.private.setters[propertyName];
- }
- }
- }
- proxy.methods = Object.create( prototype.methods || Object.prototype, {
- node: { value: proxy }
- } );
- proxy.private.bodies = Object.create( prototype.private ?
- prototype.private.bodies : Object.prototype
- );
- for ( var methodName in behavior.methods ) {
- if ( behavior.methods.hasOwnProperty( methodName ) ) {
- ( function( methodName ) {
- createMethodAccessor.call( self, proxy.methods, methodName );
- proxy.hasOwnProperty( methodName ) ||
- createMethodAccessor.call( self, proxy, methodName );
- } )( methodName );
-
- if ( behavior.private.bodies.hasOwnProperty( methodName ) ) {
- proxy.private.bodies[methodName] = behavior.private.bodies[methodName];
- }
- }
- }
- proxy.events = Object.create( prototype.events || Object.prototype, {
- node: { value: proxy }
- } );
- proxy.private.listeners = {};
- for ( var eventName in behavior.events ) {
- if ( behavior.events.hasOwnProperty( eventName ) ) {
- ( function( eventName ) {
- createEventAccessor.call( self, proxy.events, eventName );
- proxy.hasOwnProperty( eventName ) ||
- createEventAccessor.call( self, proxy, eventName );
- } )( eventName );
- }
- }
- for ( var eventName in behavior.private.listeners ) {
- if ( behavior.private.listeners.hasOwnProperty( eventName ) ) {
- proxy.private.listeners[eventName] = behavior.private.listeners[eventName];
- }
- }
- proxy.private.future = Object.create( prototype.private ?
- prototype.private.future : Object.prototype
- );
- Object.defineProperty( proxy.private.future, "private", {
- value: {
- when: 0,
- callback: undefined,
- change: 0,
- }
- } );
- proxy.private.change = behavior.private.change;
- return proxy;
- }
-
- function refreshedFuture( node, when, callback ) {
- var self = this;
- if ( Object.getPrototypeOf( node ).private ) {
- refreshedFuture.call( this, Object.getPrototypeOf( node ) );
- }
- var future = node.private.future;
- future.private.when = when;
- future.private.callback = callback;
- if ( future.private.change < node.private.change ) {
- Object.defineProperty( future, "id", {
- value: node.id,
- enumerable: true,
- } );
- future.properties = Object.create( Object.getPrototypeOf( future ).properties || Object.prototype, {
- node: { value: future }
- } );
- for ( var propertyName in node.properties ) {
- if ( node.properties.hasOwnProperty( propertyName ) ) {
- ( function( propertyName ) {
- createPropertyAccessor.call( self, future.properties, propertyName );
- future.hasOwnProperty( propertyName ) ||
- createPropertyAccessor.call( self, future, propertyName );
- } )( propertyName );
-
- }
-
- }
- future.methods = Object.create( Object.getPrototypeOf( future ).methods || Object.prototype, {
- node: { value: future }
- } );
- for ( var methodName in node.methods ) {
- if ( node.methods.hasOwnProperty( methodName ) ) {
- ( function( methodName ) {
- createMethodAccessor.call( self, future.methods, methodName, true );
- future.hasOwnProperty( methodName ) ||
- createMethodAccessor.call( self, future, methodName, true );
- } )( methodName );
- }
- }
- future.events = Object.create( Object.getPrototypeOf( future ).events || Object.prototype, {
- node: { value: future }
- } );
- for ( var eventName in node.events ) {
- if ( node.events.hasOwnProperty( eventName ) ) {
- ( function( eventName ) {
- createEventAccessor.call( self, future.events, eventName, undefined, true );
- future.hasOwnProperty( eventName ) ||
- createEventAccessor.call( self, future, eventName, undefined, true );
- } )( eventName );
- }
- }
- future.private.change = node.private.change;
- }
- return future;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- function createPropertyAccessor( container, propertyName ) {
- var self = this;
- Object.defineProperty( container, propertyName, {
-
- get: function() {
- var node = this.node || this;
- var resultKernel = self.kernel.getProperty( node.id, propertyName,
- node.private.when, node.private.callback );
- return valueJSFromKernel.call( self, resultKernel );
- },
-
- set: function( value ) {
- var node = this.node || this;
- var valueKernel = valueKernelFromJS.call( self, value );
- self.kernel.setProperty( node.id, propertyName, valueKernel,
- node.private.when, node.private.callback );
- },
- enumerable: true,
- } );
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- function createMethodAccessor( container, methodName, unsettable ) {
- var self = this;
- Object.defineProperty( container, methodName, {
-
- get: function() {
- var node = this.node || this;
- return function( /* parameter1, parameter2, ... */ ) {
- var argumentsKernel = parametersKernelFromJS.call( self, arguments );
- var resultKernel = self.kernel.callMethod( node.id, methodName, argumentsKernel,
- node.private.when, node.private.callback );
- return valueJSFromKernel.call( self, resultKernel );
- };
- },
-
- set: unsettable ? undefined : function( value ) {
- var node = this.node || this;
- self.kernel.setMethod( node.id, methodName,
- handlerFromFunction( value, configuration.active[ "preserve-script-closures" ] ) );
- },
- enumerable: true,
- } );
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- function createEventAccessor( container, eventName, eventNamespace, unsettable ) {
- var self = this;
- Object.defineProperty( container, eventName, {
-
-
-
- get: eventNamespace ? undefined : function() {
- var node = this.node || this;
- return function( /* parameter1, parameter2, ... */ ) {
- var argumentsKernel = parametersKernelFromJS.call( self, arguments );
- var resultKernel = self.kernel.fireEvent( node.id, eventName, argumentsKernel,
- node.private.when, node.private.callback );
- return valueJSFromKernel.call( self, resultKernel );
- };
- },
-
- set: unsettable ? undefined : function( value ) {
- var node = this.node || this;
- var namespacedName = eventNamespace ? [ eventNamespace, eventName ] : eventName;
- if ( typeof value === "function" || value instanceof Function ) {
-
- addListener( value, node );
- } else if ( value.add ) {
-
- if ( ! value.phases || value.phases instanceof Array ) {
- addListener( value.handler, value.context, value.phases, value.callback );
- } else {
- addListener( value.handler, value.context, [ value.phases ], value.callback );
- }
- } else if ( value.remove ) {
-
-
-
-
- self.kernel.removeEventListener( node.id, namespacedName,
- value.handler ? value.handler.listenerID : value.id );
- } else if ( value.flush ) {
-
- self.kernel.flushEventListeners( node.id, namespacedName,
- value.context && value.context.id );
- }
- function addListener( handler, context, phases, callback ) {
- var listenerID = self.kernel.addEventListener( node.id, namespacedName,
- handlerFromFunction( handler, configuration.active[ "preserve-script-closures" ] ),
- context && context.id, phases );
-
-
-
- handler.listenerID = listenerID;
- callback && callback.call( node, listenerID );
- }
- },
-
-
-
- enumerable: ! eventNamespace,
- } );
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- function functionFromHandler( handler, errback /* exception */, bypass ) {
- if ( bypass && ( typeof handler.body === "function" || handler.body instanceof Function ) ) {
- return handler.body;
- } else if ( handler.type === scriptMediaType ) {
- var name = handler.name, parameters = handler.parameters, body = handler.body;
- var parameterString = parameters && parameters.length ?
- " " + parameters.join( ", " ) + " " :
- "";
- var prefix = "function(" + parameterString + ") {";
- var suffix = "}";
- var functionString, indentedBody;
- if ( body && body.length ) {
- if ( body.charAt( body.length-1 ) === "\n" ) {
- indentedBody = body.match( /^[^\S\n]/ ) ? body : body.replace( /^./gm, " $&" );
- functionString = prefix + "\n" + indentedBody + suffix + "\n";
- } else {
- functionString = prefix + " " + body + " " + suffix;
- }
- } else {
- functionString = prefix + suffix;
- }
- try {
- return eval( "( " + functionString + ")" );
- } catch( exception ) {
- errback && errback( exception );
- }
- }
- return undefined;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- function handlerFromFunction( funcshun, bypass ) {
- var name, parameters, body, type = scriptMediaType;
- var match, leadingMatch, trailingMatch, indention = "";
- if ( bypass ) {
- return {
- body: funcshun,
- };
- } else if ( match = functionRegex.exec( funcshun.toString() ) ) {
- name = match[1];
-
-
-
- var parameterString = match[2].replace( /\/\*.*\*\//, "" ).trim();
- parameters = parameterString.length ? parameterString.split( "," ).map( function( parameter ) {
- return parameter.trim();
- } ) : undefined;
-
-
- body = match[3];
- leadingMatch =
- body.match( /^([^\S\n]*\n)([^\S\n]*)/ );
- trailingMatch =
- body.match( /\n([^\S\n]*)$/ );
-
-
-
- if ( leadingMatch ) {
- body = body.substr( leadingMatch[1].length );
- indention = leadingMatch[2];
- } else {
- body = body.replace( /^\s*/, "" );
- }
-
-
-
-
- if ( trailingMatch ) {
- body = body.substr( -trailingMatch[1] );
- indention = trailingMatch[1];
- } else {
- body = body.replace( /\s*$/, "" );
- }
-
-
- if ( leadingMatch || trailingMatch ) {
- body = body.replace( new RegExp( "^" + indention, "gm" ), "" );
- body = body.replace( /\n?$/, "\n" );
- }
- return {
- name: name,
- parameters: parameters,
- body: body,
- type: type,
- };
- }
- return undefined;
- }
-
-
-
- var scriptMediaType = "application/javascript";
-
-
-
- var functionRegex = new RegExp(
- "function" +
- "\\s*" +
- "([a-zA-Z_$][0-9a-zA-Z_$]*)?" +
- "\\s*" +
- "\\(([^)]*)\\)" +
- "\\s*" +
- "\\{([^]*)\\}"
- );
-
- function findListeners( node, eventName, targetOnly ) {
- var prototypeListeners = Object.getPrototypeOf( node ).private ?
- findListeners( Object.getPrototypeOf( node ), eventName, true ) : [];
- var nodeListeners = node.private.listeners && node.private.listeners[eventName] || [];
- if ( targetOnly ) {
- return prototypeListeners.concat( nodeListeners.filter( function( listener ) {
- return listener.context === node.id ||
- ( node.private.origin && listener.context === node.private.origin.id );
- } ) );
- } else {
- return prototypeListeners.map( function( listener ) {
- return { handler: listener.handler, context: node.id, phases: listener.phases };
- } ).concat( nodeListeners );
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- function componentKernelFromJS( component ) {
- return valueKernelFromJS.call( this, component );
- }
-
-
-
-
-
-
-
-
- function parametersKernelFromJS( parameters ) {
- return valueKernelFromJS.call( this, parameters );
- }
-
-
-
-
-
-
-
-
- function parametersJSFromKernel( parameters ) {
- return valueJSFromKernel.call( this, parameters );
- }
-
-
-
-
-
-
-
-
-
-
-
-
- function valueKernelFromJS( value ) {
- var self = this;
- return utility.transform( value, function( object, names, depth, finished ) {
- if ( valueIsNode.call( self, object ) ) {
- finished();
- return kutility.nodeReference( object.id );
- } else if ( object && object.buffer && object.buffer.toString() === "[object ArrayBuffer]" ) {
- finished();
- return object;
- } else if ( kutility.valueIsNodeReference( object ) ) {
- finished();
- self.logger.warnx( "valueKernelFromJS", "javascript-format value contains a kernel-format node reference" );
- return object;
- } else {
- return object;
- }
- } );
- }
-
-
-
-
-
-
-
-
-
- function valueJSFromKernel( value ) {
- var self = this;
- return utility.transform( value, function( object, names, depth, finished ) {
- if ( kutility.valueIsNodeReference( object ) ) {
- finished();
- return self.nodes[ object.id ];
- } else if ( object && object.buffer && object.buffer.toString() === "[object ArrayBuffer]" ) {
- finished();
- return object;
- } else if ( valueIsNode.call( self, object ) ) {
- finished();
- self.logger.warnx( "valueJSFromKernel", "kernel-format value contains a javascript-format node reference" );
- return object;
- } else {
- return object;
- }
- } );
- }
-
-
-
-
-
-
-
-
- function valueIsNode( value ) {
- return this.protoNode &&
- ( this.protoNode.isPrototypeOf( value ) || value === this.protoNode );
- }
- return exports;
- } );
|