Skip to content

Commit 6e22a86

Browse files
committed
track event improvements and port param additions
1 parent 52e8034 commit 6e22a86

13 files changed

+231
-38
lines changed

daimio/1_daimio.js

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
688733
D.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

daimio/pflavs/dom-do-submit.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
D.import_port_flavour('dom-do-submit', {
22
dir: 'out',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'The form element id to submit',
7+
type: 'id'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_exit: function(ship) {
416
if(this.element)
517
this.element.submit()
18+
// TODO: fallthrough to dynamic instead of a fixed element
619
},
720
outside_add: function() {
821
this.element = document.getElementById(this.settings.thing)

daimio/pflavs/dom-on-blur.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
D.import_port_flavour('dom-on-blur', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
5-
D.track_event('blur', this.settings.thing, function(value) {self.enter(value)})
17+
D.track_event('blur', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
618
}
719
})

daimio/pflavs/dom-on-change.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
D.import_port_flavour('dom-on-change', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
5-
D.track_event('change', this.settings.thing, function(value) {self.enter(value)})
17+
D.track_event('change', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
618
}
719
})

daimio/pflavs/dom-on-click.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
D.import_port_flavour('dom-on-click', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
5-
D.track_event('click', this.settings.thing, function(value) {self.enter(value)})
17+
D.track_event('click', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
618
}
719
})

daimio/pflavs/dom-on-keypress.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
D.import_port_flavour('dom-on-keypress', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
// THINK: this requires binding to a particular DOM element -- is there a way to default to 'document'?
517
// TODO: fix this in FFX
618
var self = this
7-
D.track_event('keypress', this.settings.thing, function(value) {self.enter(value)})
19+
D.track_event('keypress', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
820
}
921
})

daimio/pflavs/dom-on-mouseout.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
D.import_port_flavour('dom-on-mouseout', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
5-
D.track_event('mouseout', this.settings.thing, function(value) {self.enter(value)})
17+
D.track_event('mouseout', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
618
}
719
})

daimio/pflavs/dom-on-mouseover.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
D.import_port_flavour('dom-on-mouseover', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
5-
D.track_event('mouseover', this.settings.thing, function(value) {self.enter(value)})
17+
D.track_event('mouseover', this.settings.thing, this.settings.parent, function(value) {self.enter(value)})
618
}
719
})

daimio/pflavs/dom-on-submit.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
D.import_port_flavour('dom-on-submit', {
22
dir: 'in',
3+
settings: [
4+
{
5+
key: 'thing',
6+
desc: 'A dom selector for binding',
7+
type: 'selector'
8+
},
9+
{
10+
key: 'parent',
11+
desc: 'A dom element contain thing. Defaults to document.',
12+
type: 'id'
13+
},
14+
],
315
outside_add: function() {
416
var self = this
517

@@ -26,6 +38,6 @@ D.import_port_flavour('dom-on-submit', {
2638
self.enter(ship)
2739
}
2840

29-
D.track_event('submit', this.settings.thing, callback)
41+
D.track_event('submit', this.settings.thing, this.settings.parent, callback)
3042
}
3143
})

daimio/pflavs/dom-set-html.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
D.import_port_flavour('dom-set-html', {
44
dir: 'out',
5+
settings: [
6+
{
7+
key: 'thing',
8+
desc: 'A dom selector for binding',
9+
type: 'selector'
10+
},
11+
{
12+
key: 'parent',
13+
desc: 'A dom element contain thing. Defaults to document.',
14+
type: 'id'
15+
},
16+
],
517
outside_exit: function(ship) {
618
// OPT: we could save some time by tying this directly to paint events: use requestAnimationFrame and feed it the current ship. that way we skip the layout cost between screen paints for fast moving events.
719
if(this.element)

0 commit comments

Comments
 (0)