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 // WARNING: Do not edit - generated code. | 5 // WARNING: Do not edit - generated code. |
6 | 6 |
7 part of $LIBRARYNAME; | 7 part of $LIBRARYNAME; |
8 | 8 |
9 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
{ | 9 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
{ |
10 $!MEMBERS | 10 $!MEMBERS |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 } | 214 } |
215 } | 215 } |
216 } | 216 } |
217 | 217 |
218 classMirror = classMirror.superclass; | 218 classMirror = classMirror.superclass; |
219 } | 219 } |
220 | 220 |
221 // If we're an element then everything is okay. | 221 // If we're an element then everything is okay. |
222 return isElement ? jsClassName : null; | 222 return isElement ? jsClassName : null; |
223 } | 223 } |
| 224 |
| 225 /** |
| 226 * Does this CustomElement class have: |
| 227 * |
| 228 * - a created constructor with no arguments? |
| 229 * - a created constructor with a super.created() initializer? |
| 230 * |
| 231 * e.g., MyCustomClass.created() : super.created(); |
| 232 */ |
| 233 bool _hasCreatedConstructor(ClassMirror classMirror) { |
| 234 var createdParametersValid = false; |
| 235 var superCreatedCalled = false; |
| 236 var className = MirrorSystem.getName(classMirror.simpleName); |
| 237 var methodMirror = classMirror.declarations[new Symbol("$className.created")
]; |
| 238 if (methodMirror != null) { |
| 239 createdParametersValid = methodMirror.parameters.length == 0; |
| 240 |
| 241 // Get the created constructor source and look at the initializer; |
| 242 // Must call super.created() if not its as an error. |
| 243 var createdSource = methodMirror.source; |
| 244 RegExp regExp = new RegExp(r":(.*?)(;|}|\n)"); |
| 245 var match = regExp.firstMatch(createdSource); |
| 246 superCreatedCalled = match.input.substring(match.start,match.end).contains
("super.created()"); |
| 247 } |
| 248 |
| 249 if (!superCreatedCalled) { |
| 250 throw new DomException.jsInterop('created constructor initializer must cal
l super.created()'); |
| 251 } else if (!createdParametersValid) { |
| 252 throw new DomException.jsInterop('created constructor must have no paramet
ers'); |
| 253 } |
| 254 |
| 255 return true; |
| 256 } |
224 $endif | 257 $endif |
225 | 258 |
226 @Experimental() | 259 @Experimental() |
227 /** | 260 /** |
228 * Register a custom subclass of Element to be instantiatable by the DOM. | 261 * Register a custom subclass of Element to be instantiatable by the DOM. |
229 * | 262 * |
230 * This is necessary to allow the construction of any custom elements. | 263 * This is necessary to allow the construction of any custom elements. |
231 * | 264 * |
232 * The class being registered must either subclass HtmlElement or SvgElement. | 265 * The class being registered must either subclass HtmlElement or SvgElement. |
233 * If they subclass these directly then they can be used as: | 266 * If they subclass these directly then they can be used as: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 // TODO(terry): Need to handle the extendsTag. | 307 // TODO(terry): Need to handle the extendsTag. |
275 | 308 |
276 // Figure out which DOM class is being extended from the user's Dart class. | 309 // Figure out which DOM class is being extended from the user's Dart class. |
277 var classMirror = reflectClass(customElementClass); | 310 var classMirror = reflectClass(customElementClass); |
278 var jsClassName = _getJSClassName(classMirror); | 311 var jsClassName = _getJSClassName(classMirror); |
279 if (jsClassName == null) { | 312 if (jsClassName == null) { |
280 // Only components derived from HTML* can be extended. | 313 // Only components derived from HTML* can be extended. |
281 throw new DomException.jsInterop("HierarchyRequestError: Only HTML element
s can be customized."); | 314 throw new DomException.jsInterop("HierarchyRequestError: Only HTML element
s can be customized."); |
282 } | 315 } |
283 | 316 |
284 // Start the hookup the JS way create an <x-foo> element that extends the | 317 if (_hasCreatedConstructor(classMirror)) { |
285 // <x-base> custom element. Inherit its prototype and signal what tag is | 318 // Start the hookup the JS way create an <x-foo> element that extends the |
286 // inherited: | 319 // <x-base> custom element. Inherit its prototype and signal what tag is |
287 // | 320 // inherited: |
288 // var myProto = Object.create(HTMLElement.prototype); | 321 // |
289 // var myElement = document.registerElement('x-foo', {prototype: myProto
}); | 322 // var myProto = Object.create(HTMLElement.prototype); |
290 var baseElement = js.context[jsClassName]; | 323 // var myElement = document.registerElement('x-foo', {prototype: myPro
to}); |
291 if (baseElement == null) { | 324 var baseElement = js.context[jsClassName]; |
292 // Couldn't find the HTML element so use a generic one. | 325 if (baseElement == null) { |
293 baseElement = js.context['HTMLElement']; | 326 // Couldn't find the HTML element so use a generic one. |
| 327 baseElement = js.context['HTMLElement']; |
| 328 } |
| 329 var elemProto = js.context['Object'].callMethod("create", [baseElement['pr
ototype']]); |
| 330 |
| 331 // TODO(terry): Hack to stop recursion re-creating custom element when the |
| 332 // created() constructor of the custom element does e.g., |
| 333 // |
| 334 // MyElement.created() : super.created() { |
| 335 // this.innerHtml = "<b>I'm an x-foo-with-markup!</b>"; |
| 336 // } |
| 337 // |
| 338 // sanitizing causes custom element to created recursively |
| 339 // until stack overflow. |
| 340 // |
| 341 // See https://github.com/dart-lang/sdk/issues/23666 |
| 342 int creating = 0; |
| 343 elemProto['createdCallback'] = new js.JsFunction.withThis(($this) { |
| 344 if (_getJSClassName(reflectClass(customElementClass).superclass) != null
&& creating < 2) { |
| 345 creating++; |
| 346 |
| 347 var dartClass; |
| 348 try { |
| 349 dartClass = _blink.Blink_Utils.constructElement(customElementClass,
$this); |
| 350 } catch (e) { |
| 351 dartClass = HtmlElement.internalCreateHtmlElement(); |
| 352 throw e; |
| 353 } finally { |
| 354 // Need to remember the Dart class that was created for this custom
so |
| 355 // return it and setup the blink_jsObject to the $this that we'll be
working |
| 356 // with as we talk to blink. |
| 357 $this['dart_class'] = dartClass; |
| 358 |
| 359 creating--; |
| 360 } |
| 361 } |
| 362 }); |
| 363 elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this,
attrName, oldVal, newVal) { |
| 364 if ($this["dart_class"] != null && $this['dart_class'].attributeChanged
!= null) { |
| 365 $this['dart_class'].attributeChanged(attrName, oldVal, newVal); |
| 366 } |
| 367 }); |
| 368 elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) { |
| 369 if ($this["dart_class"] != null && $this['dart_class'].attached != null)
{ |
| 370 $this['dart_class'].attached(); |
| 371 } |
| 372 }); |
| 373 elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) { |
| 374 if ($this["dart_class"] != null && $this['dart_class'].detached != null)
{ |
| 375 $this['dart_class'].detached(); |
| 376 } |
| 377 }); |
| 378 // document.registerElement('x-foo', {prototype: elemProto, extends: exten
dsTag}); |
| 379 var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': exte
ndsTag}); |
| 380 js.context['document'].callMethod('registerElement', [tag, jsMap]); |
294 } | 381 } |
295 var elemProto = js.context['Object'].callMethod("create", [baseElement['prot
otype']]); | |
296 | |
297 // TODO(terry): Hack to stop recursion re-creating custom element when the | |
298 // created() constructor of the custom element does e.g., | |
299 // | |
300 // MyElement.created() : super.created() { | |
301 // this.innerHtml = "<b>I'm an x-foo-with-markup!</b>"; | |
302 // } | |
303 // | |
304 // sanitizing causes custom element to created recursively | |
305 // until stack overflow. | |
306 // | |
307 // See https://github.com/dart-lang/sdk/issues/23666 | |
308 int creating = 0; | |
309 elemProto['createdCallback'] = new js.JsFunction.withThis(($this) { | |
310 if (_getJSClassName(reflectClass(customElementClass).superclass) != null &
& creating < 2) { | |
311 creating++; | |
312 | |
313 var dartClass; | |
314 try { | |
315 dartClass = _blink.Blink_Utils.constructElement(customElementClass, $t
his); | |
316 } catch (e) { | |
317 dartClass = null; | |
318 } finally { | |
319 // Need to remember the Dart class that was created for this custom so | |
320 // return it and setup the blink_jsObject to the $this that we'll be w
orking | |
321 // with as we talk to blink. | |
322 $this['dart_class'] = dartClass; | |
323 | |
324 creating--; | |
325 } | |
326 } | |
327 }); | |
328 elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, a
ttrName, oldVal, newVal) { | |
329 if ($this["dart_class"] != null && $this['dart_class'].attributeChanged !=
null) { | |
330 $this['dart_class'].attributeChanged(attrName, oldVal, newVal); | |
331 } | |
332 }); | |
333 elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) { | |
334 if ($this["dart_class"] != null && $this['dart_class'].attached != null) { | |
335 $this['dart_class'].attached(); | |
336 } | |
337 }); | |
338 elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) { | |
339 if ($this["dart_class"] != null && $this['dart_class'].detached != null) { | |
340 $this['dart_class'].detached(); | |
341 } | |
342 }); | |
343 // document.registerElement('x-foo', {prototype: elemProto, extends: extends
Tag}); | |
344 var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extend
sTag}); | |
345 js.context['document'].callMethod('registerElement', [tag, jsMap]); | |
346 $endif | 382 $endif |
347 } | 383 } |
348 | 384 |
349 /** *Deprecated*: use [registerElement] instead. */ | 385 /** *Deprecated*: use [registerElement] instead. */ |
350 @deprecated | 386 @deprecated |
351 @Experimental() | 387 @Experimental() |
352 void register(String tag, Type customElementClass, {String extendsTag}) { | 388 void register(String tag, Type customElementClass, {String extendsTag}) { |
353 return registerElement(tag, customElementClass, extendsTag: extendsTag); | 389 return registerElement(tag, customElementClass, extendsTag: extendsTag); |
354 } | 390 } |
355 | 391 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 /// parameter must be provided. | 439 /// parameter must be provided. |
404 @Experimental() | 440 @Experimental() |
405 ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) { | 441 ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) { |
406 $if DART2JS | 442 $if DART2JS |
407 return new _JSElementUpgrader(this, type, extendsTag); | 443 return new _JSElementUpgrader(this, type, extendsTag); |
408 $else | 444 $else |
409 return new _VMElementUpgrader(this, type, extendsTag); | 445 return new _VMElementUpgrader(this, type, extendsTag); |
410 $endif | 446 $endif |
411 } | 447 } |
412 } | 448 } |
OLD | NEW |