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

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: Code review fixes 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 $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
421 }
422
423 String remove(String key) => $dom_attributes.remove(_attr(key));
424
425 void clear() {
426 // Needs to operate on a snapshot since we are mutating the collection.
427 for (String key in getKeys()) {
428 remove(key);
429 }
430 }
431
432 void forEach(void f(String key, String value)) {
433 $dom_attributes.forEach((String key, String value) {
434 if (_matches(key)) {
435 f(_strip(key), value);
436 }
437 });
438 }
439
440 Collection<String> getKeys() {
441 final keys = new List<String>();
442 $dom_attributes.forEach((String key, String value) {
443 if (_matches(key)) {
444 keys.add(_strip(key));
445 }
446 });
447 return keys;
448 }
449
450 Collection<String> getValues() {
451 final values = new List<String>();
452 $dom_attributes.forEach((String key, String value) {
453 if (_matches(key)) {
454 values.add(value);
455 }
456 });
457 return values;
458 }
459
460 int get length() => getKeys().length;
461
462 // TODO: Use lazy iterator when it is available on Map.
463 bool isEmpty() => length == 0;
464
465 // Helpers.
466 String _attr(String key) => 'data-$key';
467 bool _matches(String key) => key.startsWith('data-');
468 String _strip(String key) => key.substring(5);
469 }
470
471 class _CssClassSet implements Set<String> {
472
473 final _ElementImpl _element;
474
475 _CssClassSet(this._element);
476
477 String toString() => _formatSet(_read());
478
479 // interface Iterable - BEGIN
480 Iterator<String> iterator() => _read().iterator();
481 // interface Iterable - END
482
483 // interface Collection - BEGIN
484 void forEach(void f(String element)) {
485 _read().forEach(f);
486 }
487
488 Collection map(f(String element)) => _read().map(f);
489
490 Collection<String> filter(bool f(String element)) => _read().filter(f);
491
492 bool every(bool f(String element)) => _read().every(f);
493
494 bool some(bool f(String element)) => _read().some(f);
495
496 bool isEmpty() => _read().isEmpty();
497
498 int get length() =>_read().length;
499
500 // interface Collection - END
501
502 // interface Set - BEGIN
503 bool contains(String value) => _read().contains(value);
504
505 void add(String value) {
506 // TODO - figure out if we need to do any validation here
507 // or if the browser natively does enough
508 _modify((s) => s.add(value));
509 }
510
511 bool remove(String value) {
512 Set<String> s = _read();
513 bool result = s.remove(value);
514 _write(s);
515 return result;
516 }
517
518 void addAll(Collection<String> collection) {
519 // TODO - see comment above about validation
520 _modify((s) => s.addAll(collection));
521 }
522
523 void removeAll(Collection<String> collection) {
524 _modify((s) => s.removeAll(collection));
525 }
526
527 bool isSubsetOf(Collection<String> collection) =>
528 _read().isSubsetOf(collection);
529
530 bool containsAll(Collection<String> collection) =>
531 _read().containsAll(collection);
532
533 Set<String> intersection(Collection<String> other) =>
534 _read().intersection(other);
535
536 void clear() {
537 _modify((s) => s.clear());
538 }
539 // interface Set - END
540
541 /**
542 * Helper method used to modify the set of css classes on this element.
543 *
544 * f - callback with:
545 * s - a Set of all the css class name currently on this element.
546 *
547 * After f returns, the modified set is written to the
548 * className property of this element.
549 */
550 void _modify( f(Set<String> s)) {
551 Set<String> s = _read();
552 f(s);
553 _write(s);
554 }
555
556 /**
557 * Read the class names from the Element class property,
558 * and put them into a set (duplicates are discarded).
559 */
560 Set<String> _read() {
561 // TODO(mattsh) simplify this once split can take regex.
562 Set<String> s = new Set<String>();
563 for (String name in _classname().split(' ')) {
564 String trimmed = name.trim();
565 if (!trimmed.isEmpty()) {
566 s.add(trimmed);
567 }
568 }
569 return s;
570 }
571
572 /**
573 * Read the class names as a space-separated string. This is meant to be
574 * overridden by subclasses.
575 */
576 String _classname() => _element.$dom_className;
577
578 /**
579 * Join all the elements of a set into one string and write
580 * back to the element.
581 */
582 void _write(Set s) {
583 _element.$dom_className = _formatSet(s);
584 }
585
586 String _formatSet(Set<String> s) {
587 // TODO(mattsh) should be able to pass Set to String.joins http:/b/5398605
588 List list = new List.from(s);
589 return Strings.join(list, ' ');
590 }
591 }
592
396 class _SimpleClientRect implements ClientRect { 593 class _SimpleClientRect implements ClientRect {
397 final num left; 594 final num left;
398 final num top; 595 final num top;
399 final num width; 596 final num width;
400 final num height; 597 final num height;
401 num get right() => left + width; 598 num get right() => left + width;
402 num get bottom() => top + height; 599 num get bottom() => top + height;
403 600
404 const _SimpleClientRect(this.left, this.top, this.width, this.height); 601 const _SimpleClientRect(this.left, this.top, this.width, this.height);
405 602
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 final out = new List(_clientRects.length); 648 final out = new List(_clientRects.length);
452 for (num i = 0; i < _clientRects.length; i++) { 649 for (num i = 0; i < _clientRects.length; i++) {
453 out[i] = _clientRects.item(i); 650 out[i] = _clientRects.item(i);
454 } 651 }
455 return out; 652 return out;
456 } 653 }
457 } 654 }
458 655
459 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { 656 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
460 657
461 // TODO(jacobr): caching these may hurt performance.
462 ElementAttributeMap _elementAttributeMap;
463 _CssClassSet _cssClassSet;
464 _DataAttributeMap _dataAttributes;
465
466 /** 658 /**
467 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute, 659 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute,
468 * Element.removeAttribute 660 * Element.removeAttribute
469 */ 661 */
470 Map<String, String> get attributes() { 662 _ElementAttributeMap get attributes() => new _ElementAttributeMap(this);
471 if (_elementAttributeMap === null) {
472 _elementAttributeMap = new ElementAttributeMap._wrap(this);
473 }
474 return _elementAttributeMap;
475 }
476 663
477 void set attributes(Map<String, String> value) { 664 void set attributes(Map<String, String> value) {
478 Map<String, String> attributes = this.attributes; 665 Map<String, String> attributes = this.attributes;
479 attributes.clear(); 666 attributes.clear();
480 for (String key in value.getKeys()) { 667 for (String key in value.getKeys()) {
481 attributes[key] = value[key]; 668 attributes[key] = value[key];
482 } 669 }
483 } 670 }
484 671
485 void set elements(Collection<Element> value) { 672 void set elements(Collection<Element> value) {
486 final elements = this.elements; 673 final elements = this.elements;
487 elements.clear(); 674 elements.clear();
488 elements.addAll(value); 675 elements.addAll(value);
489 } 676 }
490 677
491 ElementList get elements() => new _ChildrenElementList._wrap(this); 678 ElementList get elements() => new _ChildrenElementList._wrap(this);
492 679
493 ElementList queryAll(String selectors) => 680 ElementList queryAll(String selectors) =>
494 new _FrozenElementList._wrap($dom_querySelectorAll(selectors)); 681 new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
495 682
496 Set<String> get classes() { 683 _CssClassSet get classes() => new _CssClassSet(this);
497 if (_cssClassSet === null) {
498 _cssClassSet = new _CssClassSet(this);
499 }
500 return _cssClassSet;
501 }
502 684
503 void set classes(Collection<String> value) { 685 void set classes(Collection<String> value) {
504 _CssClassSet classSet = classes; 686 _CssClassSet classSet = classes;
505 classSet.clear(); 687 classSet.clear();
506 classSet.addAll(value); 688 classSet.addAll(value);
507 } 689 }
508 690
509 Map<String, String> get dataAttributes() { 691 Map<String, String> get dataAttributes() =>
510 if (_dataAttributes === null) { 692 new _DataAttributeMap(attributes);
511 _dataAttributes = new _DataAttributeMap(attributes);
512 }
513 return _dataAttributes;
514 }
515 693
516 void set dataAttributes(Map<String, String> value) { 694 void set dataAttributes(Map<String, String> value) {
517 Map<String, String> dataAttributes = this.dataAttributes; 695 final dataAttributes = this.dataAttributes;
518 dataAttributes.clear(); 696 dataAttributes.clear();
519 for (String key in value.getKeys()) { 697 for (String key in value.getKeys()) {
520 dataAttributes[key] = value[key]; 698 dataAttributes[key] = value[key];
521 } 699 }
522 } 700 }
523 701
524 Future<ElementRect> get rect() { 702 Future<ElementRect> get rect() {
525 return _createMeasurementFuture( 703 return _createMeasurementFuture(
526 () => new _ElementRectImpl(this), 704 () => new _ElementRectImpl(this),
527 new Completer<ElementRect>()); 705 new Completer<ElementRect>());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 772
595 /** @domName Document.createElement */ 773 /** @domName Document.createElement */
596 $if FROG 774 $if FROG
597 // Optimization to improve performance until the frog compiler inlines this 775 // Optimization to improve performance until the frog compiler inlines this
598 // method. 776 // method.
599 factory Element.tag(String tag) native "return document.createElement(tag)"; 777 factory Element.tag(String tag) native "return document.createElement(tag)";
600 $else 778 $else
601 factory Element.tag(String tag) => _document.$dom_createElement(tag); 779 factory Element.tag(String tag) => _document.$dom_createElement(tag);
602 $endif 780 $endif
603 } 781 }
OLDNEW
« no previous file with comments | « client/tests/client/html/ElementTests.dart ('k') | lib/dom/templates/html/interface/interface_Element.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698