dart-archive / polymer-dart

Polymer support for Dart
https://pub.dartlang.org/packages/polymer
BSD 3-Clause "New" or "Revised" License
180 stars 33 forks source link

Can't read properties of event.details (sent from JS) #596

Closed zoechi closed 9 years ago

zoechi commented 9 years ago

In the JS demo event.details looks like:

Object {keyboardEvent: KeyboardEvent}
> keyboardEvent: KeyboardEvent
v __proto__: Object
  combo: "pageup"
  event: "keydown"
  key: "pageup"
  __proto__: Object

in Dart

v {keyboardEvent: Instance of 'KeyboardEvent'}
  > [[class]]: _InternalLinkedHashMap

sent from https://github.com/PolymerElements/iron-a11y-keys/blob/master/demo/x-key-aware.html#L49

I can access event.detail['keyboardEvent'] butevent.detail['combo'] doesn't work in Dart (works fine in the JS example)

Any idea how to get access to the combo item?

jakemac53 commented 9 years ago

I have a feeling it might just need to be updated, also if the detail object is actually another event and they set custom properties on it from JS then you would need to do something like:

new JsObject.fromBrowserObject(e.detail['keyboardEvent'].original)['combo']

We could possibly automate this in the CustomEventWrapper object though (it is already abstracting away some of the event.detail madness from you). Basically just override the index operators to read from the underlying CustomEvent object. This could be a relatively easy contribution if you are interested ;).

zoechi commented 9 years ago

I tried that. combo isn't a property on KeyboardEvent but another item in the map (sibling to keyboardEvent) but added to __proto__ (my interpretation from my limited JS knowledge) and not accessible from the Dart side. in JS event.detail.combo returns pageup. In Dart event.detail['combo'] returnsnull`.

jakemac53 commented 9 years ago

Ok, so this should work: convertToJs(event.detail)['combo'] (jsValue instead of convertToJs if you are on the 0.2.0-dev branch of polymer_interop). Basically convertToJs gives you the original JsObject that the map was created from.

Long story short it looks like they are hot swapping the prototype of the object without actually creating a constructor, and that breaks some assumptions in convertToDart so the dart map we create doesn't contain things from the prototype.

jakemac53 commented 9 years ago

Edit: they aren't hot swapping they are creating it with Object.create(proto). When you do that the constructor is still Object, so we think its a normal object and go ahead and create a map out of it. We should be checking that the prototype is equal to Object.prototype instead of checking the constructor.

tldr; Javascript

jakemac53 commented 9 years ago

should be fixed now (although not verified)

zoechi commented 9 years ago

Yup, works fine :)