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

boomqueries

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

boomqueries - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

223

dist/js/boomqueries.js

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

/*! BoomQueries 0.0.3 | http://boomtownroi.github.io/boomqueries/ | (c) 2014 BoomTown | MIT License */
/*! BoomQueries 0.0.4 | http://boomtownroi.github.io/boomqueries/ | (c) 2014 BoomTown | MIT License */
(function (global, boomQueries) {

@@ -13,9 +13,18 @@ if(typeof define === 'function' && define.amd) {

var boomQueriesComponents = {};
var elementKey = 0;
function boomQuery() {
// Array of dom nodes which update their class when the window resizes
this.nodes = [];
function debounce(func, wait, immediate) {
// Hash of selectors with their corresponding break points
this.map = {};
// Dispatch our custom event when the window resizes
window.addEventListener('resize', this.debounce(this, this.update, 100), false);
}
// Rate limit the amount of times our update method gets called on window resize
boomQuery.prototype.debounce = function(context, func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var args = arguments;
var later = function() {

@@ -30,64 +39,174 @@ timeout = null;

};
}
};
function add(nameOrObject, descriptor) {
var key;
if (typeof nameOrObject === 'string') {
key = nameOrObject;
boomQueriesComponents[nameOrObject] = descriptor;
} else {
key = elementKey++;
boomQueriesComponents[key] = nameOrObject;
}
return key;
}
// Called whenever we need to ensure all nodes have their proper class
boomQuery.prototype.update = function(options) {
var details = {};
// You can pass a custom object to each node when we dispatch the event
if ( typeof options !== 'undefined' ) details["detail"] = options;
var updateEvent = new CustomEvent("checkyourself", details);
// Loop through our nodes firing a "checkyourself" event on each of them
this.nodes.forEach(function(node) {
node.dispatchEvent(updateEvent);
});
};
function remove(key) {
delete boomQueriesComponents[key];
}
// Internal function that accepts a DOM node with break points
// Adds custom properties and a listener to the node and then stores the node in an internal array
boomQuery.prototype._add = function(node, breakPoints, selector) {
// Check to ensure we aren't already tracking this node
if ( node.breaks === undefined ) {
// Store the break points array in the node
node.breaks = breakPoints;
function calculateElements() {
var componentKeys = Object.keys(boomQueriesComponents);
// If we pass a selector/name, add it to the node so we can reference it later
if ( selector !== null ) node.selector = selector;
var currentComponent;
var $elements;
// Attach an event listener with functionality to update it's own class
node.addEventListener("checkyourself", function(event) {
// event.detail is custom object if we have one
function calculateElement(element, i) {
if (element.offsetParent !== null) {
var componentBreaksCounter = currentComponent.breaks.length,
currentWidth = element.offsetWidth,
currentBreak = -1;
// Ensure we have a parent with layout to assess our offsetWidth from
if ( this.offsetParent !== null ) {
var componentBreaksCounter = this.breaks.length,
currentWidth = this.offsetWidth,
currentBreak = -1;
while (componentBreaksCounter--) {
if(currentWidth >= currentComponent.breaks[componentBreaksCounter][0]) {
currentBreak++;
while ( componentBreaksCounter-- ) {
if ( currentWidth >= this.breaks[componentBreaksCounter][0] ) {
currentBreak++;
}
this.classList.remove(this.breaks[componentBreaksCounter][1]);
}
element.classList.remove(currentComponent.breaks[componentBreaksCounter][1]);
if ( currentBreak >= 0 ) {
this.classList.add(this.breaks[currentBreak][1]);
}
// Create a custom object with details of our event to pass to our callback
var details = {
detail: {
'offsetWidth': currentWidth,
'currentBreak': this.breaks[currentBreak]
}
};
var completedEvent = new CustomEvent("nodeUpdated", details);
// You can now attach an event listener to this node to catch when we have completed the event
this.dispatchEvent(completedEvent);
}
});
if (currentBreak >= 0) {
element.classList.add(currentComponent.breaks[currentBreak][1]);
node.addEventListener("cleanup", function(event) {
var self = this;
this.breaks.forEach(function(br) {
self.classList.remove(br[1]);
});
});
// Push the node on to our stack of nodes
this.nodes.push(node);
}
};
// Internal method that accepts a css selector,
boomQuery.prototype._addSelector = function(selector, breakPoints) {
// Add selector to internal map hash for refreshing
this.map[selector] = breakPoints;
// Loop through nodes adding them internally
var nodes = document.querySelectorAll(selector), self = this;
Array.prototype.forEach.call(nodes, function(node) {
self._add(node, breakPoints, selector);
});
};
// Main method for external use
// Can add a css selector or DOM node as first par
// Breakpoints is a multi dimensional array containing an offsetWidth int and a corresponding class name
// Name is an optional parameter that allows you to specify or name a DOM node
boomQuery.prototype.add = function (selector, breakPoints, name) {
if ( typeof selector === 'string' ) {
this._addSelector(selector, breakPoints);
} else {
var id = null, self = this;
if ( name !== 'undefined' ) id = name;
if ( selector.constructor === Array ) {
selector.forEach(function(node){
self._add(node, breakPoints, id);
});
} else {
this._add(selector, breakPoints, id);
}
}
this.update();
};
// Call refresh method when new DOM elements have been added
boomQuery.prototype.refresh = function() {
// First let's remove any nodes which have been removed from DOM
this.remove();
// Now we need to roll through css selectors and requery them to see if there are a new nodes we need to consume
var selectors = Object.keys(this.map), self = this;
selectors.forEach(function(selector) {
self._addSelector(selector, self.map[selector]);
});
this.update();
};
// Internal method to stay DRY
boomQuery.prototype._delete = function(i) {
// Remove event listener before discarding to avoid zombies
this.nodes[i].dispatchEvent(new CustomEvent("cleanup"));
this.nodes[i].removeEventListener("checkyourself");
this.nodes[i].removeEventListener("cleanup");
this.nodes.splice(i, 1);
return true;
};
// Remove internal nodes based on selector or it's presence in the DOM
boomQuery.prototype.remove = function(selector) {
// Remove node based on selector or unique name provided
if ( selector !== undefined ) {
for ( var i = this.nodes.length; i--; ) {
if ( this.nodes[i].selector === selector ) {
this._delete(i);
}
}
// Make sure our selector map actually has selector before deleting
// If we pass an ID of DOM node to delete, it won't be contained in our selector map
if ( this.map.hasOwnProperty(selector) ) delete this.map[selector];
// If a selector is not passed, let's remove the node if it is no longer in the DOM
} else {
for ( var i = this.nodes.length; i--; ) {
if ( !document.body.contains(this.nodes[i]) ) {
this._delete(i);
}
}
}
};
componentKeys.forEach(function(key) {
currentComponent = boomQueriesComponents[key];
if (currentComponent.selector) {
$elements = document.querySelectorAll(currentComponent.selector);
} else if (currentComponent.element) {
$elements = [currentComponent.element];
boomQuery.prototype.get = function(selector) {
// Loop through internal array of nodes
for ( var i = this.nodes.length; i--; ) {
if ( this.nodes[i].selector === selector ) {
return this.nodes[i];
}
Array.prototype.forEach.call($elements, calculateElement);
});
}
}
};
window.addEventListener('load', calculateElements);
window.addEventListener('resize', debounce(calculateElements, 100), false);
// Just logs the internal array of nodes for debug/inspection
// You can specify which internal store you want to inspect: map or nodes
boomQuery.prototype.inspect = function(which) {
if ( typeof console !== "undefined" ) {
if ( which === 'map' ) console.log(this.map);
else console.log(this.nodes);
}
};
return {
add: add,
remove: remove,
calculate: calculateElements
};
}));
return new boomQuery();
}));

@@ -5,3 +5,3 @@ {

"description": "BoomQueries is our take on element-queries; sizing elements based on their container.",
"version": "0.0.3",
"version": "0.0.4",
"homepage": "http://boomtownroi.github.io/boomqueries/",

@@ -25,3 +25,3 @@ "author": {

"type": "MIT",
"url": "https://github.com/boomtownroi/boomqueries/blog/master/LICENSE.md"
"url": "https://github.com/BoomTownROI/boomqueries/blob/master/LICENSE.md"
}

@@ -37,3 +37,2 @@ ],

"gulp-less": "^1.3.6",
"gulp-livereload": "^2.1.1",
"gulp-rename": "^1.2.0",

@@ -40,0 +39,0 @@ "gulp-uglify": "^1.0.1",

# BoomQueries
BoomQueries is our take on element-queries; sizing elements based on their container.
BoomQueries is our take on element queries; sizing elements based on their container.

@@ -22,31 +22,80 @@ As our product has grown to be more modular, we began to see the limitations of sizing those modular components across more granular scopes; main content areas, sidebars, etc. And most of all, the specificities of keeping up with all these variations started to take a toll on productivity and maintenance. While there are other implementations, we didn't find any that quite fit our needs. The benefits of our version are:

Please see tests/kitchensink.html for a thorough example of usage.
## Initializing/Adding Components
Use `window.boomQueries.add()` to register your component(s) with the BoomQueries library. Each instance can house a `key`; can be used to interact after it has been registered, a `selector`, and a `breaks` array, which holds references to your desired `min-width` breakpoint and the class to be added to your component.
Use `boomQueries.add()` to register your component(s) with the BoomQueries library.
window.boomQueries.add("COMPONENTKEY", {
selector: ".component",
breaks: [
boomQueries.add('.component', [
[480, "component--md"],
[600, "component--lg"]
]
});
]);
Once you have added your components, you can initialize BoomQueries with:
You can also register DOM nodes.
window.boomQueries.calculate();
var component = document.createElement('div');
boomQueries.add(component, [
[480, "component--md"],
[600, "component--lg"]
]);
When registering DOM nodes, you can pass an additional third parameter, id, to reference your node later in the application.
var component = document.createElement('div');
boomQueries.add(component, [
[480, "component--md"],
[600, "component--lg"]
], 'myComponent');
// boomQueries.get('myComponent') you can get your node
// boomQueries.remove('myComponent') you can remove your node
You can also bulk add DOM nodes.
var components = [document.createElement('div'), document.createElement('div'), document.createElement('div'), document.createElement('div')];
boomQueries.add(components, [
[480, "component--md"],
[600, "component--lg"]
], 'myComponents');
// boomQueries.remove('myComponents') to remove them
## Refreshing Components
When you are working with a dynamic application that has lots of DOM changes, you should refresh your boomQueries after change.
boomQueries.refresh();
The refresh method will remove event listeners from watched nodes that are no longer in the DOM and grab newly added elements based on their css selector.
## Component Callback
There are times when you would want to fire additional functionality on a node after it's been updated. You can do this by attaching a custom event listener to that node.
var component = document.createElement('div');
document.body.appendChild(component);
component.addEventListener('nodeUpdated', function(event){
console.log(event.detail);
});
We pass the callback an object about the recent update: 'offsetWidth' and 'currentBreak'
## Removing Components
You can remove components registered by BoomQueries by calling the `remove` method and specifying your component `key`.
You can remove components registered by BoomQueries by calling the `remove` method and specifying either your custom id or css selector.
window.boomQueries.remove("COMPONENTKEY");
boomQueries.remove('myComponent');
_You can freely add/remove components as needed throughout your app, so don't feel that you need to register them all at once!_
## Working with Dynamic Content
Using Backbone, Angular, React, etc. to dynamically interact with DOM elements? You can easily "refresh" BoomQueries by calling the `calculate()` method again:
Using Backbone, Angular, React, etc. to dynamically interact with DOM elements? You can easily "refresh" BoomQueries by calling the `refresh()` method again:
window.boomQueries.calculate();
boomQueries.refresh();

@@ -60,15 +109,34 @@ ## CommonJS Usage

boomQueries.add("COMPONENTKEY", {
selector: ".component",
breaks: [
[480, "component--md"],
[600, "component--lg"]
]
});
boomQueries.add(".component", [
[480, "component--md"],
[600, "component--lg"]
]);
boomQueries.remove("COMPONENTKEY");
boomQueries.remove(".component");
boomQueries.calculate();
boomQueries.refresh();
```
## Internal Inspection
If you need to see what nodes are currently being watched, you can log `boomQueries.inspect()`
If you need to see which css selectors are being followed/refreshed, you can log `boomQueries.inspect('map')`
And although it is not recommended, you can access the internal data for debugging purposes:
`boomQueries.nodes`
`boomQueries.map`
## Contributing
Have something you want to add to BoomQueries? Great! Here's a few helpful tips to get started:
_We use [GulpJS](http://gulpjs.com) to compile BoomQueries, so make sure you have that and [Node.js](http://nodejs.org/) installed._
* Clone the repo, `git clone git://github.com/boomtownroi/boomqueries.git`
* `npm install` to add-in Gulp dependencies
* `gulp server` to fire up a browser (using [BrowserSync](http://www.browsersync.io/)) which will take care of compiling and reloading the page.
## Versioning

@@ -80,2 +148,2 @@

Copyright 2014 [BoomTown](http://boomtownroi.com) under the [MIT License](https://github.com/boomtownroi/boomqueries/blob/LICENSE.md)
Copyright 2014 [BoomTown](http://boomtownroi.com) under the [MIT License](https://github.com/BoomTownROI/boomqueries/blob/master/LICENSE.md)
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