OLD | NEW |
---|---|
1 library html; | 1 library html; |
2 | 2 |
3 import 'dart:collection'; | 3 import 'dart:collection'; |
4 import 'dart:html_common'; | 4 import 'dart:html_common'; |
5 import 'dart:indexed_db'; | 5 import 'dart:indexed_db'; |
6 import 'dart:isolate'; | 6 import 'dart:isolate'; |
7 import 'dart:json'; | 7 import 'dart:json'; |
8 import 'dart:svg' as svg; | 8 import 'dart:svg' as svg; |
9 import 'dart:web_audio' as web_audio; | 9 import 'dart:web_audio' as web_audio; |
10 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 10 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
(...skipping 7333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7344 } | 7344 } |
7345 return s; | 7345 return s; |
7346 } | 7346 } |
7347 | 7347 |
7348 void writeClasses(Set<String> s) { | 7348 void writeClasses(Set<String> s) { |
7349 List list = new List.from(s); | 7349 List list = new List.from(s); |
7350 _element.$dom_className = Strings.join(list, ' '); | 7350 _element.$dom_className = Strings.join(list, ' '); |
7351 } | 7351 } |
7352 } | 7352 } |
7353 | 7353 |
7354 /// @domName Element | 7354 /** |
7355 * An abstract class, which all HTML elements extend. | |
7356 */ | |
7355 abstract class Element extends Node implements ElementTraversal native "*Element " { | 7357 abstract class Element extends Node implements ElementTraversal native "*Element " { |
7356 | 7358 |
7359 /** | |
7360 * Creates an HTML element from a valid fragment of HTML. | |
7361 * | |
7362 * The [html] fragment must represent valid HTML with a single element root, | |
7363 * which will be parsed and returned. | |
7364 * | |
7365 * Important: the contents of [html] should not contain any user-supplied | |
7366 * data. Without strict data validation it is impossible to prevent script | |
7367 * injection exploits. | |
7368 * | |
7369 * It is instead recommended that elements be constructed via [Element.tag] | |
7370 * and text be added via [text]. | |
7371 * | |
7372 * var element = new Element.html('<div class="foo">content</div>'); | |
7373 */ | |
7357 factory Element.html(String html) => | 7374 factory Element.html(String html) => |
7358 _ElementFactoryProvider.createElement_html(html); | 7375 _ElementFactoryProvider.createElement_html(html); |
7376 | |
7377 /** | |
7378 * Creates the HTML element specified by the tag name. | |
7379 * | |
7380 * This is similar to [Document.createElement]. | |
7381 * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then | |
7382 * this will create an [UnknownElement]. | |
7383 * | |
7384 * var divElement = new Element.tag('div'); | |
7385 * print(divElement is DivElement); // 'true' | |
7386 * var myElement = new Element.tag('unknownTag'); | |
7387 * print(myElement is UnknownElement); // 'true' | |
7388 * | |
7389 * For standard elements it is more preferable to use the type constructors: | |
7390 * var element = new DivElement(); | |
7391 */ | |
7359 factory Element.tag(String tag) => | 7392 factory Element.tag(String tag) => |
7360 _ElementFactoryProvider.createElement_tag(tag); | 7393 _ElementFactoryProvider.createElement_tag(tag); |
7361 | 7394 |
7362 /** | 7395 /** |
7363 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute, | 7396 * All attributes on this element. |
7364 * Element.removeAttribute | 7397 * |
7398 * Any modifications to the attribute map will automatically be applied to | |
7399 * this element. | |
7400 * | |
7401 * This only includes attributes which are not in a namespace | |
7402 * (such as 'xlink:href'), additional attributes can be accessed via | |
7403 * [getNamespacedAttributes]. | |
7365 */ | 7404 */ |
7366 Map<String, String> get attributes => new _ElementAttributeMap(this); | 7405 Map<String, String> get attributes => new _ElementAttributeMap(this); |
7367 | 7406 |
7368 void set attributes(Map<String, String> value) { | 7407 void set attributes(Map<String, String> value) { |
7369 Map<String, String> attributes = this.attributes; | 7408 Map<String, String> attributes = this.attributes; |
7370 attributes.clear(); | 7409 attributes.clear(); |
7371 for (String key in value.keys) { | 7410 for (String key in value.keys) { |
7372 attributes[key] = value[key]; | 7411 attributes[key] = value[key]; |
7373 } | 7412 } |
7374 } | 7413 } |
(...skipping 13 matching lines...) Expand all Loading... | |
7388 this.children = value; | 7427 this.children = value; |
7389 } | 7428 } |
7390 | 7429 |
7391 /** | 7430 /** |
7392 * Deprecated, use [children] instead. | 7431 * Deprecated, use [children] instead. |
7393 */ | 7432 */ |
7394 @deprecated | 7433 @deprecated |
7395 List<Element> get elements => this.children; | 7434 List<Element> get elements => this.children; |
7396 | 7435 |
7397 /** | 7436 /** |
7398 * @domName childElementCount, firstElementChild, lastElementChild, | 7437 * List of the direct children of this element. |
7399 * children, Node.nodes.add | 7438 * |
7439 * This collection can be used to add and remove elements from the document. | |
7440 * | |
7441 * var item = new DivElement(); | |
7442 * item.text = 'Something'; | |
7443 * document.body.children.add(item) // Item is now displayed on the page. | |
7444 * for (var element in document.body.children) { | |
7445 * element.style.background = 'red'; // Turns every child of body red. | |
7446 * } | |
7400 */ | 7447 */ |
7401 List<Element> get children => new _ChildrenElementList._wrap(this); | 7448 List<Element> get children => new _ChildrenElementList._wrap(this); |
7402 | 7449 |
7403 void set children(List<Element> value) { | 7450 void set children(List<Element> value) { |
7404 // Copy list first since we don't want liveness during iteration. | 7451 // Copy list first since we don't want liveness during iteration. |
7405 List copy = new List.from(value); | 7452 List copy = new List.from(value); |
7406 var children = this.children; | 7453 var children = this.children; |
7407 children.clear(); | 7454 children.clear(); |
7408 children.addAll(copy); | 7455 children.addAll(copy); |
7409 } | 7456 } |
7410 | 7457 |
7458 /** | |
7459 * Finds the first descendant element of this element that matches the | |
7460 * specified group of selectors. | |
7461 * | |
7462 * [selectors] should be a string using CSS selector syntax. | |
7463 * | |
7464 * // Gets the first descendant with the class 'classname' | |
7465 * var element = element.query('.className'); | |
7466 * // Gets the element with id 'id' | |
7467 * var element = element.query('#id'); | |
7468 * // Gets the first descendant [ImageElement] | |
7469 * var img = element.query('img'); | |
7470 * | |
7471 * See also: | |
7472 * | |
7473 * * [CSS Selectors](http://docs.webplatform.org/wiki/css/selectors) | |
7474 */ | |
7411 Element query(String selectors) => $dom_querySelector(selectors); | 7475 Element query(String selectors) => $dom_querySelector(selectors); |
7412 | 7476 |
7477 /** | |
7478 * Finds all descendent elements of this element that match the specified | |
7479 * group of selectors. | |
7480 * | |
7481 * [selectors] should be a string using CSS selector syntax. | |
7482 * | |
7483 * var items = element.query('.itemClassName'); | |
7484 */ | |
7413 List<Element> queryAll(String selectors) => | 7485 List<Element> queryAll(String selectors) => |
7414 new _FrozenElementList._wrap($dom_querySelectorAll(selectors)); | 7486 new _FrozenElementList._wrap($dom_querySelectorAll(selectors)); |
7415 | 7487 |
7416 /** @domName className, classList */ | 7488 /** |
7489 * The set of CSS classes applied to this element. | |
7490 * | |
7491 * This set makes it easy to add, remove or toggle the classes applied to | |
7492 * this element. | |
7493 * | |
7494 * element.classes.add('selected'); | |
7495 * element.classes.toggle('isOnline'); | |
7496 * element.classes.remove('selected'); | |
7497 */ | |
7417 CssClassSet get classes => new _ElementCssClassSet(this); | 7498 CssClassSet get classes => new _ElementCssClassSet(this); |
7418 | 7499 |
7419 void set classes(Collection<String> value) { | 7500 void set classes(Collection<String> value) { |
7420 CssClassSet classSet = classes; | 7501 CssClassSet classSet = classes; |
7421 classSet.clear(); | 7502 classSet.clear(); |
7422 classSet.addAll(value); | 7503 classSet.addAll(value); |
7423 } | 7504 } |
7424 | 7505 |
7506 /** | |
7507 * Allows access to all custom data attributes (data-*) set on this element. | |
7508 * | |
7509 * The keys for the map must follow these rules: | |
7510 * | |
7511 * * The name must not begin with 'xml'. | |
7512 * * The name cannot contain a semi-colon (`;`). | |
Andrei Mouravski
2012/12/12 20:32:19
Quotes here, too.
blois
2012/12/12 20:34:35
Done.
| |
7513 * * The name cannot contain any capital letters. | |
7514 * | |
7515 * Any keys from markup will be converted to camel-cased keys in the map. | |
7516 * | |
7517 * For example, HTML specified as: | |
7518 * | |
7519 * <div data-my-random-value='value'></div> | |
7520 * | |
7521 * Would be accessed in Dart as: | |
7522 * | |
7523 * var value = element.dataAttributes['myRandomValue']; | |
7524 * | |
7525 * See also: | |
7526 * | |
7527 * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.htm l#custom-data-attribute) | |
7528 */ | |
7425 Map<String, String> get dataAttributes => | 7529 Map<String, String> get dataAttributes => |
7426 new _DataAttributeMap(attributes); | 7530 new _DataAttributeMap(attributes); |
7427 | 7531 |
7428 void set dataAttributes(Map<String, String> value) { | 7532 void set dataAttributes(Map<String, String> value) { |
7429 final dataAttributes = this.dataAttributes; | 7533 final dataAttributes = this.dataAttributes; |
7430 dataAttributes.clear(); | 7534 dataAttributes.clear(); |
7431 for (String key in value.keys) { | 7535 for (String key in value.keys) { |
7432 dataAttributes[key] = value[key]; | 7536 dataAttributes[key] = value[key]; |
7433 } | 7537 } |
7434 } | 7538 } |
7435 | 7539 |
7436 /** | 7540 /** |
7437 * Gets a map for manipulating the attributes of a particular namespace. | 7541 * Gets a map for manipulating the attributes of a particular namespace. |
7542 * | |
7438 * This is primarily useful for SVG attributes such as xref:link. | 7543 * This is primarily useful for SVG attributes such as xref:link. |
7439 */ | 7544 */ |
7440 Map<String, String> getNamespacedAttributes(String namespace) { | 7545 Map<String, String> getNamespacedAttributes(String namespace) { |
7441 return new _NamespacedAttributeMap(this, namespace); | 7546 return new _NamespacedAttributeMap(this, namespace); |
7442 } | 7547 } |
7443 | 7548 |
7444 /** @domName Window.getComputedStyle */ | 7549 /** |
7550 * The set of all CSS values applied to this element, including inherited | |
7551 * and default values. | |
7552 * | |
7553 * The computedStyle contains values that are inherited from other | |
7554 * sources, such as parent elements or stylesheets. This differs from the | |
7555 * [style] property, which contains only the values specified directly on this | |
7556 * element. | |
7557 * | |
7558 * See also: | |
7559 * | |
7560 * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/ inheritance_and_cascade) | |
7561 */ | |
7445 Future<CssStyleDeclaration> get computedStyle { | 7562 Future<CssStyleDeclaration> get computedStyle { |
7446 // TODO(jacobr): last param should be null, see b/5045788 | 7563 // TODO(jacobr): last param should be null, see b/5045788 |
7447 return getComputedStyle(''); | 7564 return getComputedStyle(''); |
7448 } | 7565 } |
7449 | 7566 |
7450 /** @domName Window.getComputedStyle */ | 7567 /** |
7568 * Returns the computed styles for pseudo-elements such as `::after`, | |
7569 * `::before`, `::marker`, `::line-marker`. | |
7570 * | |
7571 * See also: | |
7572 * | |
7573 * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-e lements) | |
7574 */ | |
7451 Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) { | 7575 Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) { |
7452 return _createMeasurementFuture( | 7576 return _createMeasurementFuture( |
7453 () => window.$dom_getComputedStyle(this, pseudoElement), | 7577 () => window.$dom_getComputedStyle(this, pseudoElement), |
7454 new Completer<CssStyleDeclaration>()); | 7578 new Completer<CssStyleDeclaration>()); |
7455 } | 7579 } |
7456 | 7580 |
7457 /** | 7581 /** |
7458 * Adds the specified element to after the last child of this. | 7582 * Adds the specified element to after the last child of this element. |
7459 */ | 7583 */ |
7460 void append(Element e) { | 7584 void append(Element e) { |
7461 this.children.add(e); | 7585 this.children.add(e); |
7462 } | 7586 } |
7463 | 7587 |
7464 /** | 7588 /** |
7465 * Adds the specified text as a text node after the last child of this. | 7589 * Adds the specified text as a text node after the last child of this |
7590 * element. | |
7466 */ | 7591 */ |
7467 void appendText(String text) { | 7592 void appendText(String text) { |
7468 this.insertAdjacentText('beforeend', text); | 7593 this.insertAdjacentText('beforeend', text); |
7469 } | 7594 } |
7470 | 7595 |
7471 /** | 7596 /** |
7472 * Parses the specified text as HTML and adds the resulting node after the | 7597 * Parses the specified text as HTML and adds the resulting node after the |
7473 * last child of this. | 7598 * last child of this element. |
7474 */ | 7599 */ |
7475 void appendHtml(String text) { | 7600 void appendHtml(String text) { |
7476 this.insertAdjacentHtml('beforeend', text); | 7601 this.insertAdjacentHtml('beforeend', text); |
7477 } | 7602 } |
7478 | 7603 |
7479 // Hooks to support custom WebComponents. | 7604 // Hooks to support custom WebComponents. |
7480 /** | 7605 /** |
7481 * Experimental support for [web components][wc]. This field stores a | 7606 * Experimental support for [web components][wc]. This field stores a |
7482 * reference to the component implementation. It was inspired by Mozilla's | 7607 * reference to the component implementation. It was inspired by Mozilla's |
7483 * [x-tags][] project. Please note: in the future it may be possible to | 7608 * [x-tags][] project. Please note: in the future it may be possible to |
7484 * `extend Element` from your class, in which case this field will be | 7609 * `extend Element` from your class, in which case this field will be |
7485 * deprecated and will simply return this [Element] object. | 7610 * deprecated and will simply return this [Element] object. |
7486 * | 7611 * |
7487 * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html | 7612 * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html |
7488 * [x-tags]: http://x-tags.org/ | 7613 * [x-tags]: http://x-tags.org/ |
7489 */ | 7614 */ |
7490 @Creates('Null') // Set from Dart code; does not instantiate a native type. | 7615 @Creates('Null') // Set from Dart code; does not instantiate a native type. |
7491 var xtag; | 7616 var xtag; |
7492 | 7617 |
7493 // TODO(vsm): Implement noSuchMethod or similar for dart2js. | 7618 // TODO(vsm): Implement noSuchMethod or similar for dart2js. |
7494 | 7619 |
7495 /** @domName Element.insertAdjacentText */ | 7620 /** |
7621 * Creates a text node and inserts it into the DOM at the specified location. | |
7622 * | |
7623 * To see the possible values for [where], read the doc for | |
7624 * [insertAdjacentHtml]. | |
7625 * | |
7626 * See also: | |
7627 * | |
7628 * * [insertAdjacentHtml] | |
7629 */ | |
7496 void insertAdjacentText(String where, String text) { | 7630 void insertAdjacentText(String where, String text) { |
7497 if (JS('bool', '!!#.insertAdjacentText', this)) { | 7631 if (JS('bool', '!!#.insertAdjacentText', this)) { |
7498 _insertAdjacentText(where, text); | 7632 _insertAdjacentText(where, text); |
7499 } else { | 7633 } else { |
7500 _insertAdjacentNode(where, new Text(text)); | 7634 _insertAdjacentNode(where, new Text(text)); |
7501 } | 7635 } |
7502 } | 7636 } |
7503 | 7637 |
7504 @JSName('insertAdjacentText') | 7638 @JSName('insertAdjacentText') |
7505 void _insertAdjacentText(String where, String text) native; | 7639 void _insertAdjacentText(String where, String text) native; |
7506 | 7640 |
7507 /** @domName Element.insertAdjacentHTML */ | 7641 /** |
7642 * Parses text as an HTML fragment and inserts it into the DOM at the | |
7643 * specified location. | |
7644 * | |
7645 * The [where] parameter indicates where to insert the HTML fragment: | |
7646 * | |
7647 * * 'beforeBegin': Immediately before this element. | |
7648 * * 'afterBegin': As the first child of this element. | |
7649 * * 'beforeEnd': As the last child of this element. | |
7650 * * 'afterEnd': Immediately after this element. | |
7651 * | |
7652 * var html = '<div class="something">content</div>'; | |
7653 * // Inserts as the first child | |
7654 * document.body.insertAdjacentHtml('afterBegin', html); | |
7655 * var createdElement = document.body.children[0]; | |
7656 * print(createdElement.classes[0]); // Prints 'something' | |
7657 * | |
7658 * See also: | |
7659 * | |
7660 * * [insertAdjacentText] | |
7661 * * [insertAdjacentElement] | |
7662 */ | |
7508 void insertAdjacentHtml(String where, String text) { | 7663 void insertAdjacentHtml(String where, String text) { |
7509 if (JS('bool', '!!#.insertAdjacentHtml', this)) { | 7664 if (JS('bool', '!!#.insertAdjacentHtml', this)) { |
7510 _insertAdjacentHtml(where, text); | 7665 _insertAdjacentHtml(where, text); |
7511 } else { | 7666 } else { |
7512 _insertAdjacentNode(where, new DocumentFragment.html(text)); | 7667 _insertAdjacentNode(where, new DocumentFragment.html(text)); |
7513 } | 7668 } |
7514 } | 7669 } |
7515 | 7670 |
7516 @JSName('insertAdjacentHTML') | 7671 @JSName('insertAdjacentHTML') |
7517 void _insertAdjacentHTML(String where, String text) native; | 7672 void _insertAdjacentHTML(String where, String text) native; |
7518 | 7673 |
7519 /** @domName Element.insertAdjacentHTML */ | 7674 /** |
7675 * Inserts [element] into the DOM at the specified location. | |
7676 * | |
7677 * To see the possible values for [where], read the doc for | |
7678 * [insertAdjacentHtml]. | |
7679 * | |
7680 * See also: | |
7681 * | |
7682 * * [insertAdjacentHtml] | |
7683 */ | |
7520 Element insertAdjacentElement(String where, Element element) { | 7684 Element insertAdjacentElement(String where, Element element) { |
7521 if (JS('bool', '!!#.insertAdjacentElement', this)) { | 7685 if (JS('bool', '!!#.insertAdjacentElement', this)) { |
7522 _insertAdjacentElement(where, element); | 7686 _insertAdjacentElement(where, element); |
7523 } else { | 7687 } else { |
7524 _insertAdjacentNode(where, element); | 7688 _insertAdjacentNode(where, element); |
7525 } | 7689 } |
7526 return element; | 7690 return element; |
7527 } | 7691 } |
7528 | 7692 |
7529 @JSName('insertAdjacentElement') | 7693 @JSName('insertAdjacentElement') |
(...skipping 18173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
25703 T next() { | 25867 T next() { |
25704 if (!hasNext) { | 25868 if (!hasNext) { |
25705 throw new StateError("No more elements"); | 25869 throw new StateError("No more elements"); |
25706 } | 25870 } |
25707 return _array[_pos++]; | 25871 return _array[_pos++]; |
25708 } | 25872 } |
25709 | 25873 |
25710 final List<T> _array; | 25874 final List<T> _array; |
25711 int _pos; | 25875 int _pos; |
25712 } | 25876 } |
OLD | NEW |