Skip to content

Commit

Permalink
new features for the exposed function
Browse files Browse the repository at this point in the history
  • Loading branch information
jgnewman committed Jun 30, 2016
1 parent f7578e3 commit ba3dee4
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 41 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,22 @@ To use retina.js the old-school way, download **retina.min.js** and put it on yo

Using this technique, retina.js will run automatically on page load. It will also create a globally available function called `retinajs`. Whenever you'd like to manually re-initialize the script, simply call `window.retinajs()`.

If you don't pass any arguments to the `retinajs` function, it will only attempt to process images that have not previously been processed by the script. Optionally, you can pass a collection of HTML elements to the script, in which case it will only attempt to process elements in that collection, specifically the ones that have not been processed before. Your collection may take the form of an Array, NodeList, or jQuery selection.

```javascript
retinajs();
// Finds all images not previously processed and processes them.

retinajs( [img, img, img] );
// Only attempts to process the images in the collection.

retinajs( $('img') );
// Same.

retinajs( document.querySelectorAll('img') );
// Same.
```

#### New-School

To use retina.js the new-school way, you'll want to `require` it (or `import` it if you're using ES6) into your Gulp/Webpack/Grunt/CommonJS/etc application. In this case, the script won't run automatically. Instead, it'll let you determine when you'd like it to run.
Expand All @@ -197,6 +213,22 @@ window.addEventListener('load', retina);

Notice that the `retina` function can be called as often as you need in order to re-initialize the image swapping.

If you don't pass any arguments to the `retina` function, it will only attempt to process images that have not previously been processed by the script. Optionally, you can pass a collection of HTML elements to the script, in which case it will only attempt to process elements in that collection, specifically the ones that have not been processed before. Your collection may take the form of an Array, NodeList, or jQuery selection.

```javascript
retina();
// Finds all images not previously processed and processes them.

retina( [img, img, img] );
// Only attempts to process the images in the collection.

retina( $('img') );
// Same.

retina( document.querySelectorAll('img') );
// Same.
```

### CSS Preprocessors

The process for including the CSS mixins is relatively straightforward. Here is a breakdown for each:
Expand Down
73 changes: 54 additions & 19 deletions dist/retina.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Retina.js v2.0.0
* Retina.js v2.1.0
*
* Copyright 2016 Axial, LLC
* Released under the MIT license
Expand Down Expand Up @@ -34,6 +34,22 @@ var inlineReplace = /url\(('|")?([^\)'"]+)('|")?\)/i;
*/
var selector = '[data-rjs]';

/*
* Define the attribute we'll use to mark an image as having been processed.
*/
var processedAttr = 'data-rjs-processed';

/**
* Shortcut for turning some iterable object into an array.
*
* @param {Iterable} object Any iterable object.
*
* @return {Array}
*/
function arrayify(object) {
return Array.prototype.slice.call(object);
}

/**
* Chooses the actual image size to fetch, (for example 2 or 3) that
* will be used to create a suffix like "@2x" or "@3x".
Expand Down Expand Up @@ -120,6 +136,11 @@ function setSourceIfAvailable(image, retinaURL) {
* image resource.
*/
testImage.setAttribute('src', retinaURL);

/*
* Mark our image as processed so that it won't be processed again.
*/
image.setAttribute(processedAttr, true);
}

