| 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 // Raw Element. | 8 // Raw Element. |
| 9 final Element _element; | 9 final Element _element; |
| 10 final HtmlCollection _childElements; | 10 final HtmlCollection _childElements; |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 bool matchesWithAncestors(String selectors) { | 974 bool matchesWithAncestors(String selectors) { |
| 975 var elem = this; | 975 var elem = this; |
| 976 do { | 976 do { |
| 977 if (elem.matches(selectors)) return true; | 977 if (elem.matches(selectors)) return true; |
| 978 elem = elem.parent; | 978 elem = elem.parent; |
| 979 } while(elem != null); | 979 } while(elem != null); |
| 980 return false; | 980 return false; |
| 981 } | 981 } |
| 982 | 982 |
| 983 $if DART2JS | 983 $if DART2JS |
| 984 @Creates('Null') // Set from Dart code; does not instantiate a native type. | |
| 985 $endif | |
| 986 Element _templateInstanceRef; | |
| 987 | |
| 988 // Note: only used if `this is! TemplateElement` | |
| 989 $if DART2JS | |
| 990 @Creates('Null') // Set from Dart code; does not instantiate a native type. | |
| 991 $endif | |
| 992 DocumentFragment _templateContent; | |
| 993 | |
| 994 bool _templateIsDecorated; | |
| 995 | |
| 996 $if DART2JS | |
| 997 @DomName('Element.createShadowRoot') | 984 @DomName('Element.createShadowRoot') |
| 998 @SupportedBrowser(SupportedBrowser.CHROME, '25') | 985 @SupportedBrowser(SupportedBrowser.CHROME, '25') |
| 999 @Experimental() | 986 @Experimental() |
| 1000 ShadowRoot createShadowRoot() { | 987 ShadowRoot createShadowRoot() { |
| 1001 return JS('ShadowRoot', | 988 return JS('ShadowRoot', |
| 1002 '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)', | 989 '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)', |
| 1003 this, this, this); | 990 this, this, this); |
| 1004 } | 991 } |
| 1005 | 992 |
| 1006 @DomName('Element.shadowRoot') | 993 @DomName('Element.shadowRoot') |
| 1007 @SupportedBrowser(SupportedBrowser.CHROME, '25') | 994 @SupportedBrowser(SupportedBrowser.CHROME, '25') |
| 1008 @Experimental() | 995 @Experimental() |
| 1009 ShadowRoot get shadowRoot => | 996 ShadowRoot get shadowRoot => |
| 1010 JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this); | 997 JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this); |
| 1011 $endif | 998 $endif |
| 1012 | 999 |
| 1013 | |
| 1014 /** | |
| 1015 * Gets the template this node refers to. | |
| 1016 * This is only supported if [isTemplate] is true. | |
| 1017 */ | |
| 1018 @Experimental() | |
| 1019 Element get ref { | |
| 1020 _ensureTemplate(); | |
| 1021 | |
| 1022 Element result = null; | |
| 1023 var refId = attributes['ref']; | |
| 1024 if (refId != null) { | |
| 1025 var treeScope = this; | |
| 1026 while (treeScope.parentNode != null) { | |
| 1027 treeScope = treeScope.parentNode; | |
| 1028 } | |
| 1029 | |
| 1030 // Note: JS code tests that getElementById is present. We can't do that | |
| 1031 // easily, so instead check for the types known to implement it. | |
| 1032 if (treeScope is Document || | |
| 1033 treeScope is ShadowRoot || | |
| 1034 treeScope is svg.SvgSvgElement) { | |
| 1035 | |
| 1036 result = treeScope.getElementById(refId); | |
| 1037 } | |
| 1038 } | |
| 1039 | |
| 1040 if (result == null) { | |
| 1041 result = _templateInstanceRef; | |
| 1042 if (result == null) return this; | |
| 1043 } | |
| 1044 | |
| 1045 var nextRef = result.ref; | |
| 1046 return nextRef != null ? nextRef : result; | |
| 1047 } | |
| 1048 | |
| 1049 /** | |
| 1050 * Gets the content of this template. | |
| 1051 * This is only supported if [isTemplate] is true. | |
| 1052 */ | |
| 1053 @Experimental() | |
| 1054 DocumentFragment get content { | |
| 1055 _ensureTemplate(); | |
| 1056 return _templateContent; | |
| 1057 } | |
| 1058 | |
| 1059 /** | |
| 1060 * Creates an instance of the template, using the provided model and optional | |
| 1061 * binding delegate. | |
| 1062 * | |
| 1063 * This is only supported if [isTemplate] is true. | |
| 1064 */ | |
| 1065 @Experimental() | |
| 1066 DocumentFragment createInstance(model, [BindingDelegate delegate]) { | |
| 1067 _ensureTemplate(); | |
| 1068 return TemplateElement.mdvPackage(this).createInstance(model, delegate); | |
| 1069 } | |
| 1070 | |
| 1071 /** | |
| 1072 * The data model which is inherited through the tree. | |
| 1073 * This is only supported if [isTemplate] is true. | |
| 1074 */ | |
| 1075 @Experimental() | |
| 1076 get model => TemplateElement.mdvPackage(this).model; | |
| 1077 | |
| 1078 @Experimental() | |
| 1079 void set model(value) { | |
| 1080 _ensureTemplate(); | |
| 1081 TemplateElement.mdvPackage(this).model = value; | |
| 1082 } | |
| 1083 | |
| 1084 /** | |
| 1085 * The binding delegate which is inherited through the tree. It can be used | |
| 1086 * to configure custom syntax for `{{bindings}}` inside this template. | |
| 1087 * | |
| 1088 * This is only supported if [isTemplate] is true. | |
| 1089 */ | |
| 1090 @Experimental() | |
| 1091 BindingDelegate get bindingDelegate => | |
| 1092 TemplateElement.mdvPackage(this).bindingDelegate; | |
| 1093 | |
| 1094 @Experimental() | |
| 1095 void set bindingDelegate(BindingDelegate value) { | |
| 1096 _ensureTemplate(); | |
| 1097 TemplateElement.mdvPackage(this).bindingDelegate = value; | |
| 1098 } | |
| 1099 | |
| 1100 // TODO(jmesserly): const set would be better | |
| 1101 static const _TABLE_TAGS = const { | |
| 1102 'caption': null, | |
| 1103 'col': null, | |
| 1104 'colgroup': null, | |
| 1105 'tbody': null, | |
| 1106 'td': null, | |
| 1107 'tfoot': null, | |
| 1108 'th': null, | |
| 1109 'thead': null, | |
| 1110 'tr': null, | |
| 1111 }; | |
| 1112 | |
| 1113 bool get _isAttributeTemplate => attributes.containsKey('template') && | |
| 1114 (localName == 'option' || localName == 'optgroup' || | |
| 1115 _TABLE_TAGS.containsKey(localName)); | |
| 1116 | |
| 1117 /** | |
| 1118 * Returns true if this node is a template. | |
| 1119 * | |
| 1120 * A node is a template if [tagName] is TEMPLATE, or the node has the | |
| 1121 * 'template' attribute and this tag supports attribute form for backwards | |
| 1122 * compatibility with existing HTML parsers. The nodes that can use attribute | |
| 1123 * form are table elments (THEAD, TBODY, TFOOT, TH, TR, TD, CAPTION, COLGROUP | |
| 1124 * and COL), OPTION, and OPTGROUP. | |
| 1125 */ | |
| 1126 // TODO(jmesserly): this is not a public MDV API, but it seems like a useful | |
| 1127 // place to document which tags our polyfill considers to be templates. | |
| 1128 // Otherwise I'd be repeating it in several other places. | |
| 1129 // See if we can replace this with a TemplateMixin. | |
| 1130 @Experimental() | |
| 1131 bool get isTemplate => tagName == 'TEMPLATE' || _isAttributeTemplate; | |
| 1132 | |
| 1133 void _ensureTemplate() { | |
| 1134 if (!isTemplate) { | |
| 1135 throw new UnsupportedError('$this is not a template.'); | |
| 1136 } | |
| 1137 TemplateElement.decorate(this); | |
| 1138 } | |
| 1139 | |
| 1140 /** | 1000 /** |
| 1141 * Access this element's content position. | 1001 * Access this element's content position. |
| 1142 * | 1002 * |
| 1143 * This returns a rectangle with the dimenions actually available for content | 1003 * This returns a rectangle with the dimenions actually available for content |
| 1144 * in this element, in pixels, regardless of this element's box-sizing | 1004 * in this element, in pixels, regardless of this element's box-sizing |
| 1145 * property. Unlike [getBoundingClientRect], the dimensions of this rectangle | 1005 * property. Unlike [getBoundingClientRect], the dimensions of this rectangle |
| 1146 * will return the same numerical height if the element is hidden or not. | 1006 * will return the same numerical height if the element is hidden or not. |
| 1147 * | 1007 * |
| 1148 * _Important_ _note_: use of this method _will_ perform CSS calculations that | 1008 * _Important_ _note_: use of this method _will_ perform CSS calculations that |
| 1149 * can trigger a browser reflow. Therefore, use of this property _during_ an | 1009 * can trigger a browser reflow. Therefore, use of this property _during_ an |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 const ScrollAlignment._internal(this._value); | 1280 const ScrollAlignment._internal(this._value); |
| 1421 toString() => 'ScrollAlignment.$_value'; | 1281 toString() => 'ScrollAlignment.$_value'; |
| 1422 | 1282 |
| 1423 /// Attempt to align the element to the top of the scrollable area. | 1283 /// Attempt to align the element to the top of the scrollable area. |
| 1424 static const TOP = const ScrollAlignment._internal('TOP'); | 1284 static const TOP = const ScrollAlignment._internal('TOP'); |
| 1425 /// Attempt to center the element in the scrollable area. | 1285 /// Attempt to center the element in the scrollable area. |
| 1426 static const CENTER = const ScrollAlignment._internal('CENTER'); | 1286 static const CENTER = const ScrollAlignment._internal('CENTER'); |
| 1427 /// Attempt to align the element to the bottom of the scrollable area. | 1287 /// Attempt to align the element to the bottom of the scrollable area. |
| 1428 static const BOTTOM = const ScrollAlignment._internal('BOTTOM'); | 1288 static const BOTTOM = const ScrollAlignment._internal('BOTTOM'); |
| 1429 } | 1289 } |
| OLD | NEW |