@@ -153,7 +153,7 @@ function initEntity(entityName, domElem, params, ignoreLazyInit, callback) {
153153
154154 entityCls . _processInit ( ) ;
155155
156- if ( ignoreLazyInit || params . lazyInit === false || ! entityCls . lazyInit && ! params . lazyInit ) {
156+ if ( ignoreLazyInit || params . lazyInit === false || ! entityCls . _lazyInitCheck ( domElem [ 0 ] ) && ! params . lazyInit ) {
157157 ignoreLazyInit && domElem . addClass ( BEM_CLASS_NAME ) ; // add css class for preventing memory leaks in further destructing
158158
159159 entity = new entityCls ( uniqIdToDomElems [ uniqId ] , params , ! ! ignoreLazyInit ) ;
@@ -341,6 +341,42 @@ function getEntityBase(baseCls, entityName, base) {
341341 return base ;
342342}
343343
344+ /**
345+ * Extract lazyInit property from staticProps
346+ * @param {Object } [staticProps]
347+ * @returns {?Boolean }
348+ */
349+ function extractLazyInitProp ( staticProps ) {
350+ if ( staticProps && staticProps . lazyInit !== undef ) {
351+ var lazyInit = staticProps . lazyInit ;
352+ delete staticProps . lazyInit ;
353+ return lazyInit ;
354+ }
355+
356+ return null ;
357+ }
358+
359+ /**
360+ * Processing lazyInit rules for entity
361+ * @param {Function } entity BemDomEntity
362+ * @param {Object } [mod] mod declaration
363+ * @param {Boolean } lazyInit lazyInit behavior
364+ * @returns {?Boolean }
365+ */
366+ function processLazyInitRule ( entity , mod , lazyInit ) {
367+ if ( arguments . length < 3 ) {
368+ lazyInit = mod ;
369+ mod = undef ;
370+ }
371+
372+ var rules = entity . _lazyInitRules || ( entity . _lazyInitRules = [ ] ) ;
373+
374+ rules . push ( {
375+ check : mod ? entity . _buildModValRE ( mod . modName , mod . modVal ) : entity . _buildRE ( ) ,
376+ lazyInit : lazyInit
377+ } ) ;
378+ }
379+
344380/**
345381 * @class BemDomEntity
346382 * @description Base mix for BEM entities that have DOM representation
@@ -770,11 +806,12 @@ var BemDomEntity = inherit(/** @lends BemDomEntity.prototype */{
770806
771807 /** @override */
772808 declMod : function ( mod , props , staticProps ) {
773- if ( staticProps && staticProps . lazyInit !== undef ) {
774- throw Error ( 'declMod with lazyInit prop not allowed. Your need use \'lazyInit\' in data-bem params' ) ;
775- }
809+ var lazyInit = extractLazyInitProp ( staticProps ) ,
810+ entity = this . __base . apply ( this , arguments ) ;
776811
777- return this . __base . apply ( this , arguments ) ;
812+ lazyInit !== null && processLazyInitRule ( entity , mod , lazyInit ) ;
813+
814+ return entity ;
778815 } ,
779816
780817 /** @override */
@@ -827,17 +864,29 @@ var BemDomEntity = inherit(/** @lends BemDomEntity.prototype */{
827864 return this . getEntityName ( ) + MOD_DELIM + modName ;
828865 } ,
829866
867+ /**
868+ * Builds a regular expression for check entity on DOM element
869+ * @private
870+ * @returns {RegExp }
871+ */
872+ _buildRE : function ( ) {
873+ return new RegExp ( '(\\s|^)' + this . getEntityName ( ) + '?(?=\\s|$)' ) ;
874+ } ,
875+
830876 /**
831877 * Builds a regular expression for extracting modifier values from a DOM element of an entity
832878 * @private
833879 * @param {String } modName Modifier name
880+ * @param {String } [modVal] Modifier value
834881 * @returns {RegExp }
835882 */
836- _buildModValRE : function ( modName ) {
883+ _buildModValRE : function ( modName , modVal ) {
884+ modVal = ( modVal === '*' || modVal === undef ) ? NAME_PATTERN : modVal ;
885+
837886 return new RegExp (
838887 '(\\s|^)' +
839888 this . _buildModClassNamePrefix ( modName ) +
840- '(?:' + MOD_DELIM + '(' + NAME_PATTERN + '))?(?=\\s|$)' ) ;
889+ '(?:' + MOD_DELIM + '(' + modVal + '))?(?=\\s|$)' ) ;
841890 } ,
842891
843892 /**
@@ -860,6 +909,23 @@ var BemDomEntity = inherit(/** @lends BemDomEntity.prototype */{
860909 */
861910 _buildSelector : function ( modName , modVal ) {
862911 return '.' + this . _buildClassName ( modName , modVal ) ;
912+ } ,
913+
914+ /**
915+ * Check domNode for lazy initialization entity
916+ * @protected
917+ * @returns {?Boolean }
918+ */
919+ _lazyInitCheck : function ( domNode ) {
920+ var rules = this . _lazyInitRules , rule ;
921+ if ( ! rules ) return null ;
922+
923+ var len = rules . length ;
924+ while ( rule = rules [ -- len ] ) {
925+ if ( rule . check . test ( domNode . className ) ) return rule . lazyInit ;
926+ }
927+
928+ return null ;
863929 }
864930} ) ;
865931
@@ -960,7 +1026,12 @@ bemDom = /** @exports */{
9601026
9611027 base = getEntityBase ( Block , blockName , base ) ;
9621028
963- return bem . declBlock ( blockName , base , props , staticProps ) ;
1029+ var lazyInit = extractLazyInitProp ( staticProps ) ,
1030+ entity = bem . declBlock ( blockName , base , props , staticProps ) ;
1031+
1032+ lazyInit !== null && processLazyInitRule ( entity , lazyInit ) ;
1033+
1034+ return entity ;
9641035 } ,
9651036
9661037 /**
@@ -983,7 +1054,12 @@ bemDom = /** @exports */{
9831054
9841055 base = getEntityBase ( Elem , entityName , base ) ;
9851056
986- return bem . declElem ( blockName , elemName , base , props , staticProps ) ;
1057+ var lazyInit = extractLazyInitProp ( staticProps ) ,
1058+ entity = bem . declElem ( blockName , elemName , base , props , staticProps ) ;
1059+
1060+ lazyInit !== null && processLazyInitRule ( entity , lazyInit ) ;
1061+
1062+ return entity ;
9871063 } ,
9881064
9891065 declMixin : bem . declMixin ,
0 commit comments