dart-archive / core-elements

Polymer core-* elements wrapped or ported for Dart
https://pub.dartlang.org/packages/core_elements
Apache License 2.0
33 stars 25 forks source link

core-list-dart polyfill -- itemData is undefined #190

Open jakemac53 opened 9 years ago

jakemac53 commented 9 years ago

Original report https://code.google.com/p/dart/issues/detail?id=22235, copied below:

Reported by robbishop65, Feb 2 I have some code with a core-list-dart being added at runtime as the result of a user action and then populated with items. In Dartium and in Chrome this works fine. However in FireFox and Internet Explorer I get an error and the list fails to populate properly.

In the Firefox console the error is reported as 'TypeError: itemData is undefined.' In the IE11 console I see 'SCRIPT5007: Unable to get property 'toString' of undefined or null reference.'

The DOM is fairly complicated, with the dynamically added core list being part of a custom element which is a child of a Section of nested core animation pages.

core-lists that are statically defined in custom element HTML do not seem to suffer the same problem.

I tried various combinations of CoreList.refresh, .updateMetrics .updateSize and
to work around the problem to no avail.

If there is only one item in the list it populates ok and the itemData error does not appear. If there is more than one item in the list then the first item is displayed but is malformed (bad data values).

What version of the product are you using? Dart SDK 1.8.5, polymer 0.15.5, core_element 0.6.0+4

On what operating system? Win 7 x64

What browser (if applicable)? FireFox 35.0.1, IE11 (Dartium and Chrome work as expected)

jakemac53 commented 9 years ago

Would it be possible for you to post a code sample that will reproduce the issue?

rbishop-bah commented 9 years ago

I can't share our code but I'll see if I can reproduce with a minimal example.

rbishop-bah commented 9 years ago

I won't be able to generate a code sample (well, not without days more work anyway) but here is the spot that's causing trouble in FF/IE (in compiled but not minimized JS):

          if (receiver._core_list_dart$__$selectionEnabled === true && virtualDatum != null) {
            t3 = receiver._selectedData;
            t3.toString;
            values = H.Primitives_getProperty(virtualDatum, "expando$values");
            t3 = J.$eq(values == null ? null : H.Primitives_getProperty(values, t3._getKey$0()), true);
          } else

t3 is undefined, so the toString line causes an error.

It's from CoreList's updateItems. More precisely from _updateItemData in the Dart file:

Dart

      physicalDatum.selected = selectionEnabled && virtualDatum != null ?
          (_selectedData[virtualDatum] == true) : null;

