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

Side by Side Diff: tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate

Issue 1373563004: Fixed a bunch of failure cases for custom elements (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merged Created 5 years, 2 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
« no previous file with comments | « tests/html/html.status ('k') | tools/dom/templates/html/impl/impl_Node.darttemplate » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // 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
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
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
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 }
OLDNEW
« no previous file with comments | « tests/html/html.status ('k') | tools/dom/templates/html/impl/impl_Node.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698