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

Changeset 7296

Show
Ignore:
Timestamp:
08/09/07 09:27:11 (2 years ago)
Author:
madrobby
Message:

script.aculo.us: Effect.ScrollTo is now no longer a core effect (returns a Effect.Tween instance now), some effect code refactoring to take advantage of new Prototype 1.6 features

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • spinoffs/scriptaculous/CHANGELOG

    r7292 r7296  
    11*SVN* 
     2 
     3* Some effect code refactoring to take advantage of new Prototype 1.6 features. 
     4 
     5* Effect.ScrollTo is now no longer a core effect (returns a Effect.Tween instance now). 
    26 
    37* Add Effect.Tween, a new core effect. This effect tweens between two values and sets a property or calls a method on an object (including DOM elements); or allows for a callback method, which will be automatically bound to the object. 
  • spinoffs/scriptaculous/lib/prototype.js

    r7287 r7296  
    3939var Class = { 
    4040  create: function(parent, methods) { 
    41     if (arguments.length == 1 && typeof parent !== 'function'
     41    if (arguments.length == 1 && !Object.isFunction(parent)
    4242      methods = parent, parent = null; 
    4343 
     
    175175  isFunction: function(object) { 
    176176    return typeof object == "function"; 
     177  }, 
     178 
     179  isString: function(object) { 
     180    return typeof object == "string"; 
     181  }, 
     182 
     183  isNumber: function(object) { 
     184    return typeof object == "number"; 
     185  }, 
     186 
     187  isUndefined: function(object) { 
     188    return typeof object == "undefined"; 
    177189  } 
    178190}); 
     
    180192Object.extend(Function.prototype, { 
    181193  argumentNames: function() { 
    182     var names = this.toString().match(/^function\s*\((.*?)\)/)[1].split(",").invoke("strip"); 
     194    var names = this.toString().match(/^[\s\(]*function\s*\((.*?)\)/)[1].split(",").invoke("strip"); 
    183195    return names.length == 1 && !names[0] ? [] : names; 
    184196  }, 
     
    250262        returnValue = lambda(); 
    251263        break; 
    252       } catch (e) {
     264      } catch (e) {
    253265    } 
    254266 
     
    388400  toQueryParams: function(separator) { 
    389401    var match = this.strip().match(/([^?#]*)(#.*)?$/); 
    390     if (!match) return {}; 
    391  
    392     return match[1].split(separator || '&').inject({}, function(hash, pair) { 
     402    if (!match) return { }; 
     403 
     404    return match[1].split(separator || '&').inject({ }, function(hash, pair) { 
    393405      if ((pair = pair.split('='))[0]) { 
    394406        var key = decodeURIComponent(pair.shift()); 
     
    513525 
    514526String.prototype.gsub.prepareReplacement = function(replacement) { 
    515   if (typeof replacement == 'function') return replacement; 
     527  if (Object.isFunction(replacement)) return replacement; 
    516528  var template = new Template(replacement); 
    517529  return function(match) { return template.evaluate(match) }; 
     
    536548 
    537549  evaluate: function(object) { 
    538     if (typeof object.toTemplateReplacements == 'function'
     550    if (Object.isFunction(object.toTemplateReplacements)
    539551      object = object.toTemplateReplacements(); 
    540552 
     
    562574}; 
    563575 
    564 var $break = {}; 
     576var $break = { }; 
    565577 
    566578var Enumerable = { 
     
    641653    var results = []; 
    642654 
    643     if (typeof filter == "string"
     655    if (Object.isString(filter)
    644656      filter = new RegExp(filter); 
    645657 
     
    652664 
    653665  include: function(object) { 
    654     if (typeof this.indexOf == 'function'
     666    if (Object.isFunction(this.indexOf)
    655667      return this.indexOf(object) != -1; 
    656668 
     
    754766  zip: function() { 
    755767    var iterator = Prototype.K, args = $A(arguments); 
    756     if (typeof args.last() == 'function'
     768    if (Object.isFunction(args.last())
    757769      iterator = args.pop(); 
    758770 
     
    796808  function $A(iterable) { 
    797809    if (!iterable) return []; 
    798     if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && 
    799       iterable.toArray) { 
     810    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && 
     811        iterable.toArray) { 
    800812      return iterable.toArray(); 
    801813    } else { 
     
    898910 
    899911// use native browser JS 1.6 implementation if available 
    900 if (typeof Array.prototype.forEach == 'function'
     912if (Object.isFunction(Array.prototype.forEach)
    901913  Array.prototype._each = Array.prototype.forEach; 
    902914 
     
    967979var Hash = function(object) { 
    968980  if (object instanceof Hash) this.merge(object); 
    969   else Object.extend(this, object || {}); 
     981  else Object.extend(this, object || { }); 
    970982}; 
    971983 
     
    11571169  dispatch: function(callback, request, transport, json) { 
    11581170    this.each(function(responder) { 
    1159       if (typeof responder[callback] == 'function') { 
     1171      if (Object.isFunction(responder[callback])) { 
    11601172        try { 
    11611173          responder[callback].apply(responder, [request, transport, json]); 
    1162         } catch (e) {
     1174        } catch (e) {
    11631175      } 
    11641176    }); 
     
    11771189}); 
    11781190 
    1179 Ajax.Base = function() {}; 
     1191Ajax.Base = function() { }; 
    11801192Ajax.Base.prototype = { 
    11811193  setOptions: function(options) { 
     
    11891201      evalJS:       true 
    11901202    }; 
    1191     Object.extend(this.options, options || {}); 
     1203    Object.extend(this.options, options || { }); 
    11921204 
    11931205    this.options.method = this.options.method.toLowerCase(); 
    1194     if (typeof this.options.parameters == 'string'
     1206    if (Object.isString(this.options.parameters)
    11951207      this.options.parameters = this.options.parameters.toQueryParams(); 
    11961208  } 
     
    12871299      var extras = this.options.requestHeaders; 
    12881300 
    1289       if (typeof extras.push == 'function'
     1301      if (Object.isFunction(extras.push)
    12901302        for (var i = 0, length = extras.length; i < length; i += 2) 
    12911303          headers[extras[i]] = extras[i+1]; 
     
    14611473    if (receiver = $(receiver)) { 
    14621474      if (options.insertion) { 
    1463         if (typeof options.insertion == 'string') { 
    1464           var insertion = {}; insertion[options.insertion] = responseText; 
     1475        if (Object.isString(options.insertion)) { 
     1476          var insertion = { }; insertion[options.insertion] = responseText; 
    14651477          receiver.insert(insertion); 
    14661478        } 
     
    14851497    this.decay = (this.options.decay || 1); 
    14861498 
    1487     this.updater = {}; 
     1499    this.updater = { }; 
    14881500    this.container = container; 
    14891501    this.url = url; 
     
    15231535    return elements; 
    15241536  } 
    1525   if (typeof element == 'string'
     1537  if (Object.isString(element)
    15261538    element = document.getElementById(element); 
    15271539  return Element.extend(element); 
     
    16321644    element = $(element); 
    16331645 
    1634     if (typeof insertions == 'string' || typeof insertions == 'number' || 
     1646    if (Object.isString(insertions) || Object.isNumber(insertions) || 
    16351647        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) 
    16361648          insertions = {bottom:insertions}; 
     
    16651677    if (Object.isElement(wrapper)) 
    16661678      $(wrapper).writeAttribute(attributes || { }); 
    1667     else if (typeof wrapper == 'string') wrapper = new Element(wrapper, attributes); 
     1679    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); 
    16681680    else wrapper = new Element('div', wrapper); 
    16691681    if (element.parentNode) 
     
    17281740 
    17291741  match: function(element, selector) { 
    1730     if (typeof selector == 'string'
     1742    if (Object.isString(selector)
    17311743      selector = new Selector(selector); 
    17321744    return selector.match($(element)); 
     
    19021914    element = $(element); 
    19031915    var elementStyle = element.style, match; 
    1904     if (typeof styles === 'string') { 
     1916    if (Object.isString(styles)) { 
    19051917      element.style.cssText += ';' + styles; 
    19061918      return styles.include('opacity') ? 
     
    21992211    element = $(element); 
    22002212 
    2201     if (typeof insertions == 'string' || typeof insertions == 'number' || 
     2213    if (Object.isString(insertions) || Object.isNumber(insertions) || 
    22022214        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) 
    2203           insertions = {bottom:insertions}; 
     2215          insertions = { bottom: insertions }; 
    22042216 
    22052217    var t = Element._insertionTranslations, content, position, pos, tagName; 
     
    25752587    for (property in methods) { 
    25762588      value = methods[property]; 
    2577       if (typeof value == 'function' && !(property in element)) 
     2589      if (Object.isFunction(value) && !(property in element)) 
    25782590        element[property] = value.methodize(); 
    25792591    } 
     
    26372649    for (var property in methods) { 
    26382650      var value = methods[property]; 
    2639       if (typeof value != 'function') continue; 
     2651      if (!Object.isFunction(value)) continue; 
    26402652      if (!onlyIfAbsent || !(property in destination)) 
    26412653        destination[property] = value.methodize(); 
     
    26762688    for (var tag in Element.Methods.ByTag) { 
    26772689      var klass = findDOMClass(tag); 
    2678       if (typeof klass == "undefined") continue; 
     2690      if (Object.isUndefined(klass)) continue; 
    26792691      copy(T[tag], klass.prototype); 
    26802692    } 
     
    26862698  if (Element.extend.refresh) Element.extend.refresh(); 
    26872699  Element.cache = { }; 
     2700}; 
     2701 
     2702document.viewport = { 
     2703  getDimensions: function() { 
     2704    var dimensions = { }; 
     2705    $w('width height').each(function(d) { 
     2706      var D = d.capitalize(); 
     2707      dimensions[d] = self['inner' + D] || 
     2708       (document.documentElement['client' + D] || document.body['client' + D]); 
     2709    }); 
     2710    return dimensions; 
     2711  }, 
     2712 
     2713  getWidth: function() { 
     2714    return this.getDimensions().width; 
     2715  }, 
     2716 
     2717  getHeight: function() { 
     2718    return this.getDimensions().height; 
     2719  }, 
     2720 
     2721  getScrollOffsets: function() { 
     2722    return Element._returnOffset( 
     2723      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, 
     2724      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 
     2725  } 
    26882726}; 
    26892727/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, 
     
    27082746 
    27092747    if (Selector._cache[e]) { 
    2710       this.matcher = Selector._cache[e]; return; 
    2711     } 
     2748      this.matcher = Selector._cache[e]; 
     2749      return; 
     2750    } 
     2751 
    27122752    this.matcher = ["this.matcher = function(root) {", 
    27132753                    "var r = root, h = Selector.handlers, c = false, n;"]; 
     
    27182758        p = ps[i]; 
    27192759        if (m = e.match(p)) { 
    2720           this.matcher.push(typeof c[i] == 'function' ? c[i](m) : 
     2760          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : 
    27212761              new Template(c[i]).evaluate(m)); 
    27222762          e = e.replace(m[0], ''); 
     
    27442784      for (var i in ps) { 
    27452785        if (m = e.match(ps[i])) { 
    2746           this.matcher.push(typeof x[i] == 'function' ? x[i](m) : 
     2786          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : 
    27472787            new Template(x[i]).evaluate(m)); 
    27482788          e = e.replace(m[0], ''); 
     
    28082848 
    28092849Object.extend(Selector, { 
    2810   _cache: {}, 
     2850  _cache: { }, 
    28112851 
    28122852  xpath: { 
     
    28302870      var h = Selector.xpath.pseudos[m[1]]; 
    28312871      if (!h) return ''; 
    2832       if (typeof h === 'function') return h(m); 
     2872      if (Object.isFunction(h)) return h(m); 
    28332873      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); 
    28342874    }, 
     
    28592899          for (var i in p) { 
    28602900            if (m = e.match(p[i])) { 
    2861               v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); 
     2901              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); 
    28622902              exclusion.push("(" + v.substring(1, v.length - 1) + ")"); 
    28632903              e = e.replace(m[0], ''); 
     
    32933333 
    32943334  findElement: function(elements, expression, index) { 
    3295     if (typeof expression == 'number') { 
     3335    if (Object.isNumber(expression)) { 
    32963336      index = expression; expression = false; 
    32973337    } 
     
    33273367    var key, value, submitted = false, submit = options.submit; 
    33283368 
    3329     var data = elements.inject({}, function(result, element) { 
     3369    var data = elements.inject({ }, function(result, element) { 
    33303370      if (!element.disabled && element.name) { 
    33313371        key = element.name; value = $(element).getValue(); 
     
    34103450 
    34113451  request: function(form, options) { 
    3412     form = $(form), options = Object.clone(options || {}); 
     3452    form = $(form), options = Object.clone(options || { }); 
    34133453 
    34143454    var params = options.parameters, action = form.readAttribute('action') || ''; 
     
    34173457 
    34183458    if (params) { 
    3419       if (typeof params == 'string') params = params.toQueryParams(); 
     3459      if (Object.isString(params)) params = params.toQueryParams(); 
    34203460      Object.extend(options.parameters, params); 
    34213461    } 
     
    34483488      var value = element.getValue(); 
    34493489      if (value != undefined) { 
    3450         var pair = {}; 
     3490        var pair = { }; 
    34513491        pair[element.name] = value; 
    34523492        return Hash.toQueryString(pair); 
     
    34853525          !['button', 'reset', 'submit'].include(element.type))) 
    34863526        element.select(); 
    3487     } catch (e) {
     3527    } catch (e) {
    34883528    return element; 
    34893529  }, 
     
    35753615/*--------------------------------------------------------------------------*/ 
    35763616 
    3577 Abstract.TimedObserver = function() {}; 
     3617Abstract.TimedObserver = function() { }; 
    35783618Abstract.TimedObserver.prototype = { 
    35793619  initialize: function(element, frequency, callback) { 
     
    35923632  onTimerEvent: function() { 
    35933633    var value = this.getValue(); 
    3594     var changed = ('string' == typeof this.lastValue && 'string' == typeof value 
     3634    var changed = (Object.isString(this.lastValue) && Object.isString(value) 
    35953635      ? this.lastValue != value : String(this.lastValue) != String(value)); 
    35963636    if (changed) { 
     
    36173657/*--------------------------------------------------------------------------*/ 
    36183658 
    3619 Abstract.EventObserver = function() {}; 
     3659Abstract.EventObserver = function() { }; 
    36203660Abstract.EventObserver.prototype = { 
    36213661  initialize: function(element, callback) { 
     
    38923932 
    38933933      event.eventName = eventName; 
    3894       event.memo = memo || {}; 
     3934      event.memo = memo || { }; 
    38953935 
    38963936      if (document.createEvent) { 
     
    40754115 
    40764116  clone: function(source, target, options) { 
    4077     options = options || {}; 
     4117    options = options || { }; 
    40784118    return Element.clonePosition(target, source, options); 
    40794119  } 
  • spinoffs/scriptaculous/src/effects.js

    r7292 r7296  
    6363/*--------------------------------------------------------------------------*/ 
    6464 
    65 Array.prototype.call = function() { 
    66   var args = arguments; 
    67   this.each(function(f){ f.apply(this, args) }); 
    68 } 
    69  
    70 /*--------------------------------------------------------------------------*/ 
    71  
    7265var Effect = { 
    7366  _elementDoesNotExistError: { 
     
    170163/* ------------- core effects ------------- */ 
    171164 
    172 Effect.ScopedQueue = Class.create(); 
    173 Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { 
     165Effect.ScopedQueue = Class.create(Class.mixin({ 
    174166  initialize: function() { 
    175167    this.effects  = []; 
     
    223215      this.effects[i] && this.effects[i].loop(timePos); 
    224216  } 
    225 }); 
     217}, Enumerable)); 
    226218 
    227219Effect.Queues = { 
     
    323315} 
    324316 
    325 Effect.Parallel = Class.create(); 
    326 Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { 
     317Effect.Parallel = Class.create(Effect.Base, { 
    327318  initialize: function(effects) { 
    328319    this.effects = effects || []; 
     
    345336Effect.Tween = Class.create(Effect.Base, { 
    346337  initialize: function(object, from, to) { 
    347     object = typeof object == 'string' ? $(object) : object; 
     338    object = Object.isString(object) ? $(object) : object; 
    348339    var args = $A(arguments), method = args.last(),  
    349340      options = args.length == 5 ? args[3] : null; 
    350     this.method = typeof method == 'function' ? method.bind(object) : 
    351       typeof object[method] == 'function' ? object[method].bind(object) :  
     341    this.method = Object.isFunction(method) ? method.bind(object) : 
     342      Object.isFunction(object[method]) ? object[method].bind(object) :  
    352343      function(value) { object[method] = value }; 
    353344    this.start(Object.extend({ from: from, to: to }, options || {})); 
     
    358349}); 
    359350 
    360 Effect.Event = Class.create(); 
    361 Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), { 
     351Effect.Event = Class.create(Effect.Base, { 
    362352  initialize: function() { 
    363353    var options = Object.extend({ 
     
    369359}); 
    370360 
    371 Effect.Opacity = Class.create(); 
    372 Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { 
     361Effect.Opacity = Class.create(Effect.Base, { 
    373362  initialize: function(element) { 
    374363    this.element = $(element); 
     
    388377}); 
    389378 
    390 Effect.Move = Class.create(); 
    391 Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { 
     379Effect.Move = Class.create(Effect.Base, { 
    392380  initialize: function(element) { 
    393381    this.element = $(element); 
     
    401389  }, 
    402390  setup: function() { 
    403     // Bug in Opera: Opera returns the "real" position of a static element or 
    404     // relative element that does not have top/left explicitly set. 
    405     // ==> Always set top and left for position relative elements in your stylesheets  
    406     // (to 0 if you do not need them)  
    407391    this.element.makePositioned(); 
    408392    this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); 
    409393    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0'); 
    410394    if(this.options.mode == 'absolute') { 
    411       // absolute movement, so we need to calc deltaX and deltaY 
    412395      this.options.x = this.options.x - this.originalLeft; 
    413396      this.options.y = this.options.y - this.originalTop; 
     
    428411}; 
    429412 
    430 Effect.Scale = Class.create(); 
    431 Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { 
     413Effect.Scale = Class.create(Effect.Base, { 
    432414  initialize: function(element, percent) { 
    433415    this.element = $(element); 
     
    503485}); 
    504486 
    505 Effect.Highlight = Class.create(); 
    506 Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { 
     487Effect.Highlight = Class.create(Effect.Base, { 
    507488  initialize: function(element) { 
    508489    this.element = $(element); 
     
    539520}); 
    540521 
    541 Effect.ScrollTo = Class.create(); 
    542 Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { 
    543   initialize: function(element) { 
    544     this.element = $(element); 
     522Effect.ScrollTo = function(element) { 
     523  var options = arguments[1] || {}, 
     524    scrollOffsets = document.viewport.getScrollOffsets(), 
     525    elementOffsets = $(element).cumulativeOffset(), 
     526    max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();   
     527 
     528  if(options.offset) elementOffsets[1] += options.offset; 
     529 
     530  return new Effect.Tween(null, 
     531    scrollOffsets.top, 
     532    elementOffsets[1] > max ? max : elementOffsets[1], 
     533    options, 
     534    function(p){ scrollTo(scrollOffsets.left, p.round()) } 
     535  ); 
     536}; 
     537/*    this.element = $(element); 
    545538    this.start(arguments[1] || {}); 
    546539  }, 
     
    562555      this.scrollStart + (position*this.delta)); 
    563556  } 
    564 }); 
     557});*/ 
    565558 
    566559/* ------------- combination effects ------------- */ 
     
    943936}; 
    944937 
    945 Effect.Morph = Class.create(); 
    946 Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { 
     938Effect.Morph = Class.create(Effect.Base, { 
    947939  initialize: function(element) { 
    948940    this.element = $(element); 
     
    10271019          (Math.round(transform.originalValue[2]+ 
    10281020            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : 
    1029         transform.originalValue + 
    1030           ((transform.targetValue - transform.originalValue) * position).toFixed(3) + transform.unit; 
     1021        (transform.originalValue + 
     1022          (transform.targetValue - transform.originalValue) * position).toFixed(3) + transform.unit; 
    10311023    this.element.setStyle(style, true); 
    10321024  } 
    10331025}); 
    10341026 
    1035 Effect.Transform = Class.create(); 
    1036 Object.extend(Effect.Transform.prototype, { 
     1027Effect.Transform = Class.create({ 
    10371028  initialize: function(tracks){ 
    10381029    this.tracks  = []; 
  • spinoffs/scriptaculous/test/unit/effects_test.html

    r7292 r7296  
    443443      $('error_message').morph('font-size:17px').morph('opacity:0',{delay:3}); 
    444444      wait(4100,function(){ // 3000ms delay + 1000ms default duration 
    445         assertEqual(0, $('error_message').getOpacity()); 
     445        assertEqual(0, $('error_message').getStyle('opacity')); 
    446446      }); 
    447447    }},