New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

bemquery

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bemquery - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

38

CHANGELOG.md
# bemquery Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
---
## [0.1.4]
### Added
* Ability to install package via [Bower](https://bower.io/).
## 0.1.3
### Changed
* Changelog is now compliant with [Keep a Changelog](http://keepachangelog.com/) format.
## [0.1.3] – 2016-08-08
### Changed
* Updated boilerplate.
### Fixed
* Fixed changelog.
## 0.1.2
## [0.1.2] – 2016-07-10
### Changed
* Updated CI configuration.
* Updated dependencies.
## 0.1.1
## [0.1.1] – 2016-06-25
### Changed
* Updated rollup configuration.
* Updated dependencies.
### Fixed
* Fixed wrong project name in documentation.
## 0.1.0
## [0.1.0] – 2016-05-09
### Changed
* Updated boilerplate.

@@ -27,4 +41,10 @@ * Updated dependencies.

## 0.0.1
## 0.0.1 – 2016-05-01
### Added
* First working version.
* First working version.
[0.1.4]: https://github.com/BEMQuery/bemquery/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/BEMQuery/bemquery/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/BEMQuery/bemquery/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/BEMQuery/bemquery/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/BEMQuery/bemquery/compare/v0.0.1...v0.1.0

@@ -1,2 +0,2 @@

/*! bemquery v0.1.3 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/*! bemquery v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/*! bemquery-selector-converter v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */

@@ -161,3 +161,3 @@ /** Simple class representing selector */

*/
function factory$1( converterConfig = defaultConfig ) {
function factory$2( converterConfig = defaultConfig ) {
const converter = new Converter( converterConfig );

@@ -201,2 +201,3 @@

/*! bemquery-core v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
function checkConverter( converter ) {

@@ -380,3 +381,3 @@ return typeof converter === 'object' && typeof converter.convert === 'function';

function factory( query, context = document ) {
const converter = factory$1();
const converter = factory$2();
const selectorEngine = new SelectorEngine();

@@ -390,3 +391,4 @@ const bemQuery = new BEMQuery( query, context, converter, selectorEngine );

var $ = Object.freeze({
var $$1 = Object.freeze({
BEMQuery: BEMQuery,

@@ -396,2 +398,3 @@ default: factory

/*! bemquery-async-dom v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Class storing queue of DOM operations. */

@@ -563,2 +566,3 @@ class Batch {

/*! bemquery-dom-events v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Storage for events listeners */

@@ -763,3 +767,3 @@ class ListenersStorage {

export default $;
export default $$1;
//# sourceMappingURL=bemquery.js.map

@@ -1,2 +0,2 @@

/*! bemquery v0.1.3 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/*! bemquery v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
(function (global, factory) {

@@ -6,762 +6,766 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :

(global.bemquery = factory());
}(this, function () { 'use strict';
}(this, (function () { 'use strict';
/*! bemquery-selector-converter v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Simple class representing selector */
class Selector {
/*! bemquery-selector-converter v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Simple class representing selector */
class Selector {
/**
* Creates new Selector instance.
*
* @param {String} BEM BEM version of selector.
* @param {String} CSS CSS version of selector.
*/
constructor( BEM, CSS ) {
/**
* Creates new Selector instance.
* BEM version of selector.
*
* @param {String} BEM BEM version of selector.
* @param {String} CSS CSS version of selector.
* @property {String}
*/
constructor( BEM, CSS ) {
/**
* BEM version of selector.
*
* @property {String}
*/
this.BEM = BEM;
this.BEM = BEM;
/**
* CSS version of selector.
*
* @property {String}
*/
this.CSS = CSS;
/**
* CSS version of selector.
*
* @property {String}
*/
this.CSS = CSS;
Object.freeze( this );
}
Object.freeze( this );
}
}
function endsWithModifier( selector, bemConfig ) {
const regex = new RegExp( `[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+${bemConfig.modifierSeparator}[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+$`,
'g' );
function endsWithModifier( selector, bemConfig ) {
const regex = new RegExp( `[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+${bemConfig.modifierSeparator}[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+$`,
'g' );
return !!selector.match( regex );
}
return !!selector.match( regex );
}
function getSelectorWithoutModifier( selector, modifierSeparator ) {
return ` ${selector.substring( selector.lastIndexOf( '.' ), selector.lastIndexOf( modifierSeparator ) )}`;
}
function getSelectorWithoutModifier( selector, modifierSeparator ) {
return ` ${selector.substring( selector.lastIndexOf( '.' ), selector.lastIndexOf( modifierSeparator ) )}`;
}
const defaultConfig = {
bem: {
elemSeparator: '__',
modifierSeparator: '_'
const defaultConfig = {
bem: {
elemSeparator: '__',
modifierSeparator: '_'
},
rules: {
default( token ) {
return `.${token}`;
},
rules: {
default( token ) {
return `.${token}`;
},
' > '( token, config ) {
return ` ${config.rules.default( token )}`;
},
' > '( token, config ) {
return ` ${config.rules.default( token )}`;
},
' '( token, config, selector ) {
if ( endsWithModifier( selector, config.bem ) ) {
return `${getSelectorWithoutModifier( selector, config.bem.modifierSeparator )}${config.bem.elemSeparator}${token}`;
}
return `${config.bem.elemSeparator}${token}`;
},
':'( token, config ) {
return `${config.bem.modifierSeparator}${token}`;
' '( token, config, selector ) {
if ( endsWithModifier( selector, config.bem ) ) {
return `${getSelectorWithoutModifier( selector, config.bem.modifierSeparator )}${config.bem.elemSeparator}${token}`;
}
}
};
function convertToken( tokens, config, selector = '' ) {
const rules = config.rules;
const delimeter = tokens.shift();
let rule;
let token;
return `${config.bem.elemSeparator}${token}`;
},
if ( !delimeter ) {
return selector;
} else if ( !selector ) {
token = delimeter;
rule = rules.default;
} else {
token = tokens.shift();
rule = rules[ delimeter ];
':'( token, config ) {
return `${config.bem.modifierSeparator}${token}`;
}
}
};
if ( typeof rule !== 'function' ) {
throw new SyntaxError( 'Malformed BEM rule' );
}
function convertToken( tokens, config, selector = '' ) {
const rules = config.rules;
const delimeter = tokens.shift();
let rule;
let token;
selector += rule( token, config, selector );
if ( !delimeter ) {
return selector;
} else if ( !selector ) {
token = delimeter;
rule = rules.default;
} else {
token = tokens.shift();
rule = rules[ delimeter ];
}
return convertToken( tokens, config, selector );
if ( typeof rule !== 'function' ) {
throw new SyntaxError( 'Malformed BEM rule' );
}
function convert( selector, config ) {
const rules = Object.keys( config.rules ).filter( ( rule ) => {
return rule !== 'default';
} );
const splitRule = new RegExp( `(${rules.join( '|' )})`, 'g' );
const splittedSelector = selector.split( splitRule );
selector += rule( token, config, selector );
selector = convertToken( splittedSelector, config );
return convertToken( tokens, config, selector );
}
return selector;
}
function convert( selector, config ) {
const rules = Object.keys( config.rules ).filter( ( rule ) => {
return rule !== 'default';
} );
const splitRule = new RegExp( `(${rules.join( '|' )})`, 'g' );
const splittedSelector = selector.split( splitRule );
/** Converter's class*/
class Converter {
/**
* Create converter's instance.
*
* @param {Object} [config=defaultConfig] converter's configuration options.
* @class
*/
constructor( config = defaultConfig ) {
/**
* Converter's configuration
*
* @property {Object}
*/
this.config = config;
}
selector = convertToken( splittedSelector, config );
/**
* Converts given selector to CSS.
*
* @param {String} selector BEM selector to be converted.
* @return {Selector} Converted selector.
*/
convert( selector ) {
const convertedSelector = convert( selector, this.config );
return selector;
}
return new Selector( selector, convertedSelector );
}
/** Converter's class*/
class Converter {
/**
* Create converter's instance.
*
* @param {Object} [config=defaultConfig] converter's configuration options.
* @class
*/
constructor( config = defaultConfig ) {
/**
* Get state from given `[class]` attribute contents.
* Converter's configuration
*
* @param {String} className HTML `[class]` attribute.
* @return {String|null} Fetched state.
* @property {Object}
*/
getStateFromClass( className ) {
if ( typeof className !== 'string' ) {
throw new TypeError( 'Class must be a string.' );
}
this.config = config;
}
const bemConfig = this.config.bem;
const regex = new RegExp( `[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+${bemConfig.modifierSeparator}([^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+)$` );
const match = className.match( regex );
/**
* Converts given selector to CSS.
*
* @param {String} selector BEM selector to be converted.
* @return {Selector} Converted selector.
*/
convert( selector ) {
const convertedSelector = convert( selector, this.config );
return match ? match[ 1 ] : null;
}
return new Selector( selector, convertedSelector );
}
/**
* BEM selector converter factory.
* Get state from given `[class]` attribute contents.
*
* @param {Object} [converterConfig=defaultConverterConfig] Configuration object that
* should be passed to the Converter constructor.
* @return {Converter} Converter's instance.
* @param {String} className HTML `[class]` attribute.
* @return {String|null} Fetched state.
*/
function factory$1( converterConfig = defaultConfig ) {
const converter = new Converter( converterConfig );
getStateFromClass( className ) {
if ( typeof className !== 'string' ) {
throw new TypeError( 'Class must be a string.' );
}
return converter;
const bemConfig = this.config.bem;
const regex = new RegExp( `[^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+${bemConfig.modifierSeparator}([^${bemConfig.elemSeparator}${bemConfig.modifierSeparator}]+)$` );
const match = className.match( regex );
return match ? match[ 1 ] : null;
}
}
/*! bemquery-selector-engine v0.2.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Simple selector engine. */
class SelectorEngine {
/**
* Find elements using passed selector.
*
* @param {String} selector CSS selector.
* @param {HTMLElement|Document} context Context
* in which element should be found.
* @returns {HTMLElement[]} Found elements.
*/
find( selector, context = document ) {
let tmpId = false;
/**
* BEM selector converter factory.
*
* @param {Object} [converterConfig=defaultConverterConfig] Configuration object that
* should be passed to the Converter constructor.
* @return {Converter} Converter's instance.
*/
function factory$2( converterConfig = defaultConfig ) {
const converter = new Converter( converterConfig );
if ( context !== document ) {
if ( !context.id ) {
tmpId = true;
context.id = `BEMQueryTMP_${Date.now()}`;
}
return converter;
}
selector = `#${context.id} ${selector}`;
/*! bemquery-selector-engine v0.2.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Simple selector engine. */
class SelectorEngine {
/**
* Find elements using passed selector.
*
* @param {String} selector CSS selector.
* @param {HTMLElement|Document} context Context
* in which element should be found.
* @returns {HTMLElement[]} Found elements.
*/
find( selector, context = document ) {
let tmpId = false;
if ( context !== document ) {
if ( !context.id ) {
tmpId = true;
context.id = `BEMQueryTMP_${Date.now()}`;
}
const elements = Array.from( context.querySelectorAll( selector ) );
selector = `#${context.id} ${selector}`;
}
if ( tmpId ) {
context.removeAttribute( 'id' );
}
const elements = Array.from( context.querySelectorAll( selector ) );
return elements;
if ( tmpId ) {
context.removeAttribute( 'id' );
}
}
function checkConverter( converter ) {
return typeof converter === 'object' && typeof converter.convert === 'function';
return elements;
}
}
function checkSelectorEngine( selectorEngine ) {
return typeof selectorEngine === 'object' && typeof selectorEngine.find === 'function';
}
/*! bemquery-core v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
function checkConverter( converter ) {
return typeof converter === 'object' && typeof converter.convert === 'function';
}
function determineContext( context ) {
if ( context instanceof BEMQuery ) { // eslint-disable-line no-use-before-define
context = context.elements[ 0 ];
}
function checkSelectorEngine( selectorEngine ) {
return typeof selectorEngine === 'object' && typeof selectorEngine.find === 'function';
}
if ( !( context instanceof HTMLElement ) && context !== document ) {
context = document;
}
function determineContext( context ) {
if ( context instanceof BEMQuery ) { // eslint-disable-line no-use-before-define
context = context.elements[ 0 ];
}
return context;
if ( !( context instanceof HTMLElement ) && context !== document ) {
context = document;
}
function fetchElements( query, context, converter, selectorEngine ) {
if ( !query ) {
throw new TypeError( 'Selector must be set.' );
}
return context;
}
if ( typeof query === 'string' ) {
query = converter.convert( query ).CSS;
return selectorEngine.find( query, context );
} else if ( query instanceof HTMLElement ) {
return [
query
];
} else if ( query instanceof BEMQuery ) { // eslint-disable-line no-use-before-define
return query.elements;
} else if ( typeof query === 'object' ) {
return Array.from( query );
} else {
throw new TypeError( 'Selector must be a string, object, array or DOM element.' );
}
function fetchElements( query, context, converter, selectorEngine ) {
if ( !query ) {
throw new TypeError( 'Selector must be set.' );
}
function defineProperties( obj, elements ) {
Object.defineProperty( obj, 'elements', {
value: elements
} );
if ( typeof query === 'string' ) {
query = converter.convert( query ).CSS;
return selectorEngine.find( query, context );
} else if ( query instanceof HTMLElement ) {
return [
query
];
} else if ( query instanceof BEMQuery ) { // eslint-disable-line no-use-before-define
return query.elements;
} else if ( typeof query === 'object' ) {
return Array.from( query );
} else {
throw new TypeError( 'Selector must be a string, object, array or DOM element.' );
}
}
obj.elements.forEach( ( element, index ) => {
Object.defineProperty( obj, index, {
enumerable: true,
get() {
return new BEMQuery( this.elements[ index ], document, this.converter, this.selectorEngine ); // eslint-disable-line no-use-before-define
}
} );
}, obj );
function defineProperties( obj, elements ) {
Object.defineProperty( obj, 'elements', {
value: elements
} );
Object.defineProperty( obj, 'length', {
obj.elements.forEach( ( element, index ) => {
Object.defineProperty( obj, index, {
enumerable: true,
get() {
return this.elements.length;
return new BEMQuery( this.elements[ index ], document, this.converter, this.selectorEngine ); // eslint-disable-line no-use-before-define
}
} );
}
}, obj );
/** Class representing elements collection. */
class BEMQuery {
/**
* Creates elements collection.
*
* @param {String|Iterable|HTMLElement} query Selector or
* existing elements collection upon which the new elements collection
* should be created.
* @param {Document|HTMLElement|BEMQuery} context Context from which
* elements should be fetched.
* @param {Converter} converter BEM selector converter to be used.
* @param {SelectorEngine} selectorEngine CSS selector engine to be used
* by the current and descendant `BEMQuery` instances.
* @class
*/
constructor( query, context, converter, selectorEngine ) {
if ( !checkConverter( converter ) ) {
throw new TypeError( 'Converter must be an object with convert method defined.' );
}
Object.defineProperty( obj, 'length', {
enumerable: true,
get() {
return this.elements.length;
}
} );
}
if ( !checkSelectorEngine( selectorEngine ) ) {
throw new TypeError( 'SelectorEngine must be an object with find method defined.' );
}
/** Class representing elements collection. */
class BEMQuery {
/**
* Creates elements collection.
*
* @param {String|Iterable|HTMLElement} query Selector or
* existing elements collection upon which the new elements collection
* should be created.
* @param {Document|HTMLElement|BEMQuery} context Context from which
* elements should be fetched.
* @param {Converter} converter BEM selector converter to be used.
* @param {SelectorEngine} selectorEngine CSS selector engine to be used
* by the current and descendant `BEMQuery` instances.
* @class
*/
constructor( query, context, converter, selectorEngine ) {
if ( !checkConverter( converter ) ) {
throw new TypeError( 'Converter must be an object with convert method defined.' );
}
this.converter = converter;
this.selectorEngine = selectorEngine;
if ( !checkSelectorEngine( selectorEngine ) ) {
throw new TypeError( 'SelectorEngine must be an object with find method defined.' );
}
context = determineContext( context );
this.converter = converter;
this.selectorEngine = selectorEngine;
defineProperties( this, fetchElements( query, context, converter, selectorEngine ) );
}
context = determineContext( context );
/**
* Gets element with given index.
*
* @param {Number} index Element's index.
* @return {BEMQuery} New BEMQuery instance with fetched element
* as an only element in the collection.
*/
get( index ) {
index = Number( index );
defineProperties( this, fetchElements( query, context, converter, selectorEngine ) );
}
if ( Number.isNaN( index ) ) {
throw new TypeError( 'Index must be a correct Number.' );
} else if ( index < 0 ) {
throw new RangeError( 'Index must be greater or equal to 0.' );
} else if ( index > ( this.elements.length - 1 ) ) {
throw new RangeError( 'Index cannot be greater than collection\'s length.' );
}
/**
* Gets element with given index.
*
* @param {Number} index Element's index.
* @return {BEMQuery} New BEMQuery instance with fetched element
* as an only element in the collection.
*/
get( index ) {
index = Number( index );
return new BEMQuery( this.elements[ index ], document, this.converter, this.selectorEngine );
if ( Number.isNaN( index ) ) {
throw new TypeError( 'Index must be a correct Number.' );
} else if ( index < 0 ) {
throw new RangeError( 'Index must be greater or equal to 0.' );
} else if ( index > ( this.elements.length - 1 ) ) {
throw new RangeError( 'Index cannot be greater than collection\'s length.' );
}
/**
* Executes callback on every element in the collection.
*
* @param {Function} callback Callback to be executed.
* @return {BEMQuery} Current `BEMQuery` instance.
*/
each( callback ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
}
return new BEMQuery( this.elements[ index ], document, this.converter, this.selectorEngine );
}
const converter = this.converter;
const selectorEngine = this.selectorEngine;
this.elements.forEach( ( element ) => {
callback( new BEMQuery( element, document, converter, selectorEngine ) );
} );
return this;
/**
* Executes callback on every element in the collection.
*
* @param {Function} callback Callback to be executed.
* @return {BEMQuery} Current `BEMQuery` instance.
*/
each( callback ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
}
/**
* Returns iterator for contained elements.
*
* @return {Iterator} Returned iterator.
*/
[ Symbol.iterator ]() {
let i = 0;
const elements = this.elements;
const converter = this.converter;
const selectorEngine = this.selectorEngine;
const converter = this.converter;
const selectorEngine = this.selectorEngine;
return {
next() {
if ( i < elements.length ) {
const element = elements[ i++ ];
this.elements.forEach( ( element ) => {
callback( new BEMQuery( element, document, converter, selectorEngine ) );
} );
return {
value: new BEMQuery( [ element ], document, converter, selectorEngine ),
done: false
};
}
return {
done: true
};
}
};
}
return this;
}
/**
* BEMQuery instance factory.
* Returns iterator for contained elements.
*
* @param {String|Iterable|HTMLElement} query Selector or
* existing elements collection upon which the new elements collection
* should be created.
* @param {Document|HTMLElement|BEMQuery} context Context from which
* elements should be fetched.
* @return {BEMQuery} New BEMQuery instance.
* @return {Iterator} Returned iterator.
*/
function factory( query, context = document ) {
const converter = factory$1();
const selectorEngine = new SelectorEngine();
const bemQuery = new BEMQuery( query, context, converter, selectorEngine );
[ Symbol.iterator ]() {
let i = 0;
const elements = this.elements;
const converter = this.converter;
const selectorEngine = this.selectorEngine;
return bemQuery;
}
return {
next() {
if ( i < elements.length ) {
const element = elements[ i++ ];
return {
value: new BEMQuery( [ element ], document, converter, selectorEngine ),
done: false
};
}
var $ = Object.freeze({
BEMQuery: BEMQuery,
default: factory
});
/** Class storing queue of DOM operations. */
class Batch {
/**
* Constructing new batch.
*
* @class
*/
constructor() {
this.read = [];
this.write = [];
}
/**
* Add new operation to the batch.
*
* @param {String} type Type of operation. Must be either "read" or "write".
* @param {Function} fn Operation to be fired.
* @return {BEMQuery} Current BEMQuery instance.
*/
add( type, fn ) {
if ( type !== 'read' && type !== 'write' ) {
throw new TypeError( 'Type must be either \'read\' or \'write\'.' );
return {
done: true
};
}
};
}
}
if ( typeof fn !== 'function' ) {
throw new TypeError( 'Task must be a function.' );
}
/**
* BEMQuery instance factory.
*
* @param {String|Iterable|HTMLElement} query Selector or
* existing elements collection upon which the new elements collection
* should be created.
* @param {Document|HTMLElement|BEMQuery} context Context from which
* elements should be fetched.
* @return {BEMQuery} New BEMQuery instance.
*/
function factory( query, context = document ) {
const converter = factory$2();
const selectorEngine = new SelectorEngine();
const bemQuery = new BEMQuery( query, context, converter, selectorEngine );
this[ type ].push( fn );
}
return bemQuery;
}
/**
* Run operations of given type.
*
* @param {String} type Type of operations to run. Must be either "read" or "write".
* @return {Promise} Promise that will be fulfilled after running all tasks.
*/
run( type = 'read' ) {
if ( type !== 'read' && type !== 'write' ) {
throw new TypeError( 'Type must be either \'read\' or \'write\'.' );
}
return new Promise( ( resolve ) => {
requestAnimationFrame( () => {
const results = [];
this[ type ].forEach( ( fn ) => {
results.push( fn() );
} );
this[ type ] = [];
var $$1 = Object.freeze({
BEMQuery: BEMQuery,
default: factory
});
return resolve( results );
} );
} );
}
}
/*! bemquery-async-dom v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Class storing queue of DOM operations. */
class Batch {
/**
* Method that runs all read operations stored in batch
* Constructing new batch.
*
* @return {Promise} Promise returned by batch.
* @memberof BEMQuery
* @class
*/
BEMQuery.prototype.read = function() {
if ( !this.batch ) {
this.batch = new Batch();
}
constructor() {
this.read = [];
this.write = [];
}
return this.batch.run( 'read' );
};
/**
* Method that runs all write operations stored in batch
* Add new operation to the batch.
*
* @return {Promise} Promise returned by batch.
* @memberof BEMQuery
* @param {String} type Type of operation. Must be either "read" or "write".
* @param {Function} fn Operation to be fired.
* @return {BEMQuery} Current BEMQuery instance.
*/
BEMQuery.prototype.write = function() {
if ( !this.batch ) {
this.batch = new Batch();
add( type, fn ) {
if ( type !== 'read' && type !== 'write' ) {
throw new TypeError( 'Type must be either \'read\' or \'write\'.' );
}
return this.batch.run( 'write' );
};
if ( typeof fn !== 'function' ) {
throw new TypeError( 'Task must be a function.' );
}
this[ type ].push( fn );
}
/**
* Method for getting/setting inner HTML of all elements in collection
* Run operations of given type.
*
* @param {String} [newHTML] The new inner HTML value. If not specified,
* the method will work as getter.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
* @param {String} type Type of operations to run. Must be either "read" or "write".
* @return {Promise} Promise that will be fulfilled after running all tasks.
*/
BEMQuery.prototype.html = function( newHTML ) {
if ( !this.batch ) {
this.batch = new Batch();
run( type = 'read' ) {
if ( type !== 'read' && type !== 'write' ) {
throw new TypeError( 'Type must be either \'read\' or \'write\'.' );
}
if ( typeof newHTML !== 'undefined' ) {
newHTML = String( newHTML );
return new Promise( ( resolve ) => {
requestAnimationFrame( () => {
const results = [];
this.batch.add( 'write', () => {
const elements = this.elements;
elements.forEach( ( element ) => {
element.innerHTML = newHTML;
this[ type ].forEach( ( fn ) => {
results.push( fn() );
} );
} );
} else {
this.batch.add( 'read', () => {
const elements = this.elements;
const htmls = [];
elements.forEach( ( element ) => {
htmls.push( element.innerHTML );
} );
this[ type ] = [];
return htmls;
return resolve( results );
} );
}
} );
}
}
return this;
};
/**
* Method that runs all read operations stored in batch
*
* @return {Promise} Promise returned by batch.
* @memberof BEMQuery
*/
BEMQuery.prototype.read = function() {
if ( !this.batch ) {
this.batch = new Batch();
}
function processClasses( converter, element ) {
const states = [];
return this.batch.run( 'read' );
};
[].forEach.call( element.classList, ( className ) => {
const state = converter.getStateFromClass( String( className ) );
/**
* Method that runs all write operations stored in batch
*
* @return {Promise} Promise returned by batch.
* @memberof BEMQuery
*/
BEMQuery.prototype.write = function() {
if ( !this.batch ) {
this.batch = new Batch();
}
if ( state ) {
states.push( state );
}
} );
return this.batch.run( 'write' );
};
return states;
/**
* Method for getting/setting inner HTML of all elements in collection
*
* @param {String} [newHTML] The new inner HTML value. If not specified,
* the method will work as getter.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.html = function( newHTML ) {
if ( !this.batch ) {
this.batch = new Batch();
}
/**
* Method for getting states from all elements in collection.
*
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.getStates = function() {
if ( !this.batch ) {
this.batch = new Batch();
}
if ( typeof newHTML !== 'undefined' ) {
newHTML = String( newHTML );
const elements = this.elements;
this.batch.add( 'write', () => {
const elements = this.elements;
elements.forEach( ( element ) => {
element.innerHTML = newHTML;
} );
} );
} else {
this.batch.add( 'read', () => {
const result = [];
const elements = this.elements;
const htmls = [];
elements.forEach( ( element ) => {
result.push( processClasses( this.converter, element ) );
htmls.push( element.innerHTML );
} );
return result;
return htmls;
} );
}
return this;
};
return this;
};
/** Storage for events listeners */
class ListenersStorage {
/**
* Creates new storage for event lsiteners
*
* @class
*/
constructor() {
this.storage = new WeakMap();
function processClasses( converter, element ) {
const states = [];
[].forEach.call( element.classList, ( className ) => {
const state = converter.getStateFromClass( String( className ) );
if ( state ) {
states.push( state );
}
} );
/**
* Adds event listener to the storage.
*
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @param {Function} listener Created listener.
* @return {void}
*/
add( element, type, selector, fn, listener ) {
let listeners = {};
return states;
}
if ( this.storage.has( element ) ) {
listeners = this.storage.get( element );
}
/**
* Method for getting states from all elements in collection.
*
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.getStates = function() {
if ( !this.batch ) {
this.batch = new Batch();
}
if ( typeof listeners[ type ] === 'undefined' ) {
listeners[ type ] = {};
}
const elements = this.elements;
if ( typeof listeners[ type ][ selector ] === 'undefined' ) {
listeners[ type ][ selector ] = [];
}
this.batch.add( 'read', () => {
const result = [];
listeners[ type ][ selector ].push( [ fn, listener ] );
elements.forEach( ( element ) => {
result.push( processClasses( this.converter, element ) );
} );
this.storage.set( element, listeners );
return result;
} );
return this;
};
/*! bemquery-dom-events v0.1.4 | (c) 2016 BEMQuery team | MIT license (see LICENSE) */
/** Storage for events listeners */
class ListenersStorage {
/**
* Creates new storage for event lsiteners
*
* @class
*/
constructor() {
this.storage = new WeakMap();
}
/**
* Adds event listener to the storage.
*
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @param {Function} listener Created listener.
* @return {void}
*/
add( element, type, selector, fn, listener ) {
let listeners = {};
if ( this.storage.has( element ) ) {
listeners = this.storage.get( element );
}
/**
* Gets event listener that matches the given criteria.
*
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @return {Function} Event listener.
*/
get( element, type, selector, fn ) {
if ( !this.storage.has( element ) ) {
return null;
}
if ( typeof listeners[ type ] === 'undefined' ) {
listeners[ type ] = {};
}
const listeners = this.storage.get( element );
if ( typeof listeners[ type ][ selector ] === 'undefined' ) {
listeners[ type ][ selector ] = [];
}
if ( typeof listeners[ type ] === 'undefined' || typeof listeners[ type ][ selector ] === 'undefined' ) {
return null;
}
listeners[ type ][ selector ].push( [ fn, listener ] );
for ( let pair of listeners[ type ][ selector ] ) { // eslint-disable-line prefer-const
if ( pair[ 0 ] === fn ) {
return pair[ 1 ];
}
}
this.storage.set( element, listeners );
}
/**
* Gets event listener that matches the given criteria.
*
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @return {Function} Event listener.
*/
get( element, type, selector, fn ) {
if ( !this.storage.has( element ) ) {
return null;
}
/**
* Removes event listener that matches the given criteria.
*
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @return {Function} Event listener.
*/
remove( element, type, selector, fn ) {
if ( !this.storage.has( element ) ) {
return null;
}
const listeners = this.storage.get( element );
const listeners = this.storage.get( element );
if ( typeof listeners[ type ] === 'undefined' || typeof listeners[ type ][ selector ] === 'undefined' ) {
return null;
}
if ( typeof listeners[ type ] === 'undefined' || typeof listeners[ type ][ selector ] === 'undefined' ) {
return null;
for ( let pair of listeners[ type ][ selector ] ) { // eslint-disable-line prefer-const
if ( pair[ 0 ] === fn ) {
return pair[ 1 ];
}
}
listeners[ type ][ selector ].forEach( ( pair, i ) => {
if ( pair[ 0 ] === fn ) {
listeners[ type ][ selector ].splice( i, 1 );
}
} );
return null;
}
return null;
}
const storage = new ListenersStorage();
/**
* Method for adding event listener to the element.
* Removes event listener that matches the given criteria.
*
* @param {String} type Type of the event.
* @param {String|Function} selector If that parameter is a string,
* then it's used to construct checking for the event delegation.
* However if function is passed, then it becomes the event's listener.
* @param {Function} callback If the second parameter is a string, this
* function will be used as an event's listener.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
* @param {Object} element Element to which listener is binded.
* @param {String} type Type of event.
* @param {String} selector Selector for event delegation.
* @param {Function} fn Original callback.
* @return {Function} Event listener.
*/
BEMQuery.prototype.on = function( type, selector, callback ) {
let listener;
if ( typeof type !== 'string' || !type ) {
throw new TypeError( 'Type of event must be a non-empty string.' );
remove( element, type, selector, fn ) {
if ( !this.storage.has( element ) ) {
return null;
}
if ( ( typeof selector !== 'string' && typeof selector !== 'function' ) || !selector ) {
throw new TypeError( 'Selector must be a non-empty string or function.' );
const listeners = this.storage.get( element );
if ( typeof listeners[ type ] === 'undefined' || typeof listeners[ type ][ selector ] === 'undefined' ) {
return null;
}
if ( typeof selector === 'string' ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
listeners[ type ][ selector ].forEach( ( pair, i ) => {
if ( pair[ 0 ] === fn ) {
listeners[ type ][ selector ].splice( i, 1 );
}
} );
selector = this.converter.convert( selector ).CSS;
selector = `${selector}, ${selector} *`;
return null;
}
}
listener = ( evt ) => {
if ( evt.target.matches( selector ) ) {
callback( evt );
}
};
} else {
listener = selector;
const storage = new ListenersStorage();
/**
* Method for adding event listener to the element.
*
* @param {String} type Type of the event.
* @param {String|Function} selector If that parameter is a string,
* then it's used to construct checking for the event delegation.
* However if function is passed, then it becomes the event's listener.
* @param {Function} callback If the second parameter is a string, this
* function will be used as an event's listener.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.on = function( type, selector, callback ) {
let listener;
if ( typeof type !== 'string' || !type ) {
throw new TypeError( 'Type of event must be a non-empty string.' );
}
if ( ( typeof selector !== 'string' && typeof selector !== 'function' ) || !selector ) {
throw new TypeError( 'Selector must be a non-empty string or function.' );
}
if ( typeof selector === 'string' ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
}
this.elements.forEach( ( element ) => {
element.addEventListener( type, listener, false );
selector = this.converter.convert( selector ).CSS;
selector = `${selector}, ${selector} *`;
if ( typeof selector === 'string' ) {
storage.add( element, type, selector, callback, listener );
listener = ( evt ) => {
if ( evt.target.matches( selector ) ) {
callback( evt );
}
} );
};
} else {
listener = selector;
}
return this;
};
this.elements.forEach( ( element ) => {
element.addEventListener( type, listener, false );
/**
* Method for removing event listener from the element.
*
* @param {String} type Type of the event.
* @param {String|Function} selector If that parameter is a string,
* then it's used to construct checking for the event delegation.
* However if function is passed, then it becomes the event's listener.
* @param {Function} callback If the second parameter is a string, this
* function will be used as an event's listener.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.off = function( type, selector, callback ) {
let listener;
if ( typeof type !== 'string' || !type ) {
throw new TypeError( 'Type of event must be a non-empty string.' );
if ( typeof selector === 'string' ) {
storage.add( element, type, selector, callback, listener );
}
} );
if ( ( typeof selector !== 'string' && typeof selector !== 'function' ) || !selector ) {
throw new TypeError( 'Selector must be a non-empty string or function.' );
return this;
};
/**
* Method for removing event listener from the element.
*
* @param {String} type Type of the event.
* @param {String|Function} selector If that parameter is a string,
* then it's used to construct checking for the event delegation.
* However if function is passed, then it becomes the event's listener.
* @param {Function} callback If the second parameter is a string, this
* function will be used as an event's listener.
* @return {BEMQuery} Current BEMQuery instance.
* @memberof BEMQuery
*/
BEMQuery.prototype.off = function( type, selector, callback ) {
let listener;
if ( typeof type !== 'string' || !type ) {
throw new TypeError( 'Type of event must be a non-empty string.' );
}
if ( ( typeof selector !== 'string' && typeof selector !== 'function' ) || !selector ) {
throw new TypeError( 'Selector must be a non-empty string or function.' );
}
if ( typeof selector === 'string' ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
}
selector = this.converter.convert( selector ).CSS;
selector = `${selector}, ${selector} *`;
} else {
listener = selector;
}
this.elements.forEach( ( element ) => {
if ( typeof selector === 'string' ) {
if ( typeof callback !== 'function' ) {
throw new TypeError( 'Callback must be a function.' );
}
listener = storage.get( element, type, selector, callback );
selector = this.converter.convert( selector ).CSS;
selector = `${selector}, ${selector} *`;
} else {
listener = selector;
storage.remove( element, type, selector, callback );
}
element.removeEventListener( type, listener, false );
} );
this.elements.forEach( ( element ) => {
if ( typeof selector === 'string' ) {
listener = storage.get( element, type, selector, callback );
return this;
};
storage.remove( element, type, selector, callback );
}
element.removeEventListener( type, listener, false );
} );
return $$1;
return this;
};
return $;
}));
})));
//# sourceMappingURL=bemquery.umd.js.map
{
"name": "bemquery",
"version": "0.1.3",
"version": "0.1.4",
"description": "BEMQuery library",

@@ -11,10 +11,27 @@ "main": "dist/bemquery.umd.js",

"test": "karma start config/karma/default.js",
"precommit": "npm test",
"commitmsg": "commitplease .git/COMMIT_EDITMSG",
"prebuild": "npm test",
"build": "rollup -c config/rollup/umd.js && rollup -c config/rollup/es6.js && rollup -c config/rollup/es5.js",
"build-docs": "jsdoc -c config/jsdoc/default.json ./src",
"publish-docs": "npm run build-docs && git checkout gh-pages && ncp docs/dist ./ && git add -A && git commit -m \"[ci skip] Updated docs.\" && git push origin gh-pages && git checkout master",
"preversion": "npm test",
"postversion": "git push origin && git push origin --tags",
"publish-docs": "npm run build-docs && git checkout gh-pages && ncp docs/dist ./ && git add -A && git commit -m \"docs(gh-pages): update docs [ci skip]\" && git push origin gh-pages && git checkout master",
"preversion": "npm run build && git add -f dist/",
"postversion": "git rm -r --cached dist/ && git commit -m \"chore(dist): clean after release [ci skip]\" && git push origin && git push origin --tags",
"prepublish": "in-publish && npm run build || exit 0"
},
"commitplease": {
"nohook": true,
"style": "angular",
"types": [
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"chore"
],
"scope": "\\S+.*"
},
"repository": {

@@ -51,9 +68,12 @@ "type": "git",

"chai": "^3.5.0",
"commitplease": "^2.7.2",
"cz-conventional-changelog": "^1.2.0",
"docdash": "^0.4.0",
"eslint": "^3.0.1",
"husky": "^0.11.7",
"in-publish": "^2.0.0",
"ink-docstrap": "^1.2.1",
"is-travis": "^1.0.0",
"jsdoc": "^3.4.0",
"karma": "^1.0.0",
"karma-chrome-launcher": "^1.0.1",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.0.0",

@@ -70,5 +90,5 @@ "karma-firefox-launcher": "^1.0.0",

"ncp": "^2.0.0",
"rollup": "^0.34.0",
"rollup": "^0.35.10",
"rollup-plugin-babel": "^2.6.1",
"rollup-plugin-commonjs": "^3.0.0",
"rollup-plugin-commonjs": "^5.0.0",
"rollup-plugin-mockr": "^1.0.1",

@@ -80,3 +100,8 @@ "rollup-plugin-node-resolve": "^2.0.0",

"uglify-js": "^2.6.2"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
# bemquery
[![Build Status](https://travis-ci.org/BEMQuery/bemquery.svg?branch=master)](https://travis-ci.org/BEMQuery/bemquery) [![Dependency Status](https://david-dm.org/BEMQuery/bemquery.svg)](https://david-dm.org/BEMQuery/bemquery) [![devDependency Status](https://david-dm.org/BEMQuery/bemquery/dev-status.svg)](https://david-dm.org/BEMQuery/bemquery#info=devDependencies)
[![Build Status](https://travis-ci.org/BEMQuery/bemquery.svg?branch=master)](https://travis-ci.org/BEMQuery/bemquery) · [![Dependency Status](https://david-dm.org/BEMQuery/bemquery.svg)](https://david-dm.org/BEMQuery/bemquery) · [![devDependency Status](https://david-dm.org/BEMQuery/bemquery/dev-status.svg)](https://david-dm.org/BEMQuery/bemquery#info=devDependencies) · [![Known Vulnerabilities](https://snyk.io/test/github/bemquery/bemquery/badge.svg)](https://snyk.io/test/github/bemquery/bemquery) ·[![Package quality](http://packagequality.com/badge/bemquery.png)](http://packagequality.com/#?package=bemquery) · [![npm version](https://badge.fury.io/js/bemquery.svg)](https://badge.fury.io/js/bemquery) · [![Bower version](https://badge.fury.io/bo/bemquery.svg)](https://badge.fury.io/bo/bemquery)

@@ -11,2 +11,3 @@ BEMQuery library.

You can install this package from npm:
```bash

@@ -16,4 +17,9 @@ npm install bemquery [--save]

You can also install it from bower:
```bash
bower install bemquery
```
## Documentation
Docs are available at http://bemquery.github.io/bemquery

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc