Skip to content

Commit

Permalink
Merge pull request #25 from Snugug/jehlification
Browse files Browse the repository at this point in the history
Jehlification
  • Loading branch information
Snugug committed Dec 3, 2014
2 parents 1e810ec + 79c9aed commit 9231673
Show file tree
Hide file tree
Showing 11 changed files with 7,198 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
source 'https://rubygems.org'
gem "compass", ">=0.13.alpha.7"
gem "compass", "~>1.0"
32 changes: 16 additions & 16 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
GEM
remote: https://rubygems.org/
specs:
chunky_png (1.2.9)
compass (0.13.alpha.7)
chunky_png (1.3.3)
compass (1.0.1)
chunky_png (~> 1.2)
json
listen (~> 1.1.0)
sass (~> 3.3.0.rc.1)
ffi (1.9.0)
json (1.8.1)
listen (1.1.6)
compass-core (~> 1.0.1)
compass-import-once (~> 1.0.5)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
rb-fsevent (0.9.3)
rb-inotify (0.9.2)
sass (>= 3.3.13, < 3.5)
compass-core (1.0.1)
multi_json (~> 1.0)
sass (>= 3.3.0, < 3.5)
compass-import-once (1.0.5)
sass (>= 3.2, < 3.5)
ffi (1.9.6)
multi_json (1.10.1)
rb-fsevent (0.9.4)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rb-kqueue (0.2.0)
ffi (>= 0.5.0)
sass (3.3.0.rc.1)
listen (~> 1.1.0)
sass (3.4.9)

PLATFORMS
ruby

DEPENDENCIES
compass (>= 0.13.alpha.7)
compass (~> 1.0)
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# eq.js [![Analytics](https://ga-beacon.appspot.com/UA-46859145-2/snugug/eq.js?pixel)](https://github.com/snugug/eq.js) [![Bower version](https://badge.fury.io/bo/eq.js.svg)](http://badge.fury.io/bo/eq.js) [![devDependency Status](https://david-dm.org/Snugug/eq.js/dev-status.svg)](https://david-dm.org/Snugug/eq.js#info=devDependencies)
# eq.js [![Code Climate](https://codeclimate.com/github/Snugug/eq.js/badges/gpa.svg)](https://codeclimate.com/github/Snugug/eq.js) [![Bower version](https://badge.fury.io/bo/eq.js.svg)](http://badge.fury.io/bo/eq.js)
### Element queries, fast and light

Element queries are the "holy grail" of responsive web design, allowing you to create a single component that can be dropped into any position in any layout and have them respond appropriately. Unfortunately, due to some hard-to-deal-with chicken-and-egg cases, especially involving inline elements, it's unlikely that element queries will make it into browsers any time soon.

**eq.js** aims to be a relatively easy to use drop-in solution to JavaScript powered element queries. Weighing in at about 2.8KB minified, less than 1.2KB gzipped, and requiring no external dependencies, **eq.js** sets itself apart through size, speed, and ease of use. Simply drop **eq.js** on to your site and set the `eq-pts` attribute to your element and you're ready to go!
**eq.js** aims to be a relatively easy to use drop-in solution to JavaScript powered element queries. Weighing in at about 3.3KB minified, around 1.3KB gzipped, and requiring no external dependencies, **eq.js** sets itself apart through size, speed, and ease of use. Simply drop **eq.js** on to your site and set the `eq-pts` attribute of your element (or set your points in Sass) and you're ready to go!

## Installation

Expand All @@ -17,17 +17,37 @@ Then, add either `eq.js` or `eq.min.js` to your HTML, and you're ready to rock!

## Usage

In order to use **eq.js**, you need to both include `eq.js` on your site and set up the `data-eq-pts` attribute on your desired element. `data-eq-pts` needs to be written in `key: value` pairs separated by a comma `,`, with the key being the human-readable name of the applied state and the value being the `min-width` pixel width of the element you would like to set the state at.
In order to use **eq.js**, you need to include `eq.js` on your site. Setting up element queries can be done in one of two ways: the first is to set up a `data-eq-pts` attribute on your desired element and the second is to use the `eq-pts` mixin in Sass. The first way is preferred, as it is faster for JavaScript to parse and can fire on `DOMContentLoaded` whereas the second way is slower and can only be fired on window `load`, increasing the likelihood of a flash of unstyled content.

Both methods have you write `key: value` pairs, with the key being the human-readable name of the applied state and the value being the `min-width` pixel width of the element you would like to set the state at.

With the first method, the value of `data-eq-pts` should be each pair and should be separated by a comma `,`.

```html
<div class="component" data-eq-pts="small: 400, medium: 600, large: 900">
<h1>Hello World</h1>
</div>
```

Similarly, with the second method, the `eq-pts` mixin is called with a map of your pairs. It is important not to quote your keys in the Sass map, or wonky things may happen in the parsing. At the bottom of your stylesheet, after all of your `eq-pts` have been called, you also need to call the `eq-selectors` mixin in order to write out the hook for **eq.js**.

```scss
.component {
@include eq-pts((
small: 400,
medium: 500,
large: 700
));
}

// ... at the end of the stylesheet

@include eq-selectors;
```

When **eq.js** has determined which state your element is in, it will add an `data-eq-state` attribute to the element set to the human-readable name of the `min-width` specified. If the element is smaller than the smallest state, there will be no `data-eq-state` attribute. If you did not write your states in order, fear not, they will be sorted for you.