/**
Expand Down Expand Up @@ -164,10 +185,17 @@ function manualSwapImage(image, src, hdsrc) {
* Collects all images matching our selector, and converts our
* NodeList into an Array so that Array methods will be available to it.
*
* @return {Array} Contains all elements matching our selector.
* @param {Iterable} images Optional. An Array, jQuery selection, or NodeList
* of elements to affect with retina.js.
*
* @return {Iterable} Contains all elements matching our selector.
*/
function getImages() {
return typeof document !== 'undefined' ? Array.prototype.slice.call(document.querySelectorAll(selector)) : [];
function getImages(images) {
if (!images) {
return typeof document !== 'undefined' ? arrayify(document.querySelectorAll(selector)) : [];
} else {
return typeof images.forEach === 'function' ? images : arrayify(images);
}
}

/**
Expand All @@ -186,23 +214,30 @@ function cleanBgImg(img) {
* retina equivalent taking into account the environment capabilities and
* the densities for which the user has provided images.
*
* @param {Iterable} images Optional. An Array, jQuery selection, or NodeList
* of elements to affect with retina.js. If not
* provided, retina.js will grab all images on the
* page.
*
* @return {undefined}
*/
function retina() {
getImages().forEach(function (img) {
var isImg = img.nodeName.toLowerCase() === 'img';
var src = isImg ? img.getAttribute('src') : cleanBgImg(img);
var rjs = img.getAttribute('data-rjs');
var rjsIsNumber = !isNaN(parseInt(rjs, 10));

/*
* If the user provided a number, dynamically swap out the image.
* If the user provided a url, do it manually.
*/
if (rjsIsNumber) {
dynamicSwapImage(img, src, rjs);
} else {
manualSwapImage(img, src, rjs);
function retina(images) {
getImages(images).forEach(function (img) {
if (!img.getAttribute(processedAttr)) {
var isImg = img.nodeName.toLowerCase() === 'img';
var src = isImg ? img.getAttribute('src') : cleanBgImg(img);
var rjs = img.getAttribute('data-rjs');
var rjsIsNumber = !isNaN(parseInt(rjs, 10));

/*
* If the user provided a number, dynamically swap out the image.
* If the user provided a url, do it manually.
*/
if (rjsIsNumber) {
dynamicSwapImage(img, src, rjs);
} else {
manualSwapImage(img, src, rjs);
}
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion dist/retina.min.js

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "retinajs",
"version": "2.0.1",
"version": "2.1.0",
"license": "MIT",
"homepage": "https://github.com/imulus/retinajs",
"bugs": "https://github.com/imulus/retinajs/issues",
Expand Down
75 changes: 55 additions & 20 deletions src/retina.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ const inlineReplace = /url\(('|")?([^\)'"]+)('|")?\)/i;
*/
const selector = '[data-rjs]';

/*
* Define the attribute we'll use to mark an image as having been processed.
*/
const processedAttr = 'data-rjs-processed';

/**
* Shortcut for turning some iterable object into an array.
*
* @param {Iterable} object Any iterable object.
*
* @return {Array}
*/
function arrayify(object) {
return Array.prototype.slice.call(object);
}

/**
* Chooses the actual image size to fetch, (for example 2 or 3) that
* will be used to create a suffix like "@2x" or "@3x".
Expand Down Expand Up @@ -106,6 +122,11 @@ function setSourceIfAvailable(image, retinaURL) {
* image resource.
*/
testImage.setAttribute('src', retinaURL);

/*
* Mark our image as processed so that it won't be processed again.
*/
image.setAttribute(processedAttr, true);
}

/**
Expand Down Expand Up @@ -148,12 +169,19 @@ function manualSwapImage(image, src, hdsrc) {
* Collects all images matching our selector, and converts our
* NodeList into an Array so that Array methods will be available to it.
*
* @return {Array} Contains all elements matching our selector.
* @param {Iterable} images Optional. An Array, jQuery selection, or NodeList
* of elements to affect with retina.js.
*
* @return {Iterable} Contains all elements matching our selector.
*/
function getImages() {
return typeof document !== 'undefined' ? Array.prototype.slice.call(
document.querySelectorAll(selector)
) : [];
function getImages(images) {
if (!images) {
return typeof document !== 'undefined' ? arrayify(
document.querySelectorAll(selector)
) : [];
} else {
return typeof images.forEach === 'function' ? images : arrayify(images);
}
}

/**
Expand All @@ -172,23 +200,30 @@ function cleanBgImg(img) {
* retina equivalent taking into account the environment capabilities and
* the densities for which the user has provided images.
*
* @param {Iterable} images Optional. An Array, jQuery selection, or NodeList
* of elements to affect with retina.js. If not
* provided, retina.js will grab all images on the
* page.
*
* @return {undefined}
*/
function retina() {
getImages().forEach(img => {
const isImg = img.nodeName.toLowerCase() === 'img';
const src = isImg ? img.getAttribute('src') : cleanBgImg(img);
const rjs = img.getAttribute('data-rjs');
const rjsIsNumber = !isNaN(parseInt(rjs, 10));

/*
* If the user provided a number, dynamically swap out the image.
* If the user provided a url, do it manually.
*/
if (rjsIsNumber) {
dynamicSwapImage(img, src, rjs);
} else {
manualSwapImage(img, src, rjs);
function retina(images) {
getImages(images).forEach(img => {
if (!img.getAttribute(processedAttr)) {
const isImg = img.nodeName.toLowerCase() === 'img';
const src = isImg ? img.getAttribute('src') : cleanBgImg(img);
const rjs = img.getAttribute('data-rjs');
const rjsIsNumber = !isNaN(parseInt(rjs, 10));

/*
* If the user provided a number, dynamically swap out the image.
* If the user provided a url, do it manually.
*/
if (rjsIsNumber) {
dynamicSwapImage(img, src, rjs);
} else {
manualSwapImage(img, src, rjs);
}
}
});
}
Expand Down

0 comments on commit ba3dee4

Please sign in to comment.