Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#10142 closed defect (fixed)

dojo.query returns nodes in the wrong order

Reported by: arv Owned by: alex
Priority: high Milestone: 1.4
Component: Query Version: 1.4.0b
Keywords: Cc: alex
Blocked By: Blocking:

Description

We are using a port of dojo.query in our js library and I found and fixed some issues. I haven't tested the latest copies of dojo.query so these might have been fixed already.

When using the DOM version of dojo.query results are returned in the wrong order.

DOM:

  <div class="myupperclass">
    <span class="myclass">
      <input id="myid1">
    </span>
    <span class="myclass">
      <input id="myid2">
    </span>
  </div>

JS Unit Test:

function testOrder() {
  var els = dojo.query('.myupperclass .myclass input');
  assertEquals('myid1', els[0].id);
  assertEquals('myid2', els[1].id);
}

The fix was to change the loop order inside the function filterDown:

  var filterDown = function(root, queryParts) {
    // NOTE:
    //    this is the guts of the DOM query system. It takes a list of
    //    parsed query parts and a root and finds children which match
    //    the selector represented by the parts
    var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;

    for (var i = 0; i < qpl; i++) {
      ret = [];
      qp = queryParts[i];
      x = candidates.length - 1;
      if (x > 0) {
        // if we have more than one root at this level, provide a new
        // hash to use for checking group membership but tell the
        // system not to post-filter us since we will already have been
        // gauranteed to be unique
        bag = {};
        ret.nozip = true;
      }
      var gef = getElementsFunc(qp);
      for (var j = 0; te = candidates[j]; j++) {
        // for every root, get the elements that match the descendant
        // selector, adding them to the 'ret' array and filtering them
        // via membership in this level's bag. If there are more query
        // parts, then this level's return will be used as the next
        // level's candidates
        gef(te, ret, bag);
      }
      if (!ret.length) { break; }
      candidates = ret;
    }
    return ret;
  };

Change History (4)

comment:1 Changed 10 years ago by alex

Owner: changed from anonymous to alex
Status: newassigned

comment:2 Changed 10 years ago by bill

Component: GeneralQuery

comment:3 Changed 10 years ago by James Burke

Resolution: fixed
Status: assignedclosed

(In [20852]) Fixes #10142. Thanks to arv for providing a test case that identifies the problem and identifying the backwards loop. \!strict

comment:4 Changed 10 years ago by bill

Milestone: tbd1.4
Note: See TracTickets for help on using tickets.