Compiled JS.

   _updateItems$1: function(receiver, force) {
      var groupIndex, groupItemIndex, needsReposition, t1, i, needsReposition0, t2, virtualIndex, physicalIndex, physicalItem, physicalDatum, virtualDatum, values, physicalItemData, t3, groupModel, divider, needsReposition1;
      groupIndex = receiver._groupStart;
      groupItemIndex = receiver._groupStartIndex;
      needsReposition = !force;
      t1 = receiver._physicalItemData;
      i = 0;
      needsReposition0 = false;
      while (true) {
        t2 = receiver._physicalCount;
        if (typeof t2 !== "number")
          return H.iae(t2);
        if (!(i < t2))
          break;
        virtualIndex = receiver._virtualStart + i;
        physicalIndex = C.JSNumber_methods.$mod(virtualIndex - receiver._physicalStart, t2);
        if (physicalIndex < 0)
          physicalIndex = t2 + physicalIndex;
        t2 = receiver._physicalItems;
        if (physicalIndex >>> 0 !== physicalIndex || physicalIndex >= t2.length)
          return H.ioore(t2, physicalIndex);
        physicalItem = t2[physicalIndex];
        t2 = receiver._physicalData._list;
        if (physicalIndex >= t2.length)
          return H.ioore(t2, physicalIndex);
        physicalDatum = t2[physicalIndex];
        virtualDatum = this.dataForIndex$3(receiver, virtualIndex, groupIndex, groupItemIndex);
        if (needsReposition) {
          t2 = J.get$model$x(physicalDatum);
          t2 = t2 == null ? virtualDatum != null : t2 !== virtualDatum;
        } else
          t2 = true;
        if (t2) {
          values = H.Primitives_getProperty(physicalItem, "expando$values");
          physicalItemData = values == null ? null : H.Primitives_getProperty(values, t1._getKey$0());
          if (physicalItemData == null) {
            physicalItemData = new Z._PhysicalItemData(null, null, null, null);
            t1.$indexSet(0, physicalItem, physicalItemData);
          }
          t2 = J.getInterceptor$x(physicalDatum);
          t2.set$model(physicalDatum, virtualDatum);
          t2.set$index(physicalDatum, virtualIndex);
          physicalDatum.set$physicalIndex(physicalIndex);

=====> // LOOK HERE
          if (receiver._core_list_dart$__$selectionEnabled === true && virtualDatum != null) {
            t3 = receiver._selectedData;
            t3.toString;
            values = H.Primitives_getProperty(virtualDatum, "expando$values");
            t3 = J.$eq(values == null ? null : H.Primitives_getProperty(values, t3._getKey$0()), true);
          } else
            t3 = null;
          t2.set$selected(physicalDatum, t3);

         if (receiver._grouped === true) {
            groupModel = J.$index$asx(receiver._core_list_dart$__$groups, groupIndex);
            if (groupModel != null)
              physicalDatum.set$groupModel(groupModel);
            physicalDatum.set$groupIndex(groupIndex);
            physicalDatum.set$groupItemIndex(groupItemIndex);
            physicalItemData.set$isDivider(J.get$isNotEmpty$asx(receiver._core_list_dart$__$data) && J.$eq(groupItemIndex, 0));
            physicalItemData.set$isRowStart(J.$mod$n(groupItemIndex, receiver._rowFactor) === 0);
          } else {
            physicalDatum.set$groupModel(null);
            physicalDatum.set$groupIndex(null);
            physicalDatum.set$groupItemIndex(null);
            physicalItemData.set$isDivider(false);
            t2 = receiver._rowFactor;
            if (typeof t2 !== "number")
              return H.iae(t2);
            physicalItemData.set$isRowStart(C.JSNumber_methods.$mod(virtualIndex, t2) === 0);
          }
          physicalItem.hidden = virtualDatum == null;
          t2 = receiver._physicalDividers;
          if (physicalIndex >= t2.length)
            return H.ioore(t2, physicalIndex);
          divider = t2[physicalIndex];
          if (divider != null) {
            t2 = divider.hidden;
            t3 = physicalItemData.get$isDivider();
            t3 = t2 == null ? t3 == null : t2 === t3;
            t2 = t3;
          } else
            t2 = false;
          if (t2)
            divider.hidden = physicalItemData.get$isDivider() !== true;
          needsReposition1 = needsReposition;
        } else
          needsReposition1 = false;
        needsReposition0 = needsReposition1 || force || needsReposition0;
        groupItemIndex = J.$add$ns(groupItemIndex, 1);
        t2 = receiver._core_list_dart$__$groups;
        if (t2 != null) {
          t2 = J.$sub$n(J.get$length$asx(t2), 1);
          if (typeof groupIndex !== "number")
            return groupIndex.$lt();
          if (typeof t2 !== "number")
            return H.iae(t2);
          t2 = groupIndex < t2;
        } else
          t2 = false;
        if (t2)
          if (J.$ge$n(groupItemIndex, this.getGroupLen$1(receiver, groupIndex))) {
            if (typeof groupIndex !== "number")
              return groupIndex.$add();
            ++groupIndex;
            groupItemIndex = 0;
          }
        ++i;
      }
      return needsReposition0;
    },
jakemac53 commented 9 years ago

After messing around with this for a bit it seems like core-list-dart elements are pretty broken in general when injecting them dynamically :(, I am going to see if this is also an issue on the js side of things.

jakemac53 commented 9 years ago

js example http://jsbin.com/vakeduhuqu/3/edit works in both FF and Chrome, corresponding dart version https://gist.github.com/jakemac53/1e9508cf335ac9299aad doesn't work in FF (although I'm not getting any errors either).