**eq.js** also adds `window.eqjs` to allow you to utilize **eq.js** in your own function calls. It will handle your `onload` event and all `resize` events, querying your DOM to determine what nodes need to be queried each time. If you AJAX in any nodes that you would like to query, you need to trigger the query yourself. This is easy though! Just load up your nodes into an array or a NodeList and pass that to `eqjs.query(nodes)`, and **eq.js** will work its magic. `eqjs.query()` also allows for a callback function that will be fired after all updates have been applied. `eqjs.query()` also takes a callback as a second argument with optional `nodes` parameter (for the nodes that were worked on) that will be fired once all of the nodes have been processed.
**eq.js** also adds `window.eqjs` to allow you to utilize **eq.js** in your own function calls. It will handle your `DOMContentLoaded` and `load` events as well as all `resize` events, inspecting your DOM to determine what nodes need to be queried each time. If you AJAX in any nodes that you would like to query, you need to trigger the **eq.js** yourself. This is easy though! Just load up your nodes into an array or a NodeList and pass that to `eqjs.query(nodes)`, and **eq.js** will work its magic. `eqjs.query()` also allows for a callback function that will be fired after all updates have been applied. `eqjs.query()` also takes a callback as a second argument with optional `nodes` parameter (for the nodes that were worked on) that will be fired once all of the nodes have been processed.

From there, proceed with styling as normal! Because **eq.js** uses attributes, you're going to want to select using attribute selectors. Styling follows the same patters as normal `min-width` media query styling, with styling for the base first, then subsequent styling added on top:

Expand Down Expand Up @@ -145,10 +165,6 @@ add_import_path "bower_components/eq.js/sass"

**Caveats**: On the current test site in IE8, the correct attributes get applied and the correct CSS gets applied (check in the developer tools, be sure to refresh the HTML after you've loaded the page or it'll appear as if they haven't!), but the correct paint doesn't get applied. I'm not entirely sure this is why, I guess this is due to the number of nodes, but really I've got no idea why it doesn't repaint properly.

## Todo

* Provide Sass mixins and CSS API to reduce what needs to be controlled in HTML (maybe)

## Technical Mumbo Jumbo

**eq.js** has been tested in all modern browsers with thousands of nodes all requesting element queries. The limiting factor performance wise is JavaScript's native `offsetWidth` calculation, which is required for each element; hey, it's an element query after all! We work on reducing read/write layout thrashing by grouping reads separately from writes.
Expand Down
54 changes: 50 additions & 4 deletions build/eq.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@
}
}

/*
* Parse Before
*
* Reads `:before` content and splits it at the comma
* From http://jsbin.com/ramiguzefiji/1/edit?html,css,js,output
*/
function parseBefore(elem) {
return window.getComputedStyle(elem, ':before').getPropertyValue('content').slice(1, -1);
}

/*
* Merges two node lists together.
*
* From http://stackoverflow.com/questions/914783/javascript-nodelist/17262552#17262552
*/
var mergeNodes = function(a, b) {
return [].slice.call(a).concat([].slice.call(b));
};

/*
* Query
*
Expand Down Expand Up @@ -114,7 +133,15 @@
points.push(proto.sortObj(nodes[i].getAttribute('data-eq-pts')));
}
catch (e) {
points.push({});
try {
points.push(proto.sortObj(parseBefore(nodes[i])));
}
catch (e2) {
points.push([{
key: '',
value: 0
}]);
}
}
}

Expand Down Expand Up @@ -210,8 +237,19 @@
* Refreshes the list of nodes for eqjs to work with
*/
EQjs.prototype.refreshNodes = function () {
var proto = Object.getPrototypeOf(eqjs);
var proto = Object.getPrototypeOf(eqjs),
cssNodes = [];

proto.nodes = document.querySelectorAll('[data-eq-pts]');

cssNodes = parseBefore(document.querySelector('html')).split(', ');
cssNodes.forEach(function (v) {
if (v !== '') {
proto.nodes = mergeNodes(proto.nodes, document.querySelectorAll(v));
}
});


proto.nodesLength = proto.nodes.length;
};

Expand Down Expand Up @@ -242,9 +280,9 @@
eqjs = eqjs || new EQjs();

/*
* Window Onload
* Document Loaded
*
* Fires on load
* Fires on document load; for HTML based EQs
*/
if (domready) {
domready(function () {
Expand All @@ -259,6 +297,14 @@
});
}

/*
* Window Loaded
*/
addEvent(window, 'load', function () {
eqjs.refreshNodes();
eqjs.query(undefined, true);
});

/*
* Window Resize
*
Expand Down
25 changes: 25 additions & 0 deletions config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'compass/import-once/activate'
# Require any additional compass plugins here.

# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "build"

# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed

# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true

# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false


# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
17 changes: 17 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* line 8, ../sass/style.scss */
div div {
box-sizing: border-box;
border-width: 2px;
Expand All @@ -7,25 +8,41 @@ div div {
border-color: red;
background-color: rgba(255, 0, 0, 0.25);
}
/* line 47, ../sass/_eq.scss */
div div:before {
display: none;
content: "small: 300, medium: 500, large: 700";
}
/* line 27, ../sass/_eq.scss */
div div[data-eq-state="small"] {
border-color: green;
background-color: rgba(0, 128, 0, 0.25);
}
/* line 27, ../sass/_eq.scss */
div div[data-eq-state="medium"] {
border-color: orange;
background-color: rgba(255, 165, 0, 0.25);
}
/* line 27, ../sass/_eq.scss */
div div[data-eq-state="large"] {
border-color: blue;
background-color: rgba(0, 0, 255, 0.25);
}

/* line 34, ../sass/style.scss */
#left {
width: 65%;
float: left;
}

/* line 39, ../sass/style.scss */
#right {
width: 35%;
float: right;
}

/* line 64, ../sass/_eq.scss */
html:before {
display: none;
content: "div div";
}
Binary file modified dist/eq.gz.js
Binary file not shown.
2 changes: 1 addition & 1 deletion dist/eq.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9231673

Please sign in to comment.