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

Ticket #7873: final_selectors_patch.diff

File final_selectors_patch.diff, 3.8 kB (added by savetheclocktower, 2 years ago)
  • src/selector.js

    old new  
    162162      'only-of-type':   function(m) { 
    163163        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); 
    164164      }, 
    165       nth: function(predicate, m) { 
    166         var mm, formula = m[6]
     165      nth: function(fragment, m) { 
     166        var mm, formula = m[6], predicate
    167167        if (formula == 'even') formula = '2n+0'; 
    168168        if (formula == 'odd')  formula = '2n+1'; 
    169169        if (mm = formula.match(/^(\d+)$/)) // digit only 
    170           predicate += "= " + mm[1]; 
    171         if (mm = formula.match(/^(\d+)?n(\+(\d+))?/)) { // an+b 
     170          return '[' + fragment + "= " + mm[1] + ']'; 
     171        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b 
     172          if (mm[1] == "-") mm[1] = -1; 
    172173          var a = mm[1] ? Number(mm[1]) : 1; 
    173           var b = mm[3] ? Number(mm[3]) : 0; 
    174           predicate += "mod " + a + " = " + b; 
     174          var b = mm[2] ? Number(mm[2]) : 0; 
     175          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + 
     176          "((#{fragment} - #{b}) div #{a} >= 0)]"; 
     177          return new Template(predicate).evaluate({ 
     178            fragment: fragment, a: a, b: b }); 
    175179        } 
    176         return "[" + predicate + "]";         
    177180      } 
    178181    } 
    179182  }, 
     
    265268    descendant: function(nodes) { 
    266269      var h = Selector.handlers; 
    267270      for (var i = 0, results = [], node; node = nodes[i]; i++) 
    268         h.concat(results, Element.descendants(node)); 
     271        h.concat(results, node.getElementsByTagName('*')); 
    269272      return results; 
    270273    }, 
    271274     
    272275    child: function(nodes) { 
    273276      var h = Selector.handlers; 
    274       for (var i = 0, results = [], node; node = nodes[i]; i++) 
    275         h.concat(results, Element.immediateDescendants(node)); 
     277      for (var i = 0, results = [], node; node = nodes[i]; i++) { 
     278        for (var j = 0, children = [], child; child = node.childNodes[j]; j++) 
     279          if (child.nodeType == 1 && child.tagName != '!') results.push(child); 
     280      } 
    276281      return results; 
    277282    }, 
    278283     
     
    432437      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); 
    433438    }, 
    434439     
     440    // handles the an+b logic 
     441    getIndices: function(a, b, total) { 
     442      if (a == 0) return b > 0 ? [b] : []; 
     443      return $R(1, total).inject([], function(memo, i) { 
     444        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); 
     445        return memo; 
     446      }); 
     447    }, 
     448     
    435449    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type 
    436450    nth: function(nodes, formula, root, reverse, ofType) { 
     451      if (nodes.length == 0) return []; 
    437452      if (formula == 'even') formula = '2n+0'; 
    438453      if (formula == 'odd')  formula = '2n+1'; 
    439454      var h = Selector.handlers, results = [], indexed = [], m; 
     
    448463        formula = Number(formula); 
    449464        for (var i = 0, node; node = nodes[i]; i++) 
    450465          if (node.nodeIndex == formula) results.push(node); 
    451       } else if (m = formula.match(/^(\d+)?n(\+(\d+))?$/)) { // an+b 
     466      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b 
     467        if (m[1] == "-") m[1] = -1; 
    452468        var a = m[1] ? Number(m[1]) : 1; 
    453         var b = m[3] ? Number(m[3]) : 0; 
    454         for (var i = 0, node; node = nodes[i]; i++) 
    455           if (node.nodeIndex % a == b) results.push(node); 
     469        var b = m[2] ? Number(m[2]) : 0; 
     470        var indices = Selector.pseudos.getIndices(a, b, nodes.length); 
     471        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { 
     472          for (var j = 0; j < l; j++) 
     473            if (node.nodeIndex == indices[j]) results.push(node); 
     474        } 
    456475      } 
    457476      h.unmark(nodes); 
    458477      h.unmark(indexed);