Ticket #243: mochikit_rpartial.patch

File mochikit_rpartial.patch, 9.0 kB (added by morten.barklund@tbwa-play.com, 2 years ago)

Patch for suggested solution

  • MochiKit/Base.js

    old new  
    598598        }; 
    599599    }, 
    600600 
    601     /** @id MochiKit.Base.bind */ 
    602     bind: function (func, self/* args... */) { 
     601    /** @id MochiKit.Base._bind */ 
     602    _bind: function (func, self, preargs, postargs) { 
    603603        if (typeof(func) == "string") { 
    604604            func = self[func]; 
    605605        } 
    606606        var im_func = func.im_func; 
    607607        var im_preargs = func.im_preargs; 
     608        var im_postargs = func.im_postargs; 
    608609        var im_self = func.im_self; 
    609610        var m = MochiKit.Base; 
    610611        if (typeof(func) == "function" && typeof(func.apply) == "undefined") { 
     
    624625        } else  { 
    625626            im_preargs = im_preargs.slice(); 
    626627        } 
    627         m.extend(im_preargs, arguments, 2); 
     628        im_preargs = m.concat(im_preargs, preargs); 
     629        if (typeof(im_postargs) == 'undefined') { 
     630            im_postargs = []; 
     631        } else  { 
     632            im_postargs = im_postargs.slice(); 
     633        } 
     634        im_postargs = m.concat(im_postargs, postargs); 
    628635        var newfunc = function () { 
    629636            var args = arguments; 
    630637            var me = arguments.callee; 
    631638            if (me.im_preargs.length > 0) { 
    632639                args = m.concat(me.im_preargs, args); 
    633640            } 
     641            if (me.im_postargs.length > 0) { 
     642                args = m.concat(args, me.im_postargs); 
     643            } 
    634644            var self = me.im_self; 
    635645            if (!self) { 
    636646                self = this; 
     
    640650        newfunc.im_self = im_self; 
    641651        newfunc.im_func = im_func; 
    642652        newfunc.im_preargs = im_preargs; 
     653        newfunc.im_postargs = im_postargs; 
    643654        return newfunc; 
    644655    }, 
    645  
     656         
     657        /** @id MochiKit.Base.bind */ 
     658    bind: function (func, self/* args... */) { 
     659        var m = MochiKit.Base; 
     660        return m._bind(func, self, m.extend(null,arguments,2), []); 
     661        }, 
     662         
     663        /** @id MochiKit.Base.rbind */ 
     664    rbind: function (func, self/* args... */) { 
     665        var m = MochiKit.Base; 
     666        return m._bind(func, self, [], m.extend(null,arguments,2)); 
     667        }, 
     668     
    646669    /** @id MochiKit.Base.bindMethods */ 
    647670    bindMethods: function (self) { 
    648671        var bind = MochiKit.Base.bind; 
     
    941964        return m.bind.apply(this, m.extend([func, undefined], arguments, 1)); 
    942965    }, 
    943966 
     967    /** @id MochiKit.Base.rpartial */ 
     968    rpartial: function (func) { 
     969        var m = MochiKit.Base; 
     970        return m.rbind.apply(this, m.extend([func, undefined], arguments, 1)); 
     971    }, 
     972 
    944973    /** @id MochiKit.Base.listMinMax */ 
    945974    listMinMax: function (which, lst) { 
    946975        if (lst.length === 0) { 
     
    12431272    "methodcaller", 
    12441273    "compose", 
    12451274    "bind", 
     1275    "rbind", 
    12461276    "bindMethods", 
    12471277    "NotFound", 
    12481278    "AdapterRegistry", 
     
    12561286    "keyComparator", 
    12571287    "reverseKeyComparator", 
    12581288    "partial", 
     1289    "rpartial", 
    12591290    "merge", 
    12601291    "listMinMax", 
    12611292    "listMax", 
  • MochiKit/DOM.js

    old new  
    397397    /** @id MochiKit.DOM.getNodeAttribute */ 
    398398    getNodeAttribute: function (node, attr) { 
    399399        var self = MochiKit.DOM; 
     400                var base = MochiKit.Base; 
     401                if (base.isArrayLike(node)) 
     402                        return base.map(base.rpartial(self.getNodeAttribute, attr), node); 
     403        if (base.isArrayLike(attr)) 
     404                        return base.map(base.partial(self.getNodeAttribute, node), attr); 
     405                node = self.getElement(node); 
    400406        var rename = self.attributeArray.renames[attr]; 
    401         node = self.getElement(node); 
    402407        try { 
    403408            if (rename) { 
    404409                return node[rename]; 
     
    413418    /** @id MochiKit.DOM.removeNodeAttribute */ 
    414419    removeNodeAttribute: function (node, attr) { 
    415420        var self = MochiKit.DOM; 
     421                var base = MochiKit.Base; 
     422                if (base.isArrayLike(node)) 
     423                        return base.map(base.rpartial(self.removeNodeAttribute, attr), node); 
     424        if (base.isArrayLike(attr)) 
     425                        return base.map(base.partial(self.removeNodeAttribute, node), attr); 
    416426        var rename = self.attributeArray.renames[attr]; 
    417427        node = self.getElement(node); 
    418428        try { 
     
    430440    updateNodeAttributes: function (node, attrs) { 
    431441        var elem = node; 
    432442        var self = MochiKit.DOM; 
     443                var base = MochiKit.Base; 
     444                if (base.isArrayLike(node)) 
     445                        return base.map(base.rpartial(self.updateNodeAttributes, attrs), node); 
    433446        if (typeof(node) == 'string') { 
    434447            elem = self.getElement(node); 
    435448        } 
     
    662675    /** @id MochiKit.DOM.getElement */ 
    663676    getElement: function (id) { 
    664677        var self = MochiKit.DOM; 
     678                var base = MochiKit.Base; 
    665679        if (arguments.length == 1) { 
     680                        if (base.isArrayLike(id)) 
     681                                return base.map(self.getElement, id); 
    666682            return ((typeof(id) == "string") ? 
    667683                self._document.getElementById(id) : id); 
    668684        } else { 
    669             return MochiKit.Base.map(self.getElement, arguments); 
     685            return base.map(self.getElement, arguments); 
    670686        } 
    671687    }, 
    672688 
     
    764780    /** @id MochiKit.DOM.setElementClass */ 
    765781    setElementClass: function (element, className) { 
    766782        var self = MochiKit.DOM; 
     783                var base = MochiKit.Base; 
     784                if (base.isArrayLike(element)) 
     785                        return base.map(base.rpartial(self.setElementClass, className), element); 
     786        if (base.isArrayLike(className)) 
     787                        return base.map(base.partial(self.setElementClass, element), className); 
    767788        var obj = self.getElement(element); 
    768789        if (self.attributeArray.compliant) { 
    769790            obj.setAttribute("class", className); 
     
    786807    /** @id MochiKit.DOM.addElementClass */ 
    787808    addElementClass: function (element, className) { 
    788809        var self = MochiKit.DOM; 
     810                var base = MochiKit.Base; 
     811                if (base.isArrayLike(element)) 
     812                        return base.map(base.rpartial(self.addElementClass, className), element); 
     813        if (base.isArrayLike(className)) 
     814                        return base.map(base.partial(self.addElementClass, element), className); 
    789815        var obj = self.getElement(element); 
    790816        var cls = obj.className; 
    791817        // trivial case, no className yet 
  • tests/test_Base.js

    old new  
    113113    t.is( compare([2, 1], [1, 1]), 1, "arrays compare gt (contents)" ); 
    114114     
    115115    // test partial application 
    116     var a = []; 
    117116    var func = function (a, b) { 
    118117        if (arguments.length != 2) { 
    119118            return "bad args"; 
     
    123122    }; 
    124123    var self = {"value": 1, "func": func}; 
    125124    var self2 = {"value": 2}; 
    126     t.is( self.func(2, 3), 6, "setup for test is correct" ); 
     125    t.is( self.func(2, 3), 6, "setup for partial test is correct" ); 
    127126    self.funcTwo = partial(self.func, 2); 
    128127    t.is( self.funcTwo(3), 6, "partial application works" ); 
    129128    t.is( self.funcTwo(3), 6, "partial application works still" ); 
     
    131130    self.funcTwo = bind(bind(self.funcTwo, self2), null); 
    132131    t.is( self.funcTwo(3), 6, "re-unbinding partial application works" ); 
    133132 
    134      
     133         
     134    // test rpartial application 
     135    var func = function (a, b) { 
     136        if (arguments.length != 2) { 
     137            return "bad args"; 
     138        } else { 
     139            return this.value + a + b; 
     140        } 
     141    }; 
     142    var self = {"value": 1, "func": func}; 
     143    var self2 = {"value": 2}; 
     144    t.is( self.func(2, 3), 6, "setup for rpartial test is correct" ); 
     145    self.funcRThree = rpartial(self.func, 3); 
     146    t.is( self.funcRThree(2), 6, "rpartial application works" ); 
     147    t.is( self.funcRThree(2), 6, "rpartial application works still" ); 
     148    t.is( bind(self.funcRThree, self2)(2), 7, "rebinding rpartial works" ); 
     149    self.funcBetween = bind(bind(self.funcRThree, self2), null); 
     150    t.is( self.funcRThree(2), 6, "re-unbinding rpartial application works" ); 
     151         
     152         
     153        // test partial and rpartial together 
     154    var func = function (a, b, c) { 
     155        if (arguments.length != 3) { 
     156            return "bad args"; 
     157        } else { 
     158            return this.value + a + b + c; 
     159        } 
     160    }; 
     161    var self = {"value": 1, "func": func}; 
     162    var self2 = {"value": 2}; 
     163    t.is( self.func(2, 3, 4), 10, "setup for partial-rpartial test is correct" ); 
     164    self.funcBetween = rpartial(partial(self.func, 2), 4); 
     165    t.is( self.funcBetween(3), 10, "partial-rpartial application works" ); 
     166    t.is( self.funcBetween(3), 10, "partial-rpartial application works still" ); 
     167    self.funcBetween = partial(rpartial(self.func, 4), 2); 
     168    t.is( self.funcBetween(3), 10, "rpartial-partial application works" ); 
     169    t.is( self.funcBetween(3), 10, "rpartial-partial application works still" ); 
     170    t.is( bind(self.funcBetween, self2)(3), 11, "rebinding partial-rpartial works" ); 
     171    self.funcBetween = bind(bind(self.funcBetween, self2), null); 
     172    t.is( self.funcBetween(3), 10, "re-unbinding partial-rpartial application works" ); 
     173    
    135174    // nodeWalk test 
    136175    // ... looks a lot like a DOM tree on purpose 
    137176    var tree = {