Index: lib/init.dart |
diff --git a/lib/init.dart b/lib/init.dart |
index 3a56305a7fb3c4a6392c5dcf58cff7d9c52ac324..06b0cb3bb64db24bfd626e160e91e4cfe39cce98 100644 |
--- a/lib/init.dart |
+++ b/lib/init.dart |
@@ -5,6 +5,7 @@ library polymer.lib.init; |
import 'dart:async'; |
import 'dart:js'; |
+import 'package:reflectable/reflectable.dart'; |
import 'package:web_components/web_components.dart'; |
import 'src/common/js_proxy.dart'; |
import 'src/common/polymer_register.dart'; |
@@ -13,27 +14,54 @@ main() => initPolymer(); |
Future initPolymer() async { |
await initWebComponents(typeFilter: [HtmlImport], initAll: false); |
- // Make sure `src/js/polymer_array_methods.html` is loaded first. |
- _setUpListMethods(); |
+ // Make sure polymer is loaded first. |
+ _setUpPropertyChanged(); |
await initWebComponents( |
typeFilter: [CustomElement, CustomElementProxy, PolymerRegister], |
initAll: true); |
} |
-void _setUpListMethods() { |
- var polymerDart = context['Polymer']['Dart']; |
- polymerDart['push'] = (List list, Iterable items) { |
- list.addAll(items.map((item) => dartValue(item))); |
- }; |
- polymerDart['pop'] = (List list) => list.removeLast(); |
- polymerDart['shift'] = (List list) => list.removeAt(0); |
- polymerDart['unshift'] = (List list, Iterable items) { |
- list.insertAll(0, items.map((item) => dartValue(item))); |
- }; |
- polymerDart['splice'] = |
- (List list, int start, int deleteCount, Iterable items) { |
- if (start < 0) start = list.length + start; |
- if (deleteCount > 0) list.removeRange(start, start + deleteCount); |
- list.insertAll(start, items.map((item) => dartValue(item))); |
+final _polymerDart = context['Polymer']['Dart']; |
+ |
+void _setUpPropertyChanged() { |
+ _polymerDart['propertyChanged'] = (instance, String path, newValue) { |
+ if (instance is List) { |
+ // We only care about `splices` for Lists. This does mean we don't support |
+ // setting special properties of custom List implementations though. |
+ if (path == 'splices') { |
+ // Only apply splices once, if multiple elements have a binding set up |
+ // for the same list then they will each get called here. |
+ var alreadyApplied = newValue['_applied']; |
+ if (alreadyApplied == true) return; |
+ newValue['_applied'] = true; |
+ |
+ var splices = newValue['indexSplices']; |
+ for (var splice in splices) { |
+ var index = splice['index']; |
+ var removed = splice['removed']; |
+ if (removed != null && removed.length > 0) { |
+ instance.removeRange(index, index + removed.length); |
+ } |
+ var addedCount = splice['addedCount']; |
+ var original = splice['object'] as JsArray; |
+ instance.insertAll(index, |
+ original.getRange(index, addedCount + index).map(dartValue)); |
+ } |
+ } else { |
+ try { |
+ var index = int.parse(path); |
+ instance[index] = dartValue(newValue); |
+ } on FormatException catch (_) {} |
Siggi Cherem (dart-lang)
2015/09/17 21:11:59
maybe log the error? or let the exception bubble?
jakemac
2015/09/23 17:37:08
Throwing a different error now which explains the
|
+ } |
+ } else if (instance is Map) { |
+ instance[path] = dartValue(newValue); |
+ } else { |
+ var instanceMirror = jsProxyReflectable.reflect(instance); |
+ // Catch errors for read only properties. Checking for setters using |
+ // reflection is to slow. |
Siggi Cherem (dart-lang)
2015/09/17 21:11:59
s/to/too/
might be worth investigating whether it
jakemac
2015/09/23 17:37:08
added https://github.com/dart-lang/polymer-dart/is
|
+ try { |
+ instanceMirror.invokeSetter(path, dartValue(newValue)); |
+ } on NoSuchMethodError catch (_) {} |
+ } |
}; |
} |