1- /*! jquery.views.js v0.9.78 (Beta): http://jsviews.com/ */
1+ /*! jquery.views.js v0.9.79 (Beta): http://jsviews.com/ */
22/*
33 * Interactive data-driven views using JsRender templates.
44 * Subcomponent of JsViews
@@ -44,7 +44,7 @@ var setGlobals = $ === false; // Only set globals if script block in browser (no
4444jsr = jsr || setGlobals && global . jsrender ;
4545$ = $ || global . jQuery ;
4646
47- var versionNumber = "v0.9.78 " ,
47+ var versionNumber = "v0.9.79 " ,
4848 requiresStr = "JsViews requires " ;
4949
5050if ( ! $ || ! $ . fn ) {
@@ -1591,6 +1591,7 @@ function addDataBinding(linkMarkup, node, currentView, boundTagId, isLink, data,
15911591 tag = tag . linkCtx ? tag . linkCtx . tag : tag ;
15921592
15931593 linkCtx = tag . linkCtx || {
1594+ type : "inline" ,
15941595 data : currentView . data , // source
15951596 elem : tag . _elCnt ? tag . parentElem : node , // target
15961597 view : currentView ,
@@ -1643,6 +1644,7 @@ function addDataBinding(linkMarkup, node, currentView, boundTagId, isLink, data,
16431644 params = tokens [ 9 ] ;
16441645
16451646 linkCtx = {
1647+ type : isLink ? "top" : "link" ,
16461648 data : data , // source
16471649 elem : node , // target
16481650 view : currentView ,
@@ -1798,12 +1800,7 @@ function callAfterLink(tag, eventArgs) {
17981800 tagCtx = tag . tagCtx ,
17991801 view = tagCtx . view ,
18001802 props = tagCtx . props ,
1801- linkCtx = tag . linkCtx = tag . linkCtx || {
1802- tag : tag ,
1803- data : view . data ,
1804- view : view ,
1805- ctx : view . ctx
1806- } ;
1803+ linkCtx = tag . linkCtx ;
18071804
18081805 if ( tag . onAfterLink ) {
18091806 tag . onAfterLink ( tagCtx , linkCtx , eventArgs ) ;
@@ -2580,7 +2577,7 @@ $converters.merge = function(val) {
25802577$tags ( "on" , {
25812578 attr : NONE ,
25822579 init : function ( tagCtx ) {
2583- var props , elemProp , classProp , content ,
2580+ var content ,
25842581 tag = this ,
25852582 i = 0 ,
25862583 args = tagCtx . args , // [events,] [selector,] handler
@@ -2589,22 +2586,21 @@ $tags("on", {
25892586 for ( ; i < l && ! $isFunction ( args [ i ] ) ; i ++ ) ; // Handler is first arg of type function
25902587 tag . _hi = l > i && i + 1 ; // handler index
25912588 if ( tag . _ . inline ) {
2589+ if ( ! $sub . rTmpl . exec ( content = tagCtx . tmpl . markup ) ) {
2590+ // Inline {^{on}} tag with no content (or external template content) or with content containing
2591+ // no HTML or JsRender tags: We will wrap the (text) content, or the operation name in a <button> element
2592+ // (Otherwise we will attach the handler to the element content after data-linking)
2593+ tag . template = "<button>" + ( $ . trim ( content ) || tagCtx . params . args [ i ] || "noop" ) + "</button>" ;
2594+ }
25922595 tag . attr = HTML ;
2593- content = tagCtx . content ;
2594- content = content && content . markup ;
2595- props = tagCtx . props ;
2596- elemProp = props . elem || "button" ;
2597- classProp = props [ "class" ] ;
2598- tag . template = rFirstElem . exec ( content ) && content || "<" + elemProp + ( classProp ? ' class="' + classProp + '">' : ">" )
2599- + ( $ . trim ( content ) || props . label || tagCtx . params . args [ i ] || "noop" ) + "</" + elemProp + ">" ;
26002596 }
26012597 } ,
26022598 render : function ( ) {
26032599 var tagCtx = this . tagCtx ;
26042600 return tagCtx . render ( tagCtx . view , true ) ; // no arg, so renders against parentView.data
26052601 } ,
26062602 onAfterLink : function ( tagCtx , linkCtx ) {
2607- var handler , params ,
2603+ var handler , params , find , activeElem ,
26082604 tag = this ,
26092605 i = tag . _hi ,
26102606 args = tagCtx . args , // [events,] [selector,] handler
@@ -2618,10 +2614,13 @@ $tags("on", {
26182614 handler = args [ i - 1 ] ;
26192615 params = args . slice ( i ) ; // Subsequent args are params
26202616 args = args . slice ( 0 , i - 1 ) ; // Preceding args (if any) are events and selector
2621- tag . _sel = args [ 1 ] ;
2622- tag . activeElem = tag . activeElem || ( tag . _ . inline
2623- ? ( tag . _elCnt && error ( 'Use data-link="{on...}"' ) , tag . _sel = undefined , tag . contents ( true , args [ 1 ] || "*" ) )
2624- : $ ( linkCtx . elem ) ) ;
2617+ tag . _sel = args [ 1 ] ; // Selector for descendant elements - for delegated events on those elements, delegating to the activeElem
2618+
2619+ activeElem = tag . activeElem = tag . activeElem || $ ( tag . _ . inline
2620+ ? ( tag . _sel = args [ 1 ] || "*" , tag . parentElem )
2621+ // If inline, attach to child elements of tag parent element (filtered by selector argument if provided.
2622+ // (In handler we'll filter out events from sibling elements preceding or following tag.)
2623+ : linkCtx . elem ) ;
26252624
26262625 if ( ! contextOb ) {
26272626 // Get the path for the preceding object (context object) of handler (which is the last arg), compile function
@@ -2634,19 +2633,33 @@ $tags("on", {
26342633 tag . onDispose ( ) ;
26352634 }
26362635
2637- tag . activeElem . on (
2636+ activeElem . on (
26382637 tag . _evs = args [ 0 ] || "click" , // events defaults to "click"
26392638 tag . _sel ,
26402639 data == undefined ? null : data ,
2641- tag . _hlr = function ( ev ) {
2642- return handler . apply ( contextOb || linkCtx . data , [ ] . concat (
2643- params , // e.g. par1, par2
2644- ev ,
2645- { change : ev . type , view : view , linkCtx : linkCtx } ,
2646- params . slice . call ( arguments , 1 ) // If triggering event (e.g. jsv-domchange) has additional arguments after ev, pass them too
2647- ) ) ;
2648- // for {on 'click' handler par1 par2} use handler(par1, par2, ev, domchangeEventArgs)
2649- // for {on 'jsv-domchange' handler par1 par2} use handler(par1, par2, ev, domchangeEventArgs, tagCtx, linkCtx, observableEventArgs)
2640+ tag . _hlr = function hndlr ( ev ) {
2641+ var nodes , length ,
2642+ found = ! tag . _ . inline ;
2643+
2644+ if ( ! found ) { // If inline, filter out events from sibling elements preceding or following tag.
2645+ nodes = tag . contents ( "*" ) ;
2646+ l = nodes . length ;
2647+ while ( ! found && l -- ) {
2648+ if ( nodes [ l ] . contains ( ev . target ) ) {
2649+ found = true ;
2650+ }
2651+ }
2652+ }
2653+ if ( found ) { // target elem is indeed within the tag, so call the {on} handler
2654+ return handler . apply ( contextOb || linkCtx . data , [ ] . concat (
2655+ params , // e.g. par1, par2
2656+ ev ,
2657+ { change : ev . type , view : view , linkCtx : linkCtx } ,
2658+ params . slice . call ( arguments , 1 ) // If triggering event (e.g. jsv-domchange) has additional arguments after ev, pass them too
2659+ ) ) ;
2660+ // for {on 'click' handler par1 par2} use handler(par1, par2, ev, domchangeEventArgs)
2661+ // for {on 'jsv-domchange' handler par1 par2} use handler(par1, par2, ev, domchangeEventArgs, tagCtx, linkCtx, observableEventArgs)
2662+ }
26502663 }
26512664 ) ;
26522665 }
@@ -2655,7 +2668,10 @@ $tags("on", {
26552668 return false ;
26562669 } ,
26572670 onDispose : function ( ) {
2658- this . activeElem . off ( this . _evs , this . _sel , this . _hlr ) ;
2671+ var self = this ;
2672+ if ( self . activeElem ) {
2673+ self . activeElem . off ( self . _evs , self . _sel , self . _hlr ) ;
2674+ }
26592675 } ,
26602676 flow : true ,
26612677 dataBoundOnly : true
0 commit comments