Skip to content

Commit

Permalink
bumped version number
Browse files Browse the repository at this point in the history
  • Loading branch information
amorey committed Sep 22, 2017
1 parent 283e77a commit 6b1d26b
Show file tree
Hide file tree
Showing 14 changed files with 268 additions and 32 deletions.
196 changes: 196 additions & 0 deletions #README.md#
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Sentineljs

<img src="https://www.muicss.com/static/images/sentinel.svg" width="250px">

SentinelJS is a tiny JavaScript library that lets you detect new DOM nodes using CSS selectors (682 bytes).

## Introduction

SentinelJS is a tiny JavaScript library that makes it easy to set up a watch function that will notify you anytime a new node is added to the DOM that matches a given CSS rule. Among other things, you can take advantage of this to implement custom-elements and make other in-place modifications to new DOM elements:

```html
<script>
sentinel.on('custom-element', function(el) {
// A new <custom-element> has been detected
el.innerHTML = 'The sentinel is always watching.';
});
</script>
<custom-element></custom-element>
```

SentinelJS uses dynamically-defined CSS animation rules (`@keyframes`) to hook into browser `animationstart` events when a new node matching a given CSS selector is added to the DOM. In general this should be more performant than using a Mutation Observer to watch the entire `document` tree for changes and iterating through all new child nodes recursively. SentinelJS performs one hash key lookup on calls to the `animationstart` event so the performance overhead is minimal. If you define the `animation-name` property on a CSS rule that overlaps with the selector in your SentinelJS watch function then only one of those animations will be called which could cause unexpected behavior. To get around this you can use the `extraAnimations` argument to SentinelJS to add extra animation names to the SentinelJS CSS.

