@@ -510,14 +510,15 @@ var proto = Object.create(ANode.prototype, {
510510 * When initializing, we set the component on `this.components`.
511511 *
512512 * @param {string } attr - Component name.
513- * @param {object } attrValue - The value of the DOM attribute.
514- * @param {bollean } clobber - if the new attrValue will ccompletely replace the previous properties
513+ * @param {object } attrValue - Value of the DOM attribute.
514+ * @param {boolean } clobber - If new attrValue completely replaces previous properties.
515515 */
516516 updateComponent : {
517517 value : function ( attr , attrValue , clobber ) {
518518 var component = this . components [ attr ] ;
519519 var isDefault = attr in this . defaultComponents ;
520520 if ( component ) {
521+ // Remove component.
521522 if ( attrValue === null && ! isDefault ) {
522523 this . removeComponent ( attr ) ;
523524 return ;
@@ -526,6 +527,7 @@ var proto = Object.create(ANode.prototype, {
526527 component . updateProperties ( attrValue , clobber ) ;
527528 return ;
528529 }
530+
529531 // Component not yet initialized. Initialize component.
530532 this . initComponent ( attr , attrValue , false ) ;
531533 }
@@ -686,28 +688,37 @@ var proto = Object.create(ANode.prototype, {
686688 var arg1Type = typeof arg1 ;
687689 var clobber ;
688690 var componentName ;
691+ var delimiterIndex ;
689692 var isDebugMode ;
690693
691- var pos = attrName . indexOf ( MULTIPLE_COMPONENT_DELIMITER ) ;
692- componentName = pos > 0 ? attrName . substring ( 0 , pos ) : attrName ;
693-
694- // Determine which type of setAttribute to call based on the types of the arguments.
695- if ( COMPONENTS [ componentName ] ) {
696- if ( arg1Type === 'string' && typeof arg2 !== 'undefined' ) {
697- singlePropertyUpdate ( this , attrName , arg1 , arg2 ) ;
698- } else {
699- clobber = arg1Type !== 'object' || ( arg1Type === 'object' && arg2 === true ) ;
700- this . updateComponent ( attrName , arg1 , clobber ) ;
701- }
694+ delimiterIndex = attrName . indexOf ( MULTIPLE_COMPONENT_DELIMITER ) ;
695+ componentName = delimiterIndex > 0 ? attrName . substring ( 0 , delimiterIndex ) : attrName ;
702696
703- // In debug mode, write component data up to the DOM .
704- isDebugMode = this . sceneEl && this . sceneEl . getAttribute ( 'debug' ) ;
705- if ( isDebugMode ) { this . components [ attrName ] . flushToDOM ( ) ; }
697+ // Not a component.
698+ if ( ! COMPONENTS [ componentName ] ) {
699+ normalSetAttribute ( this , attrName , arg1 ) ;
706700 return ;
701+ }
702+
703+ // Initialize component first if not yet initialized.
704+ if ( ! this . components [ attrName ] && this . hasAttribute ( attrName ) ) {
705+ this . updateComponent ( attrName ,
706+ HTMLElement . prototype . getAttribute . call ( this , attrName ) ) ;
707+ }
708+
709+ // Determine which type of setAttribute to call based on the types of the arguments.
710+ if ( arg1Type === 'string' && typeof arg2 !== 'undefined' ) {
711+ singlePropertyUpdate ( this , attrName , arg1 , arg2 ) ;
707712 } else {
708- normalSetAttribute ( this , attrName , arg1 ) ;
713+ // Object update.
714+ clobber = arg1Type !== 'object' || ( arg1Type === 'object' && arg2 === true ) ;
715+ this . updateComponent ( attrName , arg1 , clobber ) ;
709716 }
710717
718+ // In debug mode, write component data up to the DOM.
719+ isDebugMode = this . sceneEl && this . sceneEl . getAttribute ( 'debug' ) ;
720+ if ( isDebugMode ) { this . components [ attrName ] . flushToDOM ( ) ; }
721+
711722 /**
712723 * Just update one of the component properties.
713724 * >> setAttribute('foo', 'bar', 'baz')
0 commit comments