@@ -503,7 +503,7 @@ D.filter_ports = function(ports, station, name) {
503503 }
504504}
505505
506- D . run = function ( daimio , ultimate_callback , space ) {
506+ D . run = function ( daimio , space , scope , ultimate_callback ) {
507507 // This is *always* async, so provide a callback.
508508 if ( ! daimio ) return ""
509509
@@ -533,7 +533,7 @@ D.run = function(daimio, ultimate_callback, space) {
533533 ultimate_callback ( result )
534534 }
535535
536- var result = space . execute ( D . Parser . string_to_block_segment ( daimio ) , null , prior_starter )
536+ var result = space . execute ( D . Parser . string_to_block_segment ( daimio ) , scope , prior_starter )
537537 if ( result === result )
538538 prior_starter ( result )
539539
@@ -629,62 +629,107 @@ D.get_decorators = function(by_block, by_type) {
629629// A port flavour has a dir [in, out, out/in, in/out (inback outback? up down?)], and dock and add functions
630630
631631
632- D . track_event = function ( type , target , callback ) {
633- if ( ! D . Etc . events )
634- D . Etc . events = { }
632+ D . track_event = function ( type , selector , parent , callback , options ) {
633+ // options contains:
634+ // 'scrub' -- a callback to be used instead of the standard value detector
635+ // 'nochain' -- a boolean flag that prevents walking the parent chain [YAGNI]
636+ // 'passthru' -- a boolean flag which causes events to keep their default behavior
637+
638+ /*
639+
640+ changes:
641+ - allow 'document' itself as a valid selector
642+ - allow a 'parent' element (and set the listener on the parent instead of on document)
643+ - a passthru param that pushes the event back in to the stream and marks it so it isn't caught again
644+ - a 'scrub' callback to be used instead of the standard value detector
645+
646+
647+ TODO:
648+ - test value selector and scrubber
649+ - test parent setting
650+ - test passthru
651+
652+ */
653+
654+ options = options || { }
655+ D . Etc . events = D . Etc . events || { }
635656
636657 if ( ! D . Etc . events [ type ] ) {
637658 D . Etc . events [ type ] = { by_class : { } , by_id : { } }
638-
639- document . addEventListener ( type , function ( event ) {
659+
660+ parent = parent ? document . getElementById ( parent ) : document
661+
662+ parent . addEventListener ( type , function ( event ) {
640663 var target = event . target
641- , listener
642- , parent
643- , cname
664+ var particulars
665+ var cname
666+
667+ if ( event . passthru ) return true
644668
645669 // walk the target.parentNode chain up to null, checking each item along the way until you find one
646670 // OPT: make walking the parent chain optional (use a port param to ask for it)
647- while ( ! listener && target ) {
648- listener = tracked . by_id [ target . id ]
649- if ( listener ) break
671+ while ( ! particulars && target ) {
672+ particulars = tracked . by_id [ target . id ]
673+ if ( particulars ) break
650674
651675 cname = target . className
652676 if ( cname ) {
653677 cname = cname . baseVal || cname
654678 cname . split ( / \s + / ) . forEach ( function ( name ) {
655- listener = listener || tracked . by_class [ name ] // TODO: take all matches instead of just first
679+ particulars = particulars || tracked . by_class [ name ] // TODO: take all matches instead of just first
656680 } )
657681 }
658682
659- if ( listener ) break
683+ if ( particulars ) break
660684 target = target . parentNode
661685 }
662686
663- if ( listener ) {
664- event . stopPropagation ( ) // THINK: not sure these are always desired...
665- event . preventDefault ( ) // maybe use a port param to allow passthru
687+ if ( particulars ) {
688+ if ( ! particulars . passthru ) {
689+ event . stopPropagation ( )
690+ event . preventDefault ( )
691+ event . passthru = true
692+ }
666693 var value =
667- ( target . attributes [ 'data-value' ]
668- && target . attributes [ 'data-value' ] . value ) // THINK: no empty strings allowed...
669- || ( target . value != undefined && target . value ) // TODO: catch ""
670- || ( target . attributes . value && target . attributes . value . value )
694+ particulars . scrub
695+ ? particulars . scrub ( event )
696+ : target . attributes [ 'data-value' ]
697+ ? target . attributes [ 'data-value' ] . value
698+ : target . value != undefined
699+ ? target . value
700+ : target . attributes . value
701+ && target . attributes . value . value
671702 || target . text
672703 || D . scrub_var ( event )
673704 || true
674- listener ( value , event )
705+ particulars . callback ( value , event )
675706 }
676707 } , false )
677708 }
678709
679710 var tracked = D . Etc . events [ type ]
711+ var particulars = { callback : callback , scrub : options . scrub , passthru : options . passthru }
680712
681- if ( target [ 0 ] == '.' ) {
682- tracked . by_class [ target . slice ( 1 ) ] = callback
713+ if ( selector [ 0 ] == '.' ) {
714+ tracked . by_class [ selector . slice ( 1 ) ] = particulars
683715 } else {
684- tracked . by_id [ target ] = callback
716+ tracked . by_id [ selector ] = particulars
685717 }
686718}
687719
720+ D . untrack_event = function ( type , target , parent , callback ) {
721+ if ( ! D . Etc . events ) return false
722+ if ( ! D . Etc . events [ type ] ) return false
723+
724+ var tracked = D . Etc . events [ type ]
725+ var obj = target [ 0 ] == '.' ? tracked . by_class : tracked . by_id
726+
727+ if ( ! obj || ! obj [ target ] ) return false
728+ if ( callback && obj [ target ] != callback ) return false
729+
730+ delete obj [ target ]
731+ }
732+
688733D . send_value_to_js_port = function ( space , port_name , value , port_flavour ) {
689734 port_flavour = port_flavour || 'from-js'
690735
@@ -754,17 +799,20 @@ D.port_standard_sync = function(ship, callback) {
754799}
755800
756801
757- D . import_port_flavour = function ( flavour , pflav ) {
758- if ( D . PortFlavours [ flavour ] )
802+ D . import_port_flavour = function ( flavourname , pflav ) {
803+ if ( D . PortFlavours [ flavourname ] )
759804 return D . set_error ( 'That port flavour has already been im-port-ed' )
760805
761806 // TODO: just use Port or something as a proto for pflav, then the fall-through is automatic
762807
763808 if ( ! pflav )
764809 return D . set_error ( 'That flavour is not desirable' )
765810
811+ if ( ! pflav . settings ) // settings are params for port construction
812+ pflav . settings = [ ] // THINK: error if no settings?
813+
766814 if ( typeof pflav . add != 'function' )
767- pflav . add = D . noop // noop, so we can call w/o checking
815+ pflav . add = D . noop // noop, so we can call w/o checking
768816
769817 if ( typeof pflav . exit != 'function' )
770818 pflav . exit = D . port_standard_exit
@@ -787,7 +835,7 @@ D.import_port_flavour = function(flavour, pflav) {
787835 // if([pflav.enter, pflav.add].every(function(v) {return typeof v == 'function'}))
788836 // return D.set_error("That port flavour's properties are invalid")
789837
790- D . PortFlavours [ flavour ] = pflav
838+ D . PortFlavours [ flavourname ] = pflav
791839 return true
792840}
793841
0 commit comments