OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library polymer.lib.init; | 4 library polymer.lib.init; |
5 | 5 |
6 import 'dart:async'; | 6 import 'dart:async'; |
7 import 'dart:js'; | 7 import 'dart:js'; |
| 8 import 'package:reflectable/reflectable.dart'; |
8 import 'package:web_components/web_components.dart'; | 9 import 'package:web_components/web_components.dart'; |
9 import 'src/common/js_proxy.dart'; | 10 import 'src/common/js_proxy.dart'; |
10 import 'src/common/polymer_register.dart'; | 11 import 'src/common/polymer_register.dart'; |
11 | 12 |
12 main() => initPolymer(); | 13 main() => initPolymer(); |
13 | 14 |
14 Future initPolymer() async { | 15 Future initPolymer() async { |
15 await initWebComponents(typeFilter: [HtmlImport], initAll: false); | 16 await initWebComponents(typeFilter: [HtmlImport], initAll: false); |
16 // Make sure `src/js/polymer_array_methods.html` is loaded first. | 17 // Make sure polymer is loaded first. |
17 _setUpListMethods(); | 18 _setUpPropertyChanged(); |
18 await initWebComponents( | 19 await initWebComponents( |
19 typeFilter: [CustomElement, CustomElementProxy, PolymerRegister], | 20 typeFilter: [CustomElement, CustomElementProxy, PolymerRegister], |
20 initAll: true); | 21 initAll: true); |
21 } | 22 } |
22 | 23 |
23 void _setUpListMethods() { | 24 final _polymerDart = context['Polymer']['Dart']; |
24 var polymerDart = context['Polymer']['Dart']; | 25 |
25 polymerDart['push'] = (List list, Iterable items) { | 26 void _setUpPropertyChanged() { |
26 list.addAll(items.map((item) => dartValue(item))); | 27 _polymerDart['propertyChanged'] = (instance, String path, newValue) { |
27 }; | 28 if (instance is List) { |
28 polymerDart['pop'] = (List list) => list.removeLast(); | 29 // We only care about `splices` for Lists. This does mean we don't support |
29 polymerDart['shift'] = (List list) => list.removeAt(0); | 30 // setting special properties of custom List implementations though. |
30 polymerDart['unshift'] = (List list, Iterable items) { | 31 if (path == 'splices') { |
31 list.insertAll(0, items.map((item) => dartValue(item))); | 32 // Only apply splices once, if multiple elements have a binding set up |
32 }; | 33 // for the same list then they will each get called here. |
33 polymerDart['splice'] = | 34 var alreadyApplied = newValue['_applied']; |
34 (List list, int start, int deleteCount, Iterable items) { | 35 if (alreadyApplied == true) return; |
35 if (start < 0) start = list.length + start; | 36 newValue['_applied'] = true; |
36 if (deleteCount > 0) list.removeRange(start, start + deleteCount); | 37 |
37 list.insertAll(start, items.map((item) => dartValue(item))); | 38 var splices = newValue['indexSplices']; |
| 39 for (var splice in splices) { |
| 40 var index = splice['index']; |
| 41 var removed = splice['removed']; |
| 42 if (removed != null && removed.length > 0) { |
| 43 instance.removeRange(index, index + removed.length); |
| 44 } |
| 45 var addedCount = splice['addedCount']; |
| 46 var original = splice['object'] as JsArray; |
| 47 instance.insertAll(index, |
| 48 original.getRange(index, addedCount + index).map(dartValue)); |
| 49 } |
| 50 } else if (path == 'length') { |
| 51 // Ignore this case, wait for `splices`. |
| 52 return; |
| 53 } else { |
| 54 try { |
| 55 var index = int.parse(path); |
| 56 instance[index] = dartValue(newValue); |
| 57 } on FormatException catch (_) { |
| 58 throw 'Only `splices`, `length`, and index paths are supported for ' |
| 59 'list types, found $path.'; |
| 60 } |
| 61 } |
| 62 } else if (instance is Map) { |
| 63 instance[path] = dartValue(newValue); |
| 64 } else { |
| 65 var instanceMirror = jsProxyReflectable.reflect(instance); |
| 66 // Catch errors for read only properties. Checking for setters using |
| 67 // reflection is too slow. |
| 68 // https://github.com/dart-lang/polymer-dart/issues/590 |
| 69 try { |
| 70 instanceMirror.invokeSetter(path, dartValue(newValue)); |
| 71 } on NoSuchMethodError catch (_) {} on NoSuchCapabilityError catch (_) { |
| 72 // TODO(jakemac): Remove once |
| 73 // https://github.com/dart-lang/reflectable/issues/30 is fixed. |
| 74 } |
| 75 } |
38 }; | 76 }; |
39 } | 77 } |
OLD | NEW |