Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .zuul.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: script-onload
ui: mocha-bdd
server: "./node_modules/.bin/http-server --silent -p $ZUUL_PORT test/support"
79 changes: 49 additions & 30 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,60 @@
#
# Binaries.
#

BROWSERS="chrome, safari, firefox, ie6..11"
BINS=node_modules/.bin
URL=http://localhost:3000/test
P=$(BINS)/mocha-phantomjs
C=$(BINS)/component
S=$(BINS)/serve
G=$(BINS)/gravy
ZUUL = ./node_modules/.bin/zuul

build: node_modules index.js components
@$(C) build --dev
#
# Files.
#

components: component.json
@$(C) install --dev
SRCS = index.js
TESTS = test/index.test.js

test: server build
@open $(URL)
#
# Task arguments.
#

test-phantom: server build
@$(P) $(URL)
BROWSER_NAME ?= chrome
BROWSER_VERSION ?= latest
PORT ?= 0
ZUUL_ARGS =

test-sauce: server build
@BROWSERS=$(BROWSERS) $(G) --url $(URL)
#
# Tasks.
#

node_modules: package.json
# Install node dependencies.
node_modules: package.json $(node_modules/*/package.json)
@npm install

server: kill
@$(S) . &> /dev/null & echo $$! > test/pid
@sleep 1

kill:
@-test -e test/pid \
&& kill `cat test/pid` \
&& rm -f test/pid

clean: kill
rm -rf components build

# Remove temporary files and build artifacts.
clean:
rm -rf *.log build
.PHONY: clean

# Remove temporary files, build artifacts, and vendor files.
distclean: clean
@rm -rf components node_modules
.PHONY: distclean

# Run tests in a browser. Defaults to a local browser.
# To run on Sauce Labs, set SAUCE_USERNAME and SAUCE_ACCESS_KEY.
ifdef SAUCE_USERNAME
test-browser: ZUUL_ARGS += --browser-name $(BROWSER_NAME) --browser-version $(BROWSER_VERSION)
else
test-browser: ZUUL_ARGS += --local $(PORT)
endif
test-browser: node_modules
@$(ZUUL) $(ZUUL_ARGS) -- $(TESTS)
.PHONY: test-browser

# Run tests in PhantomJS.
test-phantom: node_modules
@$(ZUUL) --phantom $(ZUUL_ARGS) -- $(TESTS)
.PHONY: test-phantom

# Test shortcut.
test: test-phantom
.PHONY: test
.DEFAULT_GOAL = test
22 changes: 17 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# script-onload [![CI][ci-badge]][ci-link]

# script-onload

Invoke `fn(err)` when the given `<script>` loads.
Invoke a function when a given `<script>` loads.

## Installation

Expand All @@ -11,9 +10,22 @@ $ component install segmentio/script-onload

## API

#### onload(el, fn)
#### onLoad(element, callback)

When the given `element` loads, invoke `callback` with `error, element`.

```js
var onLoad = require('script-onload');
var element = document.createElement('script');
element.src = '/my-script.js';
onLoad(element, function(error, element) {
// ...
});
```

## License

(MIT)
MIT

[ci-link]: https://circleci.com/gh/segmentio/script-onload
[ci-badge]: https://circleci.com/gh/segmentio/script-onload.svg?style=svg
16 changes: 16 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
machine:
node:
version: 0.12
test:
override:
- make test-phantom
- BROWSER_NAME=chrome make test-browser
- BROWSER_NAME=firefox make test-browser
- BROWSER_NAME=safari make test-browser
- BROWSER_NAME=ie make test-browser
- BROWSER_NAME=ie BROWSER_VERSION=10 make test-browser
- BROWSER_NAME=ie BROWSER_VERSION=9 make test-browser
# FIXME: https://github.com/segmentio/script-onload/issues/2
#- BROWSER_NAME=ie BROWSER_VERSION=8 make test-browser
#- BROWSER_NAME=ie BROWSER_VERSION=7 make test-browser
#- BROWSER_NAME=ie BROWSER_VERSION=6 make test-browser
4 changes: 1 addition & 3 deletions component.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
],
"dependencies": {},
"development": {
"visionmedia/mocha": "*",
"component/assert": "*",
"yields/gravy": "*"
"component/assert": "*"
}
}
75 changes: 41 additions & 34 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,60 @@
'use strict';

// https://github.com/thirdpartyjs/thirdpartyjs-code/blob/master/examples/templates/02/loading-files/index.html
// Credit: https://github.com/thirdpartyjs/thirdpartyjs-code/blob/master/examples/templates/02/loading-files/index.html

/**
* Invoke `fn(err)` when the given `el` script loads.
* Attach load event to `el` (IE >= 11, other major browsers).
*
* @param {Element} el
* @param {Function} fn
* @api public
* @api private
* @param {Element} element
* @param {Function} callback
*/

module.exports = function(el, fn){
return el.addEventListener
? add(el, fn)
: attach(el, fn);
};
function add(element, callback) {
element.addEventListener('load', function(event) {
callback(null, event);
}, false);
element.addEventListener('error', function(event) {
var error = new Error('script error "' + element.src + '"');
error.event = event;
callback(error);
}, false);
}

/**
* Add event listener to `el`, `fn()`.
* Attach event (IE <= 10).
*
* @param {Element} el
* @param {Function} fn
* @api private
* @param {Element} element
* @param {Function} callback
*/

function add(el, fn){
el.addEventListener('load', function(_, e){ fn(null, e); }, false);
el.addEventListener('error', function(e){
var err = new Error('script error "' + el.src + '"');
err.event = e;
fn(err);
}, false);
function attach(element, callback) {
element.attachEvent('onreadystatechange', function(event) {
if (!/complete|loaded/.test(element.readyState)) return;
callback(null, event);
});
element.attachEvent('onerror', function(event) {
var error = new Error('failed to load the script "' + element.src + '"');
error.event = event || window.event;
callback(error);
});
}

/**
* Attach event.
* Invoke `callback(err, event)` when the given `element` script loads.
*
* @param {Element} el
* @param {Function} fn
* @api private
* @api public
* @param {Element} element
* @param {Function(err, event)} callback
*/

function attach(el, fn){
el.attachEvent('onreadystatechange', function(e){
if (!/complete|loaded/.test(el.readyState)) return;
fn(null, e);
});
el.attachEvent('onerror', function(e){
var err = new Error('failed to load the script "' + el.src + '"');
err.event = e || window.event;
fn(err);
});
function onLoad(element, callback) {
return (element.addEventListener ? add : attach)(element, callback);
}

/**
* Exports.
*/

module.exports = onLoad;
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
},
"dependencies": {},
"devDependencies": {
"should": "^3.1.3",
"mocha-phantomjs": "^3.3.2",
"mocha": "^1.17.1",
"gravy": "^0.1.0",
"serve": "^1.4.0",
"component": "^0.19.7"
"http-server": "^0.8.0",
"phantomjs": "^1.9.16",
"zuul": "^3.0.0"
}
}
21 changes: 0 additions & 21 deletions test/index.html

This file was deleted.

68 changes: 68 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use strict';

/**
* Module dependencies.
*/

var assert = require('assert');
var fmt = require('util').format;
var onload = require('..');

/**
* Get the location of the test server. We fetch test scripts from this server.
*/

var location = window.location;
var testUrl = fmt('%s//%s%s', location.protocol, location.hostname, location.port && ':' + ZUUL.port);

/**
* Tests.
*/

describe('script-onload', function(){
// Declared by `script.js`
mocha.globals(['works']);

var container;

beforeEach(function() {
container = document.createElement('div');
document.body.appendChild(container);
});

afterEach(function() {
document.body.removeChild(container);
});

it('should invoke `callback` when the script loads', function(done) {
var el = document.createElement('script');
el.src = fmt('%s/script.js', testUrl);
container.appendChild(el);
onload(el, function(error) {
assert.equal(error, null);
assert.equal(window.works, 'yes');
done();
});
});

it('should invoke `callback` with the event', function(done) {
var el = document.createElement('script');
el.src = fmt('%s/script.js', testUrl);
container.appendChild(el);
onload(el, function(error, event) {
assert.equal(error, null);
assert.equal(typeof event, 'object');
done();
});
});

it('should invoke the callback with error on error', function(done) {
var el = document.createElement('script');
el.src = fmt('%s/nonexistent.js', testUrl);
container.appendChild(el);
onload(el, function(error) {
assert(error);
done();
});
});
});
1 change: 1 addition & 0 deletions test/support/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.works = 'yes';
26 changes: 0 additions & 26 deletions test/test.js

This file was deleted.

2 changes: 0 additions & 2 deletions test/works.js

This file was deleted.