ker/com/x-widget/x-widget.com.js
function getPropertiesAndBindings( root, libs, com, indent ) {
  // Attributes can have post initialization, especially for data bindings.
  var postInit = {};
  var hasPostInit = false;
  var key,
      val,
      values;
  var bindings;
  var slots;
  for ( key in root.attribs ) {
    if ( key.charAt( 0 ) == '$' ) {
      // All the attributes that start with a '$' are used as args attributes.
      val = root.attribs[key];
      com.prop[key.substr( 1 )] = JSON.stringify( val );
    }
    else if ( key.substr( 0, 5 ) == 'intl:' ) {
      // Internationalization.
      val = root.attribs[key];
      com.prop[key.substr( 5 )] = "APP._(" + JSON.stringify( val ) + ")";
    }
    else if ( key.substr( 0, 5 ) == 'bind:' ) {
      // Syntaxe :
      // <bind> := <bind-item> <bind-next>*
      // <bind-next> := "," <bind-item>
      // <bind-item> := <widget-name> <attribute>? <value>?
      // <widget-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/
      // <attribute> := ":" <attrib-name>
      // <attrib-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/
      // <value> := "=" <data>
      // <data> := "true" | "false" | "null" | <number> | <string>
      //
      // @example
      // <wdg:checkbox bind:value="btn1:action" />
      // <wdg:checkbox bind:value="btn1:action, btn2, action=false" />
      if ( typeof postInit[key.substr( 5 )] === 'undefined' ) {
        postInit[key.substr( 5 )] = {};
      }
      postInit[key.substr( 5 )].B = parseBinding(root.attribs[key]);
      hasPostInit = true;
    }
    else if ( key.substr( 0, 5 ) == 'slot:' ) {
      // @example
      // <wdg:button slot:action="removeOrder" />
      // <wdg:button slot:action="removeOrder, changePage" />
      // <wdg:button slot:action="my-module:my-function" />
      values = root.attribs[key].split( "," );
      key = key.substr( 5 );
      if ( typeof postInit[key] === 'undefined' ) {
        postInit[key] = {};
      }
      slots = [ ];
      values.forEach( function( val ) {
        // Before the colon (:) there is the module name. After, there
        // is the function  name. If there is no colon,  `APP` is used
        // as module.
        val = val.split( ':' );
        if ( val.length < 2 ) {
          slots.push(val[0].trim( ));
        } else {
          slots.push(val.map( String.trim ));
          libs.require(val[0]);
        }
      });
      postInit[key].S = slots;
      hasPostInit = true;
    }
    else {
      com.attr[key] = root.attribs[key];
    }
  }

  if ( hasPostInit ) {
    libs.addPostInitJS( "        W.bind('" + com.attr.id + "'," + JSON.stringify( postInit ) + ");" );
  }
}
function getPropertiesAndBindings( root, libs, com, indent ) {
  // Attributes can have post initialization, especially for data bindings.
  var postInit = {};
  var hasPostInit = false;
  var key,
      val,
      values;
  var bindings;
  var slots;
  for ( key in root.attribs ) {
    if ( key.charAt( 0 ) == '$' ) {
      // All the attributes that start with a '$' are used as args attributes.
      val = root.attribs[key];
      com.prop[key.substr( 1 )] = JSON.stringify( val );
    }
    else if ( key.substr( 0, 5 ) == 'intl:' ) {
      // Internationalization.
      val = root.attribs[key];
      com.prop[key.substr( 5 )] = "APP._(" + JSON.stringify( val ) + ")";
    }
    else if ( key.substr( 0, 5 ) == 'bind:' ) {
      // Syntaxe :
      // <bind> := <bind-item> <bind-next>*
      // <bind-next> := "," <bind-item>
      // <bind-item> := <widget-name> <attribute>? <value>?
      // <widget-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/
      // <attribute> := ":" <attrib-name>
      // <attrib-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/
      // <value> := "=" <data>
      // <data> := "true" | "false" | "null" | <number> | <string>
      //
      // @example
      // <wdg:checkbox bind:value="btn1:action" />
      // <wdg:checkbox bind:value="btn1:action, btn2, action=false" />
      if ( typeof postInit[key.substr( 5 )] === 'undefined' ) {
        postInit[key.substr( 5 )] = {};
      }
      postInit[key.substr( 5 )].B = parseBinding(root.attribs[key]);
      hasPostInit = true;
    }
    else if ( key.substr( 0, 5 ) == 'slot:' ) {
      // @example
      // <wdg:button slot:action="removeOrder" />
      // <wdg:button slot:action="removeOrder, changePage" />
      // <wdg:button slot:action="my-module:my-function" />
      values = root.attribs[key].split( "," );
      key = key.substr( 5 );
      if ( typeof postInit[key] === 'undefined' ) {
        postInit[key] = {};
      }
      slots = [ ];
      values.forEach( function( val ) {
        // Before the colon (:) there is the module name. After, there
        // is the function  name. If there is no colon,  `APP` is used
        // as module.
        val = val.split( ':' );
        if ( val.length < 2 ) {
          slots.push(val[0].trim( ));
        } else {
          slots.push(val.map( String.trim ));
          libs.require(val[0]);
        }
      });
      postInit[key].S = slots;
      hasPostInit = true;
    }
    else {
      com.attr[key] = root.attribs[key];
    }
  }

  if ( hasPostInit ) {
    libs.addPostInitJS( "        W.bind('" + com.attr.id + "'," + JSON.stringify( postInit ) + ");" );
  }
}
function getPropertiesAndBindings ( root , libs , com , indent ) { // Attributes can have post initialization, especially for data bindings. var postInit = { } ; var hasPostInit = false ; var key , val , values ; var bindings ; var slots ; for ( key in root . attribs ) { if ( key . charAt ( 0 ) == '$' ) { // All the attributes that start with a '$' are used as args attributes. val = root . attribs [ key ] ; com . prop [ key . substr ( 1 ) ] = JSON . stringify ( val ) ; } else if ( key . substr ( 0 , 5 ) == 'intl:' ) { // Internationalization. val = root . attribs [ key ] ; com . prop [ key . substr ( 5 ) ] = "APP._(" + JSON . stringify ( val ) + ")" ; } else if ( key . substr ( 0 , 5 ) == 'bind:' ) { // Syntaxe : // <bind> := <bind-item> <bind-next>* // <bind-next> := "," <bind-item> // <bind-item> := <widget-name> <attribute>? <value>? // <widget-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/ // <attribute> := ":" <attrib-name> // <attrib-name> := /[$a-zA-Z_-][$0-9a-zA-Z_-]+/ // <value> := "=" <data> // <data> := "true" | "false" | "null" | <number> | <string> // // @example // <wdg:checkbox bind:value="btn1:action" /> // <wdg:checkbox bind:value="btn1:action, btn2, action=false" /> if ( typeof postInit [ key . substr ( 5 ) ] === 'undefined' ) { postInit [ key . substr ( 5 ) ] = { } ; } postInit [ key . substr ( 5 ) ] . B = parseBinding ( root . attribs [ key ] ) ; hasPostInit = true ; } else if ( key . substr ( 0 , 5 ) == 'slot:' ) { // @example // <wdg:button slot:action="removeOrder" /> // <wdg:button slot:action="removeOrder, changePage" /> // <wdg:button slot:action="my-module:my-function" /> values = root . attribs [ key ] . split ( "," ) ; key = key . substr ( 5 ) ; if ( typeof postInit [ key ] === 'undefined' ) { postInit [ key ] = { } ; } slots = [ ] ; values . forEach ( function ( val ) { // Before the colon (:) there is the module name. After, there // is the function  name. If there is no colon,  `APP` is used // as module. val = val . split ( ':' ) ; if ( val . length < 2 ) { slots . push ( val [ 0 ] . trim ( ) ) ; } else { slots . push ( val . map ( String . trim ) ) ; libs . require ( val [ 0 ] ) ; } } ) ; postInit [ key ] . S = slots ; hasPostInit = true ; } else { com . attr [ key ] = root . attribs [ key ] ; } } if ( hasPostInit ) { libs . addPostInitJS ( "        W.bind('" + com . attr . id + "'," + JSON . stringify ( postInit ) + ");" ) ; } }
Properties and bindings.
Properties and bindings .