Chromium Code Reviews| Index: sdk/lib/js/dart2js/js_dart2js.dart |
| diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart |
| index 852b0dbc4ede6c4830bf080809c8aa81ae1b10d3..226cbb97300059ef0907d0cf160a757aea8cd38b 100644 |
| --- a/sdk/lib/js/dart2js/js_dart2js.dart |
| +++ b/sdk/lib/js/dart2js/js_dart2js.dart |
| @@ -5,7 +5,7 @@ |
| library dart.js; |
| import 'dart:html' show Blob, ImageData, Node; |
| -import 'dart:collection' show HashMap; |
| +import 'dart:collection' show HashMap, ListMixin; |
| import 'dart:indexed_db' show KeyRange; |
| import 'dart:typed_data' show TypedData; |
| @@ -29,7 +29,7 @@ _callDartFunction(callback, bool captureThis, self, List arguments) { |
| if (captureThis) { |
| arguments = [self]..addAll(arguments); |
| } |
| - var dartArgs = arguments.map(_convertToDart).toList(); |
| + var dartArgs = new List.from(arguments.map(_convertToDart)); |
| return _convertToJS(Function.apply(callback, dartArgs)); |
| } |
| @@ -187,7 +187,7 @@ class JsObject { |
| } |
| return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, name, |
| _jsObject, |
| - args == null ? null : args.map(_convertToJS).toList())); |
| + args == null ? null : new List.from(args.map(_convertToJS)))); |
| } |
| } |
| @@ -207,7 +207,99 @@ class JsFunction extends JsObject { |
| dynamic apply(List args, { thisArg }) => |
| _convertToDart(JS('', '#.apply(#, #)', _jsObject, |
| _convertToJS(thisArg), |
| - args == null ? null : args.map(_convertToJS).toList())); |
| + args == null ? null : new List.from(args.map(_convertToJS)))); |
| +} |
| + |
| +/** |
| + * A [List] that is stored in a JavaScript array. |
| + */ |
| +class JsArray<E> extends JsObject with ListMixin<E> { |
| + |
| + JsArray() : super._fromJs([]); |
| + |
| + JsArray.from(Iterable<E> other) |
| + : super._fromJs([]..addAll(other.map(_convertToJS))); |
| + |
| + JsArray._fromJs(jsObject) : super._fromJs(jsObject); |
| + |
| + _checkIndex(int index, {bool insert: false}) { |
|
Jacob
2013/10/24 21:02:09
why not have two check index methods? one for inse
justinfagnani
2013/10/26 03:26:52
Done.
|
| + int length = insert ? this.length + 1 : this.length; |
| + if (index is int && (index < 0 || index >= length)) { |
| + throw new RangeError.range(index, 0, length); |
| + } |
| + } |
| + |
| + _checkRange(int start, int end) { |
| + if (start < 0 || start > this.length) { |
| + throw new RangeError.range(start, 0, this.length); |
| + } |
| + if (end < start || end > this.length) { |
| + throw new RangeError.range(end, start, this.length); |
| + } |
| + } |
| + |
| + // Methods required by ListMixin |
| + |
| + E operator [](int index) { |
| + _checkIndex(index); |
| + return super[index]; |
| + } |
| + |
| + void operator []=(int index, E value) { |
| + _checkIndex(index); |
| + super[index] = value; |
| + } |
| + |
| + int get length => super['length']; |
| + |
| + void set length(int length) { super['length'] = length; } |
| + |
| + |
| + // Methods overriden for better performance |
| + |
| + void add(E value) { |
| + callMethod('push', [value]); |
| + } |
| + |
| + void addAll(Iterable<E> iterable) { |
| + var list = (JS('bool', '# instanceof Array', iterable)) |
| + ? iterable |
| + : new List.from(iterable); |
| + callMethod('push', list); |
| + } |
| + |
| + void insert(int index, E element) { |
| + _checkIndex(index, insert:true); |
| + callMethod('splice', [index, 0, element]); |
| + } |
| + |
| + E removeAt(int index) { |
| + _checkIndex(index); |
| + return callMethod('splice', [index, 1])[0]; |
| + } |
| + |
| + E removeLast() { |
| + if (length == 0) throw new RangeError(-1); |
| + return callMethod('pop'); |
| + } |
| + |
| + void removeRange(int start, int end) { |
| + _checkRange(start, end); |
| + callMethod('splice', [start, end - start]); |
| + } |
| + |
| + void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { |
| + _checkRange(start, end); |
| + int length = end - start; |
| + if (length == 0) return; |
| + if (skipCount < 0) throw new ArgumentError(skipCount); |
| + var args = [start, length]..addAll(iterable.skip(skipCount).take(length)); |
| + callMethod('splice', args); |
| + } |
| + |
| + void sort([int compare(E a, E b)]) { |
| + callMethod('sort', [compare]); |
| + } |
| } |
| // property added to a Dart object referencing its JS-side DartObject proxy |
| @@ -281,6 +373,9 @@ Object _convertToDart(o) { |
| } else if (JS('bool', 'typeof # == "function"', o)) { |
| return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME, |
| (o) => new JsFunction._fromJs(o)); |
| + } else if (JS('bool', '# instanceof Array', o)) { |
| + return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, |
| + (o) => new JsArray._fromJs(o)); |
| } else if (JS('bool', '#.constructor === DartObject', o)) { |
| return JS('', '#.o', o); |
| } else { |