Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: lib/dom/templates/html/impl/impl_Element.darttemplate

Issue 9930008: Fix issue http://code.google.com/p/dart/issues/detail?id=1877 without degrading performance. Impro… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 4
5 // TODO(jacobr): use _Lists.dart to remove some of the duplicated 5 // TODO(jacobr): use _Lists.dart to remove some of the duplicated
6 // functionality. 6 // functionality.
7 class _ChildrenElementList implements ElementList { 7 class _ChildrenElementList implements ElementList {
8 // Raw Element. 8 // Raw Element.
9 final _ElementImpl _element; 9 final _ElementImpl _element;
10 final _HTMLCollectionImpl _childElements; 10 final _HTMLCollectionImpl _childElements;
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 class _ElementList extends _ListWrapper<Element> implements ElementList { 298 class _ElementList extends _ListWrapper<Element> implements ElementList {
299 _ElementList(List<Element> list) : super(list); 299 _ElementList(List<Element> list) : super(list);
300 300
301 ElementList filter(bool f(Element element)) => 301 ElementList filter(bool f(Element element)) =>
302 new _ElementList(super.filter(f)); 302 new _ElementList(super.filter(f));
303 303
304 ElementList getRange(int start, int length) => 304 ElementList getRange(int start, int length) =>
305 new _ElementList(super.getRange(start, length)); 305 new _ElementList(super.getRange(start, length));
306 } 306 }
307 307
308 class ElementAttributeMap implements Map<String, String> { 308 class _ElementAttributeMap implements AttributeMap {
309 309
310 final _ElementImpl _element; 310 final _ElementImpl _element;
311 311
312 ElementAttributeMap._wrap(this._element); 312 _ElementAttributeMap(this._element);
313 313
314 bool containsValue(String value) { 314 bool containsValue(String value) {
315 final attributes = _element.$dom_attributes; 315 final attributes = _element.$dom_attributes;
316 for (int i = 0, len = attributes.length; i < len; i++) { 316 for (int i = 0, len = attributes.length; i < len; i++) {
317 if(value == attributes[i].value) { 317 if(value == attributes[i].value) {
318 return true; 318 return true;
319 } 319 }
320 } 320 }
321 return false; 321 return false;
322 } 322 }
323 323
324 bool containsKey(String key) { 324 bool containsKey(String key) {
325 return _element.$dom_hasAttribute(key); 325 return _element.$dom_hasAttribute(key);
326 } 326 }
327 327
328 String operator [](String key) { 328 String operator [](String key) {
329 return _element.$dom_getAttribute(key); 329 return _element.$dom_getAttribute(key);
330 } 330 }
331 331
332 void operator []=(String key, String value) { 332 void operator []=(String key, value) {
333 _element.$dom_setAttribute(key, value); 333 _element.$dom_setAttribute(key, '$value');
334 } 334 }
335 335
336 String putIfAbsent(String key, String ifAbsent()) { 336 String putIfAbsent(String key, String ifAbsent()) {
337 if (!containsKey(key)) { 337 if (!containsKey(key)) {
338 this[key] = ifAbsent(); 338 this[key] = ifAbsent();
339 } 339 }
340 } 340 }
341 341
342 String remove(String key) { 342 String remove(String key) {
343 _element.$dom_removeAttribute(key); 343 _element.$dom_removeAttribute(key);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 386 }
387 387
388 /** 388 /**
389 * Returns true if there is no {key, value} pair in the map. 389 * Returns true if there is no {key, value} pair in the map.
390 */ 390 */
391 bool isEmpty() { 391 bool isEmpty() {
392 return length == 0; 392 return length == 0;
393 } 393 }
394 } 394 }
395 395
396 /**
397 * Provides a Map abstraction on top of data-* attributes, similar to the
398 * dataSet in the old DOM.
399 */
400 class _DataAttributeMap implements AttributeMap {
401
402 final Map<String, String> $dom_attributes;
403
404 _DataAttributeMap(this.$dom_attributes);
405
406 // interface Map
407
408 // TODO: Use lazy iterator when it is available on Map.
409 bool containsValue(String value) => getValues().some((v) => v == value);
410
411 bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
412
413 String operator [](String key) => $dom_attributes[_attr(key)];
414
415 void operator []=(String key, value) {
416 $dom_attributes[_attr(key)] = '$value';
417 }
418
419 String putIfAbsent(String key, String ifAbsent()) {
420 if (!containsKey(key)) {
nweiz 2012/03/30 00:06:23 Can't this just call $dom_attributes.putIfAbsent?
Jacob 2012/03/30 00:40:53 Yep. Done. FYI this code isn't new I just moved it
421 return this[key] = ifAbsent();
422 }
423 return this[key];
424 }
425
426 String remove(String key) => $dom_attributes.remove(_attr(key));
427
428 void clear() {
429 // Needs to operate on a snapshot since we are mutatiting the collection.
nweiz 2012/03/30 00:06:23 mutating
Jacob 2012/03/30 00:40:53 Done.
430 for (String key in getKeys()) {
431 remove(key);
432 }
433 }
434
435 void forEach(void f(String key, String value)) {
436 $dom_attributes.forEach((String key, String value) {
437 if (_matches(key)) {
438 f(_strip(key), value);
439 }
440 });
441 }
442
443 Collection<String> getKeys() {
444 final keys = new List<String>();
445 $dom_attributes.forEach((String key, String value) {
nweiz 2012/03/30 00:06:23 This would be a little cleaner if you used this cl
Jacob 2012/03/30 00:40:53 Reasonable idea but I'd rather leave it unchanged.
446 if (_matches(key)) {
447 keys.add(_strip(key));
448 }
449 });
450 return keys;
451 }
452
453 Collection<String> getValues() {
454 final values = new List<String>();
455 $dom_attributes.forEach((String key, String value) {
nweiz 2012/03/30 00:06:23 As above, a little cleaner to use this class's for
Jacob 2012/03/30 00:40:53 feel free to send an alternate CL.
456 if (_matches(key)) {
457 values.add(value);
458 }
459 });
460 return values;
461 }
462
463 int get length() => getKeys().length;
464
465 // TODO: Use lazy iterator when it is available on Map.
466 bool isEmpty() => length == 0;
467
468 // Helpers.
469 String _attr(String key) => 'data-$key';
470 bool _matches(String key) => key.startsWith('data-');
471 String _strip(String key) => key.substring(5);
472 }
473
474 class _CssClassSet implements Set<String> {
475
476 final _ElementImpl _element;
477
478 _CssClassSet(this._element);
479
480 String toString() {
481 return _formatSet(_read());
nweiz 2012/03/30 00:06:23 =>, here and below.
Jacob 2012/03/30 00:40:53 Done.
482 }
483
484 // interface Iterable - BEGIN
485 Iterator<String> iterator() {
486 return _read().iterator();
487 }
488 // interface Iterable - END
489
490 // interface Collection - BEGIN
491 void forEach(void f(String element)) {
492 _read().forEach(f);
493 }
494
495 Collection map(f(String element)) {
496 return _read().map(f);
497 }
498
499 Collection<String> filter(bool f(String element)) {
500 return _read().filter(f);
501 }
502
503 bool every(bool f(String element)) {
504 return _read().every(f);
505 }
506
507 bool some(bool f(String element)) {
508 return _read().some(f);
509 }
510
511 bool isEmpty() {
512 return _read().isEmpty();
513 }
514
515 int get length() {
516 return _read().length;
517 }
518 // interface Collection - END
519
520 // interface Set - BEGIN
521 bool contains(String value) {
522 return _read().contains(value);
523 }
524
525 void add(String value) {
526 // TODO - figure out if we need to do any validation here
527 // or if the browser natively does enough
528 _modify((s) => s.add(value));
529 }
530
531 bool remove(String value) {
532 Set<String> s = _read();
533 bool result = s.remove(value);
nweiz 2012/03/30 00:06:23 Couldn't you use _modify here if you changed it to
Jacob 2012/03/30 00:40:53 i don't follow. if you want to send a cleanup cl f
534 _write(s);
535 return result;
536 }
537
538 void addAll(Collection<String> collection) {
539 // TODO - see comment above about validation
540 _modify((s) => s.addAll(collection));
541 }
542
543 void removeAll(Collection<String> collection) {
544 _modify((s) => s.removeAll(collection));
545 }
546
547 bool isSubsetOf(Collection<String> collection) {
548 return _read().isSubsetOf(collection);
549 }
550
551 bool containsAll(Collection<String> collection) {
552 return _read().containsAll(collection);
553 }
554
555 Set<String> intersection(Collection<String> other) {
556 return _read().intersection(other);
557 }
558
559 void clear() {
560 _modify((s) => s.clear());
561 }
562 // interface Set - END
563
564 /**
565 * Helper method used to modify the set of css classes on this element.
566 *
567 * f - callback with:
568 * s - a Set of all the css class name currently on this element.
569 *
570 * After f returns, the modified set is written to the
571 * className property of this element.
572 */
573 void _modify( f(Set<String> s)) {
574 Set<String> s = _read();
575 f(s);
576 _write(s);
577 }
578
579 /**
580 * Read the class names from the Element class property,
581 * and put them into a set (duplicates are discarded).
582 */
583 Set<String> _read() {
584 // TODO(mattsh) simplify this once split can take regex.
585 Set<String> s = new Set<String>();
586 for (String name in $dom_className().split(' ')) {
587 String trimmed = name.trim();
588 if (!trimmed.isEmpty()) {
589 s.add(trimmed);
590 }
591 }
592 return s;
593 }
594
595 /**
596 * Read the class names as a space-separated string. This is meant to be
597 * overridden by subclasses.
598 */
599 String $dom_className() => _element.$dom_className;
nweiz 2012/03/30 00:06:23 Why does this need to be implemented here?
Jacob 2012/03/30 00:40:53 Good catch... my regexp adding $dom to the names o
600
601 /**
602 * Join all the elements of a set into one string and write
603 * back to the element.
604 */
605 void _write(Set s) {
606 _element.$dom_className = _formatSet(s);
607 }
608
609 String _formatSet(Set<String> s) {
610 // TODO(mattsh) should be able to pass Set to String.joins http:/b/5398605
611 List list = new List.from(s);
612 return Strings.join(list, ' ');
613 }
614 }
615
396 class _SimpleClientRect implements ClientRect { 616 class _SimpleClientRect implements ClientRect {
397 final num left; 617 final num left;
398 final num top; 618 final num top;
399 final num width; 619 final num width;
400 final num height; 620 final num height;
401 num get right() => left + width; 621 num get right() => left + width;
402 num get bottom() => top + height; 622 num get bottom() => top + height;
403 623
404 const _SimpleClientRect(this.left, this.top, this.width, this.height); 624 const _SimpleClientRect(this.left, this.top, this.width, this.height);
405 625
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 final out = new List(_clientRects.length); 671 final out = new List(_clientRects.length);
452 for (num i = 0; i < _clientRects.length; i++) { 672 for (num i = 0; i < _clientRects.length; i++) {
453 out[i] = _clientRects.item(i); 673 out[i] = _clientRects.item(i);
454 } 674 }
455 return out; 675 return out;
456 } 676 }
457 } 677 }
458 678
459 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { 679 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
460 680
461 // TODO(jacobr): caching these may hurt performance.
462 ElementAttributeMap _elementAttributeMap;
463 _CssClassSet _cssClassSet;
464 _DataAttributeMap _dataAttributes;
465
466 /** 681 /**
467 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute, 682 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute,
468 * Element.removeAttribute 683 * Element.removeAttribute
469 */ 684 */
470 Map<String, String> get attributes() { 685 _ElementAttributeMap get attributes() => new _ElementAttributeMap(this);
471 if (_elementAttributeMap === null) {
472 _elementAttributeMap = new ElementAttributeMap._wrap(this);
473 }
474 return _elementAttributeMap;
475 }
476 686
477 void set attributes(Map<String, String> value) { 687 void set attributes(Map<String, String> value) {
478 Map<String, String> attributes = this.attributes; 688 Map<String, String> attributes = this.attributes;
479 attributes.clear(); 689 attributes.clear();
480 for (String key in value.getKeys()) { 690 for (String key in value.getKeys()) {
481 attributes[key] = value[key]; 691 attributes[key] = value[key];
482 } 692 }
483 } 693 }
484 694
485 void set elements(Collection<Element> value) { 695 void set elements(Collection<Element> value) {
486 final elements = this.elements; 696 final elements = this.elements;
487 elements.clear(); 697 elements.clear();
488 elements.addAll(value); 698 elements.addAll(value);
489 } 699 }
490 700
491 ElementList get elements() => new _ChildrenElementList._wrap(this); 701 ElementList get elements() => new _ChildrenElementList._wrap(this);
492 702
493 ElementList queryAll(String selectors) => 703 ElementList queryAll(String selectors) =>
494 new _FrozenElementList._wrap($dom_querySelectorAll(selectors)); 704 new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
495 705
496 Set<String> get classes() { 706 _CssClassSet get classes() => new _CssClassSet(this);
497 if (_cssClassSet === null) {
498 _cssClassSet = new _CssClassSet(this);
499 }
500 return _cssClassSet;
501 }
502 707
503 void set classes(Collection<String> value) { 708 void set classes(Collection<String> value) {
504 _CssClassSet classSet = classes; 709 _CssClassSet classSet = classes;
505 classSet.clear(); 710 classSet.clear();
506 classSet.addAll(value); 711 classSet.addAll(value);
507 } 712 }
508 713
509 Map<String, String> get dataAttributes() { 714 Map<String, String> get dataAttributes() {
510 if (_dataAttributes === null) { 715 return new _DataAttributeMap(attributes);
nweiz 2012/03/30 00:06:23 =>
Jacob 2012/03/30 00:40:53 Done.
511 _dataAttributes = new _DataAttributeMap(attributes);
512 }
513 return _dataAttributes;
514 } 716 }
515 717
516 void set dataAttributes(Map<String, String> value) { 718 void set dataAttributes(Map<String, String> value) {
517 Map<String, String> dataAttributes = this.dataAttributes; 719 final dataAttributes = this.dataAttributes;
518 dataAttributes.clear(); 720 dataAttributes.clear();
519 for (String key in value.getKeys()) { 721 for (String key in value.getKeys()) {
520 dataAttributes[key] = value[key]; 722 dataAttributes[key] = value[key];
521 } 723 }
522 } 724 }
523 725
524 Future<ElementRect> get rect() { 726 Future<ElementRect> get rect() {
525 return _createMeasurementFuture( 727 return _createMeasurementFuture(
526 () => new _ElementRectImpl(this), 728 () => new _ElementRectImpl(this),
527 new Completer<ElementRect>()); 729 new Completer<ElementRect>());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 796
595 /** @domName Document.createElement */ 797 /** @domName Document.createElement */
596 $if FROG 798 $if FROG
597 // Optimization to improve performance until the frog compiler inlines this 799 // Optimization to improve performance until the frog compiler inlines this
598 // method. 800 // method.
599 factory Element.tag(String tag) native "return document.createElement(tag)"; 801 factory Element.tag(String tag) native "return document.createElement(tag)";
600 $else 802 $else
601 factory Element.tag(String tag) => _document.$dom_createElement(tag); 803 factory Element.tag(String tag) => _document.$dom_createElement(tag);
602 $endif 804 $endif
603 } 805 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698