| OLD | NEW |
| 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 part of $LIBRARYNAME; | 5 part of $LIBRARYNAME; |
| 6 | 6 |
| 7 class _ChildrenElementList extends ListBase<Element> | 7 class _ChildrenElementList extends ListBase<Element> |
| 8 implements NodeListWrapper { | 8 implements NodeListWrapper { |
| 9 // Raw Element. | 9 // Raw Element. |
| 10 final Element _element; | 10 final Element _element; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 * | 373 * |
| 374 * class CustomElement extends Element { | 374 * class CustomElement extends Element { |
| 375 * factory CustomElement() => new Element.tag('x-custom'); | 375 * factory CustomElement() => new Element.tag('x-custom'); |
| 376 * | 376 * |
| 377 * CustomElement.created() : super.created() { | 377 * CustomElement.created() : super.created() { |
| 378 * // Perform any element initialization. | 378 * // Perform any element initialization. |
| 379 * } | 379 * } |
| 380 * } | 380 * } |
| 381 * document.registerElement('x-custom', CustomElement); | 381 * document.registerElement('x-custom', CustomElement); |
| 382 */ | 382 */ |
| 383 $if DART2JS |
| 383 Element.created() : super._created(); | 384 Element.created() : super._created(); |
| 385 $else |
| 386 Element.created() : super._created() { |
| 387 // Validate that this is a custom element & possibly perform additional |
| 388 // initialization. |
| 389 _blink.Blink_Utils.initializeCustomElement(this); |
| 390 } |
| 391 $endif |
| 384 | 392 |
| 385 /** | 393 /** |
| 386 * Creates the HTML element specified by the tag name. | 394 * Creates the HTML element specified by the tag name. |
| 387 * | 395 * |
| 388 * This is similar to [Document.createElement]. | 396 * This is similar to [Document.createElement]. |
| 389 * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then | 397 * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then |
| 390 * this will create an [UnknownElement]. | 398 * this will create an [UnknownElement]. |
| 391 * | 399 * |
| 392 * var divElement = new Element.tag('div'); | 400 * var divElement = new Element.tag('div'); |
| 393 * print(divElement is DivElement); // 'true' | 401 * print(divElement is DivElement); // 'true' |
| (...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 /// A secondary check for corruption, needed on IE | 1484 /// A secondary check for corruption, needed on IE |
| 1477 static bool _hasCorruptedAttributesAdditionalCheck(Element element) { | 1485 static bool _hasCorruptedAttributesAdditionalCheck(Element element) { |
| 1478 return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element); | 1486 return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element); |
| 1479 } | 1487 } |
| 1480 $else | 1488 $else |
| 1481 | 1489 |
| 1482 static var _namedNodeMap = js.context["NamedNodeMap"]; | 1490 static var _namedNodeMap = js.context["NamedNodeMap"]; |
| 1483 static var _htmlCollection = js.context["HTMLCollection"]; | 1491 static var _htmlCollection = js.context["HTMLCollection"]; |
| 1484 static var _nodeList = js.context["NodeList"]; | 1492 static var _nodeList = js.context["NodeList"]; |
| 1485 | 1493 |
| 1494 static const _evilAttributeNames = |
| 1495 const ['attributes', 'lastChild', 'children', 'childNodes']; |
| 1496 |
| 1486 static bool _hasCorruptedAttributes(Element element) { | 1497 static bool _hasCorruptedAttributes(Element element) { |
| 1487 var attributes = unwrap_jso(element)["attributes"]; | 1498 // We have trusted access to children and to attributes of objects, |
| 1488 if (!attributes.instanceof(_namedNodeMap)) { | 1499 // so we can inspect directly for attempts at DOM clobbering. |
| 1489 return true; | 1500 var child = element.firstChild; |
| 1490 } | 1501 while( child != null) { |
| 1491 var childNodes = unwrap_jso(element.childNodes); | 1502 if (child is Element) { |
| 1492 var length = childNodes["length"]; | 1503 for (var attributeName in ["id", "name"]) { |
| 1493 var lastChild = unwrap_jso(element.lastChild); | 1504 var childAttribute = child.getAttribute(attributeName); |
| 1494 if (null != lastChild && | 1505 if (_evilAttributeNames.contains(childAttribute)) return true; |
| 1495 lastChild != childNodes[length - 1]) { | 1506 }} |
| 1496 return true; | 1507 child = child.nextNode; |
| 1497 } | |
| 1498 var children = unwrap_jso(element._children); | |
| 1499 if (null != children) { // On Safari, children can apparently be null. | |
| 1500 if (!children.instanceof(_htmlCollection) || | |
| 1501 children.instanceof(_nodeList)) { | |
| 1502 » return true; | |
| 1503 } | |
| 1504 } | 1508 } |
| 1505 return false; | 1509 return false; |
| 1506 } | 1510 } |
| 1507 | 1511 |
| 1508 /// A secondary check for corruption, needed on IE | 1512 /// A secondary check for corruption, needed on IE |
| 1509 static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false; | 1513 static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false; |
| 1510 $endif | 1514 $endif |
| 1511 | 1515 |
| 1516 $if DART2JS |
| 1512 static String _safeTagName(element) { | 1517 static String _safeTagName(element) { |
| 1513 String result = 'element tag unavailable'; | 1518 String result = 'element tag unavailable'; |
| 1514 try { | 1519 try { |
| 1515 if (element.tagName is String) { | 1520 if (element.tagName is String) { |
| 1516 result = element.tagName; | 1521 result = element.tagName; |
| 1517 } | 1522 } |
| 1518 } catch (e) {} | 1523 } catch (e) {} |
| 1519 return result; | 1524 return result; |
| 1520 } | 1525 } |
| 1526 $else |
| 1527 static String _safeTagName(element) { |
| 1528 try { |
| 1529 // Safe as we plumb directly to a C++ native method. |
| 1530 return element.tagName; |
| 1531 } catch (e) {} |
| 1532 return 'element tag unavailable'; |
| 1533 } |
| 1534 $endif |
| 1521 | 1535 |
| 1522 $if DART2JS | 1536 $if DART2JS |
| 1523 @DomName('Element.offsetParent') | 1537 @DomName('Element.offsetParent') |
| 1524 @DocsEditable() | 1538 @DocsEditable() |
| 1525 final Element offsetParent; | 1539 final Element offsetParent; |
| 1526 | 1540 |
| 1527 @DomName('Element.offsetHeight') | 1541 @DomName('Element.offsetHeight') |
| 1528 @DocsEditable() | 1542 @DocsEditable() |
| 1529 int get offsetHeight => JS('num', '#.offsetHeight', this).round(); | 1543 int get offsetHeight => JS('num', '#.offsetHeight', this).round(); |
| 1530 | 1544 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1563 set scrollTop(int value) { | 1577 set scrollTop(int value) { |
| 1564 JS("void", "#.scrollTop = #", this, value.round()); | 1578 JS("void", "#.scrollTop = #", this, value.round()); |
| 1565 } | 1579 } |
| 1566 | 1580 |
| 1567 @DomName('Element.scrollWidth') | 1581 @DomName('Element.scrollWidth') |
| 1568 @DocsEditable() | 1582 @DocsEditable() |
| 1569 int get scrollWidth => JS('num', '#.scrollWidth', this).round(); | 1583 int get scrollWidth => JS('num', '#.scrollWidth', this).round(); |
| 1570 | 1584 |
| 1571 $else | 1585 $else |
| 1572 // Need to explicitly delegate because Element is no longer abstract for Darti
um. | 1586 // Need to explicitly delegate because Element is no longer abstract for Darti
um. |
| 1573 bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditab
le_Getter_(unwrap_jso(this)); | 1587 bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditab
le_Getter_(this); |
| 1574 void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso(
this)); | 1588 void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(this); |
| 1575 | 1589 |
| 1576 @DomName('Element.offsetParent') | 1590 @DomName('Element.offsetParent') |
| 1577 @DocsEditable() | 1591 @DocsEditable() |
| 1578 Element get offsetParent => wrap_jso(_blink.BlinkElement.instance.offsetParent
_Getter_(unwrap_jso(this))); | 1592 Element get offsetParent => _blink.BlinkElement.instance.offsetParent_Getter_(
this); |
| 1579 | 1593 |
| 1580 @DomName('Element.offsetHeight') | 1594 @DomName('Element.offsetHeight') |
| 1581 @DocsEditable() | 1595 @DocsEditable() |
| 1582 int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwr
ap_jso(this)); | 1596 int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(this
); |
| 1583 | 1597 |
| 1584 @DomName('Element.offsetLeft') | 1598 @DomName('Element.offsetLeft') |
| 1585 @DocsEditable() | 1599 @DocsEditable() |
| 1586 int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_j
so(this)); | 1600 int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(this); |
| 1587 | 1601 |
| 1588 @DomName('Element.offsetTop') | 1602 @DomName('Element.offsetTop') |
| 1589 @DocsEditable() | 1603 @DocsEditable() |
| 1590 int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(unwrap_jso
(this)); | 1604 int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(this); |
| 1591 | 1605 |
| 1592 @DomName('Element.offsetWidth') | 1606 @DomName('Element.offsetWidth') |
| 1593 @DocsEditable() | 1607 @DocsEditable() |
| 1594 int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(unwrap
_jso(this)); | 1608 int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(this); |
| 1595 | 1609 |
| 1596 @DomName('Element.scrollHeight') | 1610 @DomName('Element.scrollHeight') |
| 1597 @DocsEditable() | 1611 @DocsEditable() |
| 1598 int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwr
ap_jso(this)).round(); | 1612 int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(this
).round(); |
| 1599 | 1613 |
| 1600 @DomName('Element.scrollLeft') | 1614 @DomName('Element.scrollLeft') |
| 1601 @DocsEditable() | 1615 @DocsEditable() |
| 1602 int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_j
so(this)).round(); | 1616 int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(this).ro
und(); |
| 1603 | 1617 |
| 1604 @DomName('Element.scrollLeft') | 1618 @DomName('Element.scrollLeft') |
| 1605 @DocsEditable() | 1619 @DocsEditable() |
| 1606 set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(u
nwrap_jso(this), value.round()); | 1620 set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(t
his, value.round()); |
| 1607 | 1621 |
| 1608 @DomName('Element.scrollTop') | 1622 @DomName('Element.scrollTop') |
| 1609 @DocsEditable() | 1623 @DocsEditable() |
| 1610 int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso
(this)).round(); | 1624 int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(this).roun
d(); |
| 1611 | 1625 |
| 1612 @DomName('Element.scrollTop') | 1626 @DomName('Element.scrollTop') |
| 1613 @DocsEditable() | 1627 @DocsEditable() |
| 1614 set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(unw
rap_jso(this), value.round()); | 1628 set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(thi
s, value.round()); |
| 1615 | 1629 |
| 1616 @DomName('Element.scrollWidth') | 1630 @DomName('Element.scrollWidth') |
| 1617 @DocsEditable() | 1631 @DocsEditable() |
| 1618 int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap
_jso(this)).round(); | 1632 int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(this).
round(); |
| 1619 $endif | 1633 $endif |
| 1620 | 1634 |
| 1621 $!MEMBERS | 1635 $!MEMBERS |
| 1622 } | 1636 } |
| 1623 | 1637 |
| 1624 | 1638 |
| 1625 class _ElementFactoryProvider { | 1639 class _ElementFactoryProvider { |
| 1626 | 1640 |
| 1627 @DomName('Document.createElement') | 1641 @DomName('Document.createElement') |
| 1628 $if DART2JS | 1642 $if DART2JS |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1656 const ScrollAlignment._internal(this._value); | 1670 const ScrollAlignment._internal(this._value); |
| 1657 toString() => 'ScrollAlignment.$_value'; | 1671 toString() => 'ScrollAlignment.$_value'; |
| 1658 | 1672 |
| 1659 /// Attempt to align the element to the top of the scrollable area. | 1673 /// Attempt to align the element to the top of the scrollable area. |
| 1660 static const TOP = const ScrollAlignment._internal('TOP'); | 1674 static const TOP = const ScrollAlignment._internal('TOP'); |
| 1661 /// Attempt to center the element in the scrollable area. | 1675 /// Attempt to center the element in the scrollable area. |
| 1662 static const CENTER = const ScrollAlignment._internal('CENTER'); | 1676 static const CENTER = const ScrollAlignment._internal('CENTER'); |
| 1663 /// Attempt to align the element to the bottom of the scrollable area. | 1677 /// Attempt to align the element to the bottom of the scrollable area. |
| 1664 static const BOTTOM = const ScrollAlignment._internal('BOTTOM'); | 1678 static const BOTTOM = const ScrollAlignment._internal('BOTTOM'); |
| 1665 } | 1679 } |
| OLD | NEW |