The latest version of SentinelJS can be found in the `dist/` directory in this repository:
* [sentinel.js](https://raw.githubusercontent.com/muicss/sentineljs/master/dist/sentinel.js)
* [sentinel.min.js](https://raw.githubusercontent.com/muicss/sentineljs/master/dist/sentinel.min.js)

You can also use it as a CJS or AMD module:

```bash
$ npm install --save sentinel-js
```

```javascript
var sentinel = require('sentinel-js');

sentinel.on('custom-element', function(el) {
// A new <custom-element> has been detected
el.innerHTML = 'The sentinel is always watching.';
});
```

SentinelJS is 682 bytes (minified + gzipped).

## Quickstart

```html
<!doctype html>
<html>
<head>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.1/dist/sentinel.min.js"></script>
<script>
// use the `sentinel` global object
sentinel.on('.my-div', function(el) {
el.innerHTML = 'The sentinel is always watching.';
});

// add a new div to the DOM
function addDiv() {
var newEl = document.createElement('div');
newEl.className = 'my-div';
document.body.appendChild(newEl);
};
</script>
</head>
<body>
<button onclick="addDiv();">Add another DIV</button>
<div class="my-div"></div>
</body>
</html>
```

[View Demo &raquo;](https://jsfiddle.net/muicss/rbqLbjzf/)

## Browser Support

* IE10+
* Opera 12+
* Safari 5+
* Chrome
* Firefox
* iOS 6+
* Android 4.4+

## Documentation

### API

#### on() - Add a watch for new DOM nodes

```
on(cssSelectors, callbackFn[, extraAnimation])

* cssSelectors {Array or String} - A single selector string or an array
* callbackFn {Function} - The callback function
* extraAnimation {String} - Trigger extra animations (e.g. "anim1, anim2") (optional)

Examples:

1. Set up a watch for a single CSS selector:

sentinel.on('.my-div', function(el) {
// add an input box
var inputEl = document.createElement('input');
el.appendChild(inputEl);
});

2. Set up a watch for multiple CSS selectors:

sentinel.on(['.my-div1', '.my-div2'], function(el) {
// add an input box
var inputEl = document.createElement('input');
el.appendChild(inputEl);
});

3. Trigger extra animations:

sentinel.on('.my-div', function(el) {
// add an input box
var inputEl = document.createElement('input');
el.appendChild(inputEl);
}, 'anim1, anim2');
```

#### off() - Remove a watch or a callback

```
off(cssSelectors[, callbackFn])

* cssSelectors {Array or String} - A single selector string or an array
* callbackFn {Function} - The callback function you want to remove the watch for (optional)

Examples:

1. Remove a callback:

function myCallback(el) { /* do something awesome */ }

// add listener
sentinel.on('.my-div', myCallback);

// remove listener
sentinel.off('.my-div', myCallback);

2. Remove a watch:

// add multiple callbacks
sentinel.on('.my-div', function fn1(el) {});
sentinel.on('.my-div', function fn2(el) {});

// remove all callbacks
sentinel.off('.my-div');
```

#### reset() - Remove all watches and callbacks

```
reset()

Examples:

1. Remove all watches and callbacks from the sentinel library:

// add multiple callbacks
sentinel.on('.my-div1', function fn1(el) {});
sentinel.on('.my-div2', function fn2(el) {});

// remove all watches and callbacks
sentinel.reset();
```

### Async Loading

To make it easy to use SentinelJS asynchronously, the library dispatches a `sentinel-load` event that will notify you when the library is ready to be used:

```html
<!doctype html>
<html>
<head>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.1/dist/sentinel.min.js" async></script>
<script>
// use the `sentinel-load` event to detect load time
document.addEventListener('sentinel-load', function() {
// now the `sentinel` global object is available
sentinel.on('.my-div', function(el) {
el.innerHTML = 'The sentinel is always watching.';
});
});
</script>
</head>
<body>
<div class="my-div"></div>
</body>
</html>
```

Icons made by [Freepik](http://www.freepik.com) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/)
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# SentinelJS Changelog

## 0.0.2 - September 22, 2017

* New release to update NPM README

## 0.0.1 - September 18, 2017

* First release
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ SentinelJS is 682 bytes (minified + gzipped).
<!doctype html>
<html>
<head>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.1/dist/sentinel.min.js"></script>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.2/dist/sentinel.min.js"></script>
<script>
// use the `sentinel` global object
sentinel.on('.my-div', function(el) {
Expand Down Expand Up @@ -176,7 +176,7 @@ To make it easy to use SentinelJS asynchronously, the library dispatches a `sent
<!doctype html>
<html>
<head>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.1/dist/sentinel.min.js" async></script>
<script src="//cdn.rawgit.com/muicss/sentineljs/0.0.2/dist/sentinel.min.js" async></script>
<script>
// use the `sentinel-load` event to detect load time
document.addEventListener('sentinel-load', function() {
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sentinel-js",
"version": "0.0.1",
"version": "0.0.2",
"license": "MIT",
"authors": [
"Andres Morey <[email protected]>"
Expand Down
10 changes: 5 additions & 5 deletions dist/sentinel.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ function resetFn() {
* @param {Event} ev - The DOM event
*/
function animationStartHandler(ev) {
var callbacks = animationCallbacks[ev.animationName] || [],
l = callbacks.length;

// exit if a callback hasn't been registered
if (!l) return;
var callbacks = animationCallbacks[ev.animationName];

// exit if callbacks haven't been registered
if (!callbacks) return;

// stop other callbacks from firing
ev.stopImmediatePropagation();

// iterate through callbacks
var l = callbacks.length;
for (var i=0; i < l; i++) callbacks[i](ev.target);
}

Expand Down
2 changes: 1 addition & 1 deletion dist/sentinel.min.js

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

10 changes: 5 additions & 5 deletions dist/sentinel.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,16 @@ function resetFn() {
* @param {Event} ev - The DOM event
*/
function animationStartHandler(ev) {
var callbacks = animationCallbacks[ev.animationName] || [],
l = callbacks.length;

// exit if a callback hasn't been registered
if (!l) return;
var callbacks = animationCallbacks[ev.animationName];

// exit if callbacks haven't been registered
if (!callbacks) return;

// stop other callbacks from firing
ev.stopImmediatePropagation();

// iterate through callbacks
var l = callbacks.length;
for (var i=0; i < l; i++) callbacks[i](ev.target);
}

Expand Down
10 changes: 5 additions & 5 deletions examples/assets/sentineljs/sentinel.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ function resetFn() {
* @param {Event} ev - The DOM event
*/
function animationStartHandler(ev) {
var callbacks = animationCallbacks[ev.animationName] || [],
l = callbacks.length;

// exit if a callback hasn't been registered
if (!l) return;
var callbacks = animationCallbacks[ev.animationName];

// exit if callbacks haven't been registered
if (!callbacks) return;

// stop other callbacks from firing
ev.stopImmediatePropagation();

// iterate through callbacks
var l = callbacks.length;
for (var i=0; i < l; i++) callbacks[i](ev.target);
}

Expand Down
2 changes: 1 addition & 1 deletion examples/assets/sentineljs/sentinel.min.js

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

36 changes: 36 additions & 0 deletions examples/extra-animation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<html>
<head>
<style>
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}

to {
margin-left: 0%;
width: 100%;
}
}
</style>
<script src="assets/sentineljs/sentinel.js"></script>
<script>
// use the `sentinel` global object
sentinel.on('.my-div', function(el) {
//el.innerHTML = 'The sentinel is always watching.';
}, 'slidein');

// add a new div to the DOM
function addDiv() {
var newEl = document.createElement('div');
newEl.className = 'my-div';
newEl.innerHTML = 'test';
document.body.appendChild(newEl);
}
</script>
</head>
<body>
<button onclick="addDiv();">Add another DIV</button>
<div class="my-div">test</div>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sentinel-js",
"version": "0.0.1",
"version": "0.0.2",
"license": "MIT",
"description": "JS library that detects new DOM nodes using CSS selectors",
"keywords": [
Expand Down
10 changes: 5 additions & 5 deletions src/sentinel.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,16 @@ function resetFn() {
* @param {Event} ev - The DOM event
*/
function animationStartHandler(ev) {
var callbacks = animationCallbacks[ev.animationName] || [],
l = callbacks.length;

// exit if a callback hasn't been registered
if (!l) return;
var callbacks = animationCallbacks[ev.animationName];

// exit if callbacks haven't been registered
if (!callbacks) return;

// stop other callbacks from firing
ev.stopImmediatePropagation();

// iterate through callbacks
var l = callbacks.length;
for (var i=0; i < l; i++) callbacks[i](ev.target);
}

Expand Down
10 changes: 5 additions & 5 deletions test/assets/sentineljs/sentinel.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ function resetFn() {
* @param {Event} ev - The DOM event
*/
function animationStartHandler(ev) {
var callbacks = animationCallbacks[ev.animationName] || [],
l = callbacks.length;

// exit if a callback hasn't been registered
if (!l) return;
var callbacks = animationCallbacks[ev.animationName];

// exit if callbacks haven't been registered
if (!callbacks) return;

// stop other callbacks from firing
ev.stopImmediatePropagation();

// iterate through callbacks
var l = callbacks.length;
for (var i=0; i < l; i++) callbacks[i](ev.target);
}

Expand Down
Loading

0 comments on commit 6b1d26b

Please sign in to comment.