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

Ticket #7907: insertions-includes-ticket-7903.diff

File insertions-includes-ticket-7903.diff, 23.3 kB (added by Tobie, 2 years ago)

this patch includes #7903

  • test/unit/dom.html

    old new  
    261261<p id="test-full">content</p> 
    262262<div id="ancestor"><div id="child"><div><div id="great-grand-child"></div></div></div></div> 
    263263<div id="not-in-the-family"></div> 
     264 
     265<div id="insertions-container"><div id="insertions-main"><p>some content.</p></div></div> 
     266<div id="insertions-node-container"><div id="insertions-node-main"><p>some content.</p></div></div> 
     267<div id="element-insertions-container"><div id="element-insertions-main"><p>some content.</p></div></div> 
     268<div id="wrap-container"><p id="wrap"></p></div> 
    264269<!-- Tests follow --> 
    265270<script type="text/javascript" language="javascript" charset="utf-8"> 
    266271// <![CDATA[ 
    267272 
    268273  var testVar = 'to be updated'; 
    269  
     274  var getInnerHTML = function(id) { 
     275    return $(id).innerHTML.toString().toLowerCase().gsub(/[\r\n\t]/, ''); 
     276  }; 
    270277  Element.addMethods("LI", { 
    271278    pancakes: function(element) { return "pancakes"; } 
    272279  }); 
     
    303310      assertElementsMatch(document.getElementsByClassName('B', 'class_names'), 'ul#class_names_ul.A.B', 'div.B.C.D'); 
    304311      assertElementsMatch(document.getElementsByClassName('B', 'class_names_ul')); 
    305312    }}, 
     313 
     314    testInsertionWithHTML: function() {with(this) { 
     315      new Insertion.Before('insertions-main', '<p><em>before</em> text</p><p>more testing</p>'); 
     316      assert(getInnerHTML('insertions-container').startsWith('<p><em>before</em> text</p><p>more testing</p>')); 
     317      new Insertion.After('insertions-main', '<p><em>after</em> text</p><p>more testing</p>'); 
     318      assert(getInnerHTML('insertions-container').endsWith('<p><em>after</em> text</p><p>more testing</p>')); 
     319      new Insertion.Top('insertions-main', '<p><em>top</em> text.</p><p>more testing</p>'); 
     320      assert(getInnerHTML('insertions-main').startsWith('<p><em>top</em> text.</p><p>more testing</p>')); 
     321      new Insertion.Bottom('insertions-main', '<p><em>bottom</em> text.</p><p>more testing</p>'); 
     322      assert(getInnerHTML('insertions-main').endsWith('<p><em>bottom</em> text.</p><p>more testing</p>')); 
     323    }}, 
     324 
     325    testInsertionWithDOMNode: function() {with(this) { 
     326      var createParagraph = function(text) { 
     327        var p = document.createElement('p'); 
     328        p.appendChild(document.createTextNode(text)); 
     329        return p; 
     330      } 
     331      new Insertion.Before('insertions-node-main', createParagraph('node before')); 
     332      assert(getInnerHTML('insertions-node-container').startsWith('<p>node before</p>')); 
     333      new Insertion.After('insertions-node-main', createParagraph('node after')); 
     334      assert(getInnerHTML('insertions-node-container').endsWith('<p>node after</p>')); 
     335      new Insertion.Top('insertions-node-main', createParagraph('node top')); 
     336      assert(getInnerHTML('insertions-node-main').startsWith('<p>node top</p>')); 
     337      new Insertion.Bottom('insertions-node-main', createParagraph('node bottom')); 
     338      assert(getInnerHTML('insertions-node-main').endsWith('<p>node bottom</p>')); 
     339    }}, 
    306340     
    307     testInsertWithTR: function() {with(this) { 
     341    testInsertionWithNonString: function() {with(this) { 
     342      new Insertion.Bottom('insertions-main', 3); 
     343      assert(getInnerHTML('insertions-main').endsWith('3')); 
     344    }}, 
     345 
     346    testInsertionWithTR: function() {with(this) { 
    308347      new Insertion.After('second_row', '<tr id="third_row"><td>Third Row</td></tr>'); 
    309348      assert($('second_row').descendantOf('table')); 
    310349    }}, 
    311      
     350 
    312351    testElementVisible: function(){with(this) { 
    313352      assertNotEqual('none', $('test-visible').style.display); 
    314353      assertEqual('none', $('test-hidden').style.display); 
     
    419458        }); 
    420459      }); 
    421460    }}, 
    422      
     461 
     462    testElementAddBefore: function() {with(this) { 
     463      $('element-insertions-main').addBefore('before'); 
     464      assert(getInnerHTML('element-insertions-container').startsWith('before')); 
     465    }}, 
     466 
     467    testElementAddAfter: function() {with(this) { 
     468      $('element-insertions-main').addAfter('after'); 
     469      assert(getInnerHTML('element-insertions-container').endsWith('after')); 
     470    }}, 
     471 
     472    testElementPrepend: function() {with(this) { 
     473      $('element-insertions-main').prepend('top'); 
     474      assert(getInnerHTML('element-insertions-main').startsWith('top')); 
     475    }}, 
     476 
     477    testElementAppend: function() {with(this) { 
     478      $('element-insertions-main').append('bottom'); 
     479      assert(getInnerHTML('element-insertions-main').endsWith('bottom')); 
     480    }}, 
     481 
     482    testElementWrap: function() {with(this) { 
     483      var element = $('wrap');  
     484      element.wrap('div'); 
     485      assert(getInnerHTML('wrap-container').startsWith('<div><p')); 
     486      element.wrap(document.createElement('div')); 
     487      assert(getInnerHTML('wrap-container').startsWith('<div><div><p')); 
     488      assert(Object.isFunction(wrap.setStyle)); 
     489    }}, 
     490         
    423491    testElementSelectorMethod: function() {with(this) { 
    424492      var testSelector = $('container').getElementsBySelector('p.test'); 
    425493      assertEqual(testSelector.length, 4); 
  • test/unit/base.html

    old new  
    120120      assertEqual('I\'m a div with id test', Object.toJSON(element)); 
    121121    }}, 
    122122     
     123    testObjectIs: function() { with(this) { 
     124      var types = [true, false, 0, 1, '', 'text', null, undefined, [], {}, $H({}), new Hash({}), document.createElement('div'), Prototype.K]; 
     125      $H({isObject: [false, false, false, false, false, false, true, false, true, true, true, true, true, false], 
     126        isFunction: [false, false, false, false, false, false, false, false, false, false, false, false, false, true], 
     127        isArray: [ false, false, false, false, false, false, false, false, true, false, false, false, false, false], 
     128        isHash: [ false, false, false, false, false, false, false, false, false, false, true, true, false, false], 
     129        isString: [ false, false, false, false, true, true,  false, false, false, false, false, false, false, false], 
     130        isNumber: [ false, false, true, true, false, false, false, false, false, false, false, false, false, false], 
     131        isBoolean: [true, true,  false, false, false, false, false, false, false, false, false, false, false, false], 
     132        isUndefined: [false, false, false, false, false, false, false, true, false, false, false, false, false, false], 
     133        isNull: [ false, false, false, false, false, false, true, false, false, false, false, false, false, false], 
     134        isDefined: [true, true, true, true, true, true, true, false, true, true, true, true, true, true], 
     135        isNullOrUndefined: [false, false, false, false, false, false, true, true, false, false, false, false, false, false], 
     136        isElement: [false, false, false, false, false, false, false, false, false, false, false, false, true, false], 
     137        isEnumerable: [false, false, false, false, false, false, false, false, true, false, true, true, false, false] 
     138      }).each(function(item){ 
     139        item.value.zip(types).each(function(args) { 
     140          assertIdentical(args[0], Object[item.key](args[1])); 
     141        }); 
     142      }); 
     143    }},     
     144     
    123145    // sanity check 
    124146    testDoesntExtendObjectPrototype: function() {with(this) { 
    125147      // for-in is supported with objects 
  • src/string.js

    old new  
    11Object.extend(String, { 
    22  interpret: function(value) { 
    3     return value == null ? '' : String(value); 
     3    return Object.isNullOrUndefined(value) ? '' : String(value); 
    44  }, 
    55  specialChar: { 
    66    '\b': '\\b', 
     
    3131   
    3232  sub: function(pattern, replacement, count) { 
    3333    replacement = this.gsub.prepareReplacement(replacement); 
    34     count = count === undefined ? 1 : count; 
     34    count = Object.isUndefined(count) ? 1 : count; 
    3535     
    3636    return this.gsub(pattern, function(match) { 
    3737      if (--count < 0) return match[0]; 
     
    4646   
    4747  truncate: function(length, truncation) { 
    4848    length = length || 30; 
    49     truncation = truncation === undefined ? '...' : truncation; 
     49    truncation = Object.isUndefined(truncation) ? '...' : truncation; 
    5050    return this.length > length ?  
    5151      this.slice(0, length - truncation.length) + truncation : this; 
    5252  }, 
     
    9898        var name = decodeURIComponent(pair[0]); 
    9999        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; 
    100100 
    101         if (hash[name] !== undefined) { 
    102           if (hash[name].constructor != Array
     101        if (Object.isDefined(hash[name])) { 
     102          if (!Object.isArray(hash[name])
    103103            hash[name] = [hash[name]]; 
    104104          if (value) hash[name].push(value); 
    105105        } 
     
    193193}); 
    194194 
    195195String.prototype.gsub.prepareReplacement = function(replacement) { 
    196   if (typeof replacement == 'function') return replacement; 
     196  if (Object.isFunction(replacement)) return replacement; 
    197197  var template = new Template(replacement); 
    198198  return function(match) { return template.evaluate(match) }; 
    199199} 
  • src/base.js

    old new  
    1818Object.extend(Object, { 
    1919  inspect: function(object) { 
    2020    try { 
    21       if (object === undefined) return 'undefined'; 
    22       if (object === null) return 'null'; 
     21      if (Object.isUndefined(object)) return 'undefined'; 
     22      if (Object.isNull(object)) return 'null'; 
    2323      return object.inspect ? object.inspect() : object.toString(); 
    2424    } catch (e) { 
    2525      if (e instanceof RangeError) return '...'; 
     
    3535      case 'unknown': return; 
    3636      case 'boolean': return object.toString(); 
    3737    } 
    38     if (object === null) return 'null'; 
     38    if (Object.isNull(object)) return 'null'; 
    3939    if (object.toJSON) return object.toJSON(); 
    40     if (object.ownerDocument === document) return; 
     40    if (Object.isElement(object)) return; 
    4141    var results = []; 
    4242    for (var property in object) { 
    4343      var value = Object.toJSON(object[property]); 
    44       if (value !== undefined
     44      if (Object.isDefined(value)
    4545        results.push(property.toJSON() + ':' + value); 
    4646    } 
    4747    return '{' + results.join(',') + '}'; 
     
    6363   
    6464  clone: function(object) { 
    6565    return Object.extend({}, object); 
     66  }, 
     67   
     68  isArray: function(object) {  
     69    return !!(object && object.constructor === Array); 
     70  }, 
     71   
     72  isHash: function(object) {  
     73    return object instanceof Hash; 
     74  }, 
     75   
     76  isUndefined: function(object) { 
     77    return object === undefined; 
     78  }, 
     79   
     80  isNull: function(object) { 
     81    return object === null; 
     82  }, 
     83   
     84  isDefined: function(object) { 
     85    return object !== undefined; 
     86  }, 
     87   
     88  isNullOrUndefined: function(object) { 
     89    return object == undefined; 
     90  }, 
     91   
     92  isElement: function(object) { 
     93    return !!(object && object.ownerDocument === document); 
     94  }, 
     95   
     96  isEnumerable: function(object) { 
     97    return !!(object && object.each === Enumerable.each); 
    6698  } 
    6799}); 
    68100 
     101(function(type) { 
     102  for(var i = 0, length = type.length; i < length; i++) 
     103    Object['is' + type[i]] = function(t) { 
     104      return function(object) { 
     105        return typeof object === t; 
     106      }; 
     107    }(type[i].toLowerCase()); 
     108}(['Number', 'Boolean', 'String', 'Function', 'Object'])); 
     109 
    69110Function.prototype.bind = function() { 
    70111  var __method = this, args = $A(arguments), object = args.shift(); 
    71112  return function() { 
  • src/array.js

    old new  
    1313if (Prototype.Browser.WebKit) { 
    1414  $A = Array.from = function(iterable) { 
    1515    if (!iterable) return []; 
    16     if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&  
     16    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&  
    1717      iterable.toArray) { 
    1818      return iterable.toArray(); 
    1919    } else { 
     
    5757   
    5858  flatten: function() { 
    5959    return this.inject([], function(array, value) { 
    60       return array.concat(value && value.constructor == Array
     60      return array.concat(Object.isArray(value)
    6161        value.flatten() : [value]); 
    6262    }); 
    6363  }, 
     
    107107    var results = []; 
    108108    this.each(function(object) { 
    109109      var value = Object.toJSON(object); 
    110       if (value !== undefined) results.push(value); 
     110      if (Object.isDefined(value)) results.push(value); 
    111111    }); 
    112112    return '[' + results.join(',') + ']'; 
    113113  } 
     
    125125    var array = []; 
    126126    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); 
    127127    for (var i = 0, length = arguments.length; i < length; i++) { 
    128       if (arguments[i].constructor == Array) { 
     128      if (Object.isArray(arguments[i])) { 
    129129        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)  
    130130          array.push(arguments[i][j]); 
    131131      } else {  
  • src/dom.js

    old new  
    44      elements.push($(arguments[i])); 
    55    return elements; 
    66  } 
    7   if (typeof element == 'string'
     7  if (Object.isString(element)
    88    element = document.getElementById(element); 
    99  return Element.extend(element); 
    1010} 
     
    5959 
    6060  for (var property in methods) { 
    6161    var value = methods[property]; 
    62     if (typeof value == 'function' && !(property in element)) 
     62    if (Object.isFunction(value) && !(property in element)) 
    6363      element[property] = cache.findOrStore(value); 
    6464  } 
    6565 
     
    103103  }, 
    104104 
    105105  update: function(element, html) { 
    106     html = typeof html == 'undefined' ? '' : html.toString(); 
     106    html = Object.isUndefined(html) ? '' : html.toString(); 
    107107    $(element).innerHTML = html.stripScripts(); 
    108108    setTimeout(function() {html.evalScripts()}, 10); 
    109109    return element; 
     
    111111   
    112112  replace: function(element, html) { 
    113113    element = $(element); 
    114     html = typeof html == 'undefined' ? '' : html.toString(); 
     114    html = Object.isUndefined(html) ? '' : html.toString(); 
    115115    if (element.outerHTML) { 
    116116      element.outerHTML = html.stripScripts(); 
    117117    } else { 
     
    124124    return element; 
    125125  }, 
    126126   
     127  append: function(element, content) { 
     128    element = $(element); 
     129    new Insertion.Bottom(element, content); 
     130    return element; 
     131  }, 
     132   
     133  prepend: function(element, content) { 
     134    element = $(element); 
     135    new Insertion.Top(element, content); 
     136    return element; 
     137  }, 
     138   
     139  addBefore: function(element, content) { 
     140    element = $(element); 
     141    new Insertion.Before(element, content); 
     142    return element; 
     143  }, 
     144   
     145  addAfter: function(element, content) { 
     146    element = $(element); 
     147    new Insertion.After(element, content); 
     148    return element; 
     149  }, 
     150   
     151  wrap: function(element, wrapper) { 
     152    element = $(element); 
     153    if(Object.isString(wrapper)) 
     154      wrapper = document.createElement(wrapper); 
     155    element.parentNode.replaceChild(wrapper, element); 
     156    wrapper.appendChild(element); 
     157    return element; 
     158  }, 
     159     
    127160  inspect: function(element) { 
    128161    element = $(element); 
    129162    var result = '<' + element.tagName.toLowerCase(); 
     
    173206  }, 
    174207   
    175208  match: function(element, selector) { 
    176     if (typeof selector == 'string'
     209    if (Object.isString(selector)
    177210      selector = new Selector(selector); 
    178211    return selector.match($(element)); 
    179212  }, 
     
    329362      if (property == 'opacity') element.setOpacity(styles[property]) 
    330363      else  
    331364        elementStyle[(property == 'float' || property == 'cssFloat') ? 
    332           (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :  
     365          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :  
    333366          (camelized ? property : property.camelize())] = styles[property]; 
    334367 
    335368    return element; 
     
    463496  // IE is missing .innerHTML support for TABLE-related elements 
    464497  Element.Methods.update = function(element, html) { 
    465498    element = $(element); 
    466     html = typeof html == 'undefined' ? '' : html.toString(); 
     499    html = Object.isUndefined(html) ? '' : html.toString(); 
    467500    var tagName = element.tagName.toUpperCase();   
    468501    if (['THEAD','TBODY','TR','TD'].include(tagName)) { 
    469502      var div = document.createElement('div'); 
     
    575608   
    576609  if (!tagName) Object.extend(Element.Methods, methods || {});   
    577610  else { 
    578     if (tagName.constructor == Array) tagName.each(extend); 
     611    if (Object.isArray(tagName)) tagName.each(extend); 
    579612    else extend(tagName); 
    580613  } 
    581614   
     
    629662  if (F.SpecificElementExtensions) { 
    630663    for (var tag in Element.Methods.ByTag) { 
    631664      var klass = findDOMClass(tag); 
    632       if (typeof klass == "undefined") continue; 
     665      if (Object.isUndefined(klass)) continue; 
    633666      copy(T[tag], klass.prototype); 
    634667    } 
    635668  }   
     
    646679Abstract.Insertion.prototype = { 
    647680  initialize: function(element, content) { 
    648681    this.element = $(element); 
     682    if(Object.isElement(content)) return this.insertNode(content); 
     683    content = content.toString(); 
    649684    this.content = content.stripScripts(); 
    650685     
    651686    if (this.adjacency && this.element.insertAdjacentHTML) { 
     
    672707    var div = document.createElement('div'); 
    673708    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>'; 
    674709    return $A(div.childNodes[0].childNodes[0].childNodes); 
     710  }, 
     711   
     712  insertContent: function(fragments) { 
     713    fragments.each(this.insertNode.bind(this)); 
    675714  } 
    676715} 
    677716 
     
    683722    this.range.setStartBefore(this.element); 
    684723  }, 
    685724   
    686   insertContent: function(fragments) { 
    687     fragments.each((function(fragment) { 
    688       this.element.parentNode.insertBefore(fragment, this.element); 
    689     }).bind(this)); 
     725  insertNode: function(node) { 
     726    this.element.parentNode.insertBefore(node, this.element); 
    690727  } 
    691728}); 
    692729 
     
    697734    this.range.collapse(true); 
    698735  }, 
    699736   
     737  insertNode: function(node) { 
     738    this.element.insertBefore(node, this.element.firstChild); 
     739  }, 
     740   
    700741  insertContent: function(fragments) { 
    701     fragments.reverse(false).each((function(fragment) { 
    702       this.element.insertBefore(fragment, this.element.firstChild); 
    703     }).bind(this)); 
     742    fragments.reverse().each(this.insertNode.bind(this)); 
    704743  } 
    705744}); 
    706745 
     
    711750    this.range.collapse(this.element); 
    712751  }, 
    713752   
    714   insertContent: function(fragments) { 
    715     fragments.each((function(fragment) { 
    716       this.element.appendChild(fragment); 
    717     }).bind(this)); 
     753  insertNode: function(node) { 
     754    this.element.appendChild(node); 
    718755  } 
    719756}); 
    720757 
     
    724761    this.range.setStartAfter(this.element); 
    725762  }, 
    726763   
    727   insertContent: function(fragments) { 
    728     fragments.each((function(fragment) { 
    729       this.element.parentNode.insertBefore(fragment,  
    730         this.element.nextSibling); 
    731     }).bind(this)); 
     764  insertNode: function(node) { 
     765    this.element.parentNode.insertBefore(node, this.element.nextSibling); 
    732766  } 
    733767}); 
    734768 
  • src/enumerable.js

    old new  
    8989  }, 
    9090   
    9191  inGroupsOf: function(number, fillWith) { 
    92     fillWith = fillWith === undefined ? null : fillWith; 
     92    fillWith = Object.isUndefined(fillWith) ? null : fillWith; 
    9393    return this.eachSlice(number, function(slice) { 
    9494      while(slice.length < number) slice.push(fillWith); 
    9595      return slice; 
  • src/selector.js

    old new  
    109109    pseudo: function(m) { 
    110110      var h = Selector.xpath.pseudos[m[1]]; 
    111111      if (!h) return ''; 
    112       if (typeof h === 'function') return h(m); 
     112      if (Object.isFunction(h)) return h(m); 
    113113      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); 
    114114    }, 
    115115    operators: { 
     
    375375      var handler = Selector.operators[operator], results = []; 
    376376      for (var i = 0, node; node = nodes[i]; i++) { 
    377377        var nodeValue = Element.readAttribute(node, attr); 
    378         if (nodeValue === null) continue; 
     378        if (Object.isNull(nodeValue)) continue; 
    379379        if (handler(nodeValue, value)) results.push(node); 
    380380      } 
    381381      return results; 
     
    529529  }, 
    530530   
    531531  findElement: function(elements, expression, index) { 
    532     if (typeof expression == 'number') {  
     532    if (Object.isNumber(expression)) {  
    533533      index = expression; expression = false; 
    534534    } 
    535535    return Selector.matchElements(elements, expression || '*')[index || 0]; 
  • src/form.js

    old new  
    1010        var key = element.name, value = $(element).getValue(); 
    1111        if (value != null) {  
    1212                if (key in result) { 
    13             if (result[key].constructor != Array) result[key] = [result[key]]; 
     13            if (!Object.isArray(result[key])) result[key] = [result[key]]; 
    1414            result[key].push(value); 
    1515          } 
    1616          else result[key] = value; 
     
    9191    options.parameters = form.serialize(true); 
    9292     
    9393    if (params) { 
    94       if (typeof params == 'string') params = params.toQueryParams(); 
     94      if (Object.isString(params)) params = params.toQueryParams(); 
    9595      Object.extend(options.parameters, params); 
    9696    } 
    9797     
  • src/hash.js

    old new  
    11var Hash = function(object) { 
    2   if (object instanceof Hash) this.merge(object); 
     2  if (Object.isHash(object)) this.merge(object); 
    33  else Object.extend(this, object || {}); 
    44}; 
    55 
     
    1212      if (!pair.key) return; 
    1313      var value = pair.value; 
    1414       
    15       if (value && typeof value == 'object') { 
    16         if (value.constructor == Array) value.each(function(value) { 
     15      if (value && Object.isObject(value)) { 
     16        if (Object.isArray(value)) value.each(function(value) { 
    1717          parts.add(pair.key, value); 
    1818        }); 
    1919        return; 
     
    2828    var results = []; 
    2929    this.prototype._each.call(object, function(pair) { 
    3030      var value = Object.toJSON(pair.value); 
    31       if (value !== undefined) results.push(pair.key.toJSON() + ':' + value); 
     31      if (Object.isDefined(value)) results.push(pair.key.toJSON() + ':' + value); 
    3232    }); 
    3333    return '{' + results.join(',') + '}'; 
    3434  } 
    3535}); 
    3636 
    3737Hash.toQueryString.addPair = function(key, value, prefix) { 
    38   if (value == null) return; 
     38  if (Object.isNullOrUndefined(value)) return; 
    3939  key = encodeURIComponent(key); 
    40   this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); 
     40  this.push(key + '=' + (Object.isNullOrUndefined(value) ? '' : encodeURIComponent(value))); 
    4141} 
    4242 
    4343Object.extend(Hash.prototype, Enumerable); 
     
    7373    var result; 
    7474    for(var i = 0, length = arguments.length; i < length; i++) { 
    7575      var value = this[arguments[i]]; 
    76       if (value !== undefined){ 
    77         if (result === undefined) result = value; 
     76      if (Object.isDefined(value)){ 
     77        if (Object.isUndefined(result)) result = value; 
    7878        else { 
    79           if (result.constructor != Array) result = [result]; 
     79          if (!Object.isArray(result)) result = [result]; 
    8080          result.push(value) 
    8181        } 
    8282      } 
     
    101101}); 
    102102 
    103103function $H(object) { 
    104   if (object instanceof Hash) return object; 
     104  if (Object.isHash(object)) return object; 
    105105  return new Hash(object); 
    106106}; 
    107107