Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 7337

Show
Ignore:
Timestamp:
08/17/07 17:35:22 (1 year ago)
Author:
sam
Message:

prototype: Change Class.extend to allow for superclass method resolution and remove Class.inherit. Closes #9274.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • spinoffs/prototype/trunk/CHANGELOG

    r7336 r7337  
    11*SVN* 
     2 
     3* Change Class.extend to allow for superclass method resolution and remove Class.inherit.  Closes #9274.  [Samuel Lebeau] 
    24 
    35* Event handlers are now bound to the observed element, not the event's target element.  [Dan Webb] 
  • spinoffs/prototype/trunk/src/base.js

    r7304 r7337  
    11/* Based on Alex Arnell's inheritance implementation. */ 
    22var Class = { 
    3   create: function(parent, methods) { 
    4     if (arguments.length == 1 && !Object.isFunction(parent)) 
    5       methods = parent, parent = null; 
     3  create: (function() { 
     4    var extending = { }; 
     5     
     6    return function(parent, properties) { 
     7      if (arguments.length == 1 && !Object.isFunction(parent)) 
     8        properties = parent, parent = null; 
    69       
    7     var method = function() { 
    8       if (!Class.extending) this.initialize.apply(this, arguments); 
     10      function klass() { 
     11        if (arguments[0] !== extending)  
     12          this.initialize.apply(this, arguments); 
     13      } 
     14     
     15      klass.superclass = parent; 
     16      klass.subclasses = []; 
     17     
     18      if (Object.isFunction(parent)) { 
     19        klass.prototype = new parent(extending); 
     20        parent.subclasses.push(klass); 
     21      } 
     22 
     23      if (properties) Class.extend(klass, properties); 
     24      klass.prototype.constructor = klass; 
     25 
     26      return klass; 
    927    }; 
    10      
    11     method.superclass = parent; 
    12     method.subclasses = []; 
    13      
    14     if (Object.isFunction(parent)) { 
    15       Class.extending = true; 
    16       method.prototype = new parent(); 
    17  
    18       parent.subclasses.push(method); 
    19  
    20       delete Class.extending; 
    21     } 
    22  
    23     if (methods) Class.extend(method, methods); 
    24     method.prototype.constructor = method; 
    25  
    26     return method;     
    27   }, 
     28  })(), 
    2829   
    2930  extend: function(destination, source) { 
    30     for (var name in source) Class.inherit(destination, source, name); 
     31    var ancestor = destination.superclass && destination.superclass.prototype; 
     32 
     33    for (var property in source) { 
     34      var value = source[property]; 
     35      if (ancestor && Object.isFunction(value) && 
     36          value.argumentNames().first() == "$super") { 
     37        var method = value, value = Object.extend((function() {  
     38          return ancestor[property].apply(this, arguments)  
     39        }).wrap(method), { 
     40          valueOf:  function() { return method }, 
     41          toString: function() { return method.toString() }   
     42        }); 
     43      } 
     44      destination.prototype[property] = value; 
     45    } 
     46     
    3147    return destination; 
    3248  }, 
    33      
    34   inherit: function(destination, source, name) { 
    35     var prototype = destination.prototype, ancestor = prototype[name],  
    36      descendant = source[name]; 
    37     if (ancestor && Object.isFunction(descendant) && 
    38         descendant.argumentNames().first() == "$super") { 
    39       var method = descendant, descendant = ancestor.wrap(method); 
    40       Object.extend(descendant, { 
    41         valueOf:  function() { return method }, 
    42         toString: function() { return method.toString() } 
    43       }); 
    44     } 
    45  
    46     prototype[name] = descendant; 
    47  
    48     if (destination.subclasses && destination.subclasses.length > 0) { 
    49       for (var i = 0, subclass; subclass = destination.subclasses[i]; i++) { 
    50         Class.extending = true; 
    51         Object.extend(subclass.prototype, new destination()); 
    52         subclass.prototype.constructor = subclass; 
    53         delete Class.extending; 
    54         Class.inherit(subclass, destination.prototype, name); 
    55       } 
    56     } 
    57   }, 
    58    
     49 
    5950  mixin: function(destination, source) { 
    6051    return Object.extend(destination, source); 
     
    6556 
    6657Object.extend = function(destination, source) { 
    67   for (var property in source) { 
     58  for (var property in source) 
    6859    destination[property] = source[property]; 
    69   } 
    7060  return destination; 
    7161}; 
  • spinoffs/prototype/trunk/test/unit/base.html

    r7293 r7337  
    439439      assertEqual('Tom: ZZZ', tom.sleep(), "added instance method not available to subclass"); 
    440440      assertEqual("Jerry: ZZZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep()); 
     441       
     442      Class.extend(Animal, { 
     443        sleep: function() { 
     444          return this.say('zZzZ'); 
     445        } 
     446      }); 
     447       
     448      assertEqual("Jerry: zZzZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep()); 
    441449    }} 
    442450