Improve load.js mechanism and make it work for QUnit too.

This commit is contained in:
Jürg Lehni 2011-03-08 00:17:42 +00:00
parent 8f78513174
commit de797aa0fe
4 changed files with 221 additions and 203 deletions

35
lib/load.js Executable file → Normal file
View file

@ -1,33 +1,2 @@
/* Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>. MIT Licensed */
//Include the chain.js microframework (http://github.com/chriso/chain.js)
(function(a){a=a||{};var b={},c,d;c=function(a,d,e){var f=a.halt=!1;a.error=function(a){throw a},a.next=function(c){c&&(f=!1);if(!a.halt&&d&&d.length){var e=d.shift(),g=e.shift();f=!0;try{b[g].apply(a,[e,e.length,g])}catch(h){a.error(h)}}return a};for(var g in b){if(typeof a[g]==="function")continue;(function(e){a[e]=function(){var g=Array.prototype.slice.call(arguments);if(e==="onError"){if(d){b.onError.apply(a,[g,g.length]);return a}var h={};b.onError.apply(h,[g,g.length]);return c(h,null,"onError")}g.unshift(e);if(!d)return c({},[g],e);a.then=a[e],d.push(g);return f?a:a.next()}})(g)}e&&(a.then=a[e]),a.call=function(b,c){c.unshift(b),d.unshift(c),a.next(!0)};return a.next()},d=a.addMethod=function(d){var e=Array.prototype.slice.call(arguments),f=e.pop();for(var g=0,h=e.length;g<h;g++)typeof e[g]==="string"&&(b[e[g]]=f);--h||(b["then"+d.substr(0,1).toUpperCase()+d.substr(1)]=f),c(a)},d("chain",function(a){var b=this,c=function(){if(!b.halt){if(!a.length)return b.next(!0);try{null!=a.shift().call(b,c,b.error)&&c()}catch(d){b.error(d)}}};c()}),d("run",function(a,b){var c=this,d=function(){c.halt||--b||c.next(!0)},e=function(a){c.error(a)};for(var f=0,g=b;!c.halt&&f<g;f++)null!=a[f].call(c,d,e)&&d()}),d("defer",function(a){var b=this;setTimeout(function(){b.next(!0)},a.shift())}),d("onError",function(a,b){var c=this;this.error=function(d){c.halt=!0;for(var e=0;e<b;e++)a[e].call(c,d)}})})(this);
addMethod('load', function (args, argc) {
for (var queue = [], i = 0; i < argc; i++) {
(function (i) {
queue.push(function (next, error) {
loadScript(args[i], next, error);
});
}(i));
}
this.call('run', queue);
});
var head = document.getElementsByTagName('head')[0] || document.documentElement;
function loadScript(src, onload, onerror) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
script.onload = onload;
script.onerror = onerror;
script.onreadystatechange = function () {
var state = this.readyState;
if (state === 'loaded' || state === 'complete') {
script.onreadystatechange = null;
onload();
}
};
head.insertBefore(script, head.firstChild);
}
/* Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>. MIT Licensed *///Include the chain.js microframework (http://github.com/chriso/chain.js)
function loadScript(a,b,c){var d=document.createElement("script");d.type="text/javascript",d.src=a,d.onload=b,d.onerror=c,d.onreadystatechange=function(){var a=this.readyState;if(a==="loaded"||a==="complete")d.onreadystatechange=null,b()},head.insertBefore(d,head.firstChild)}(function(a){a=a||{};var b={},c,d;c=function(a,d,e){var f=a.halt=!1;a.error=function(a){throw a},a.next=function(c){c&&(f=!1);if(!a.halt&&d&&d.length){var e=d.shift(),g=e.shift();f=!0;try{b[g].apply(a,[e,e.length,g])}catch(h){a.error(h)}}return a};for(var g in b){if(typeof a[g]==="function")continue;(function(e){a[e]=function(){var g=Array.prototype.slice.call(arguments);if(e==="onError"){if(d){b.onError.apply(a,[g,g.length]);return a}var h={};b.onError.apply(h,[g,g.length]);return c(h,null,"onError")}g.unshift(e);if(!d)return c({},[g],e);a.then=a[e],d.push(g);return f?a:a.next()}})(g)}e&&(a.then=a[e]),a.call=function(b,c){c.unshift(b),d.unshift(c),a.next(!0)};return a.next()},d=a.addMethod=function(d){var e=Array.prototype.slice.call(arguments),f=e.pop();for(var g=0,h=e.length;g<h;g++)typeof e[g]==="string"&&(b[e[g]]=f);--h||(b["then"+d.substr(0,1).toUpperCase()+d.substr(1)]=f),c(a)},d("chain",function(a){var b=this,c=function(){if(!b.halt){if(!a.length)return b.next(!0);try{null!=a.shift().call(b,c,b.error)&&c()}catch(d){b.error(d)}}};c()}),d("run",function(a,b){var c=this,d=function(){c.halt||--b||c.next(!0)},e=function(a){c.error(a)};for(var f=0,g=b;!c.halt&&f<g;f++)null!=a[f].call(c,d,e)&&d()}),d("defer",function(a){var b=this;setTimeout(function(){b.next(!0)},a.shift())}),d("onError",function(a,b){var c=this;this.error=function(d){c.halt=!0;for(var e=0;e<b;e++)a[e].call(c,d)}})})(this),addMethod("load",function(a,b){for(var c=[],d=0;d<b;d++)(function(b){c.push(function(c,d){loadScript(a[b],c,d)})})(d);this.call("run",c)});var head=document.getElementsByTagName("head")[0]||document.documentElement

View file

@ -1,59 +1,149 @@
/*
* Paper.js
*
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
* based on Scriptographer.org and designed to be largely API compatible.
* http://scriptographer.org/
*
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* All rights reserved. See LICENSE file for details.
*/
// This file is only used by examples and unit tests, in order to load the
// library without having to preprocess it first.
//
// NOTE: Any files added as includes to paper.js also need to be listed here
var id = '?' + Math.random(),
base = loadBase || '';
load(
base + 'lib/bootstrap.js' + id,
base + 'lib/parse-js.js' + id
).then(
base + 'src/paper.js' + id
).then(
base + 'src/basic/Point.js' + id,
base + 'src/basic/Size.js' + id,
base + 'src/basic/Rectangle.js' + id,
base + 'src/basic/Matrix.js' + id,
base + 'src/basic/Line.js' + id
).then(
base + 'src/document/DocumentView.js' + id,
base + 'src/document/Document.js' + id,
base + 'src/document/Symbol.js' + id
).then(
base + 'src/item/Item.js' + id
).then(
base + 'src/item/Group.js' + id,
base + 'src/item/Raster.js' + id,
base + 'src/item/PlacedSymbol.js' + id,
base + 'src/item/PathStyle.js' + id,
base + 'src/path/PathItem.js' + id,
base + 'src/path/Segment.js' + id,
base + 'src/path/Curve.js' + id
).then(
// Needs Group
base + 'src/item/Layer.js' + id,
// Needs PathItem
base + 'src/path/Path.js' + id,
base + 'src/path/CompoundPath.js' + id
).then(
base + 'src/path/Path.Constructors.js' + id,
base + 'src/color/Color.js' + id
).then(
base + 'src/color/RGBColor.js' + id,
base + 'src/color/GrayColor.js' + id,
base + 'src/color/GradientColor.js' + id,
base + 'src/color/Gradient.js' + id,
base + 'src/color/GradientStop.js' + id
).then(
base + 'src/tool/ToolEvent.js' + id,
base + 'src/tool/ToolHandler.js' + id
).then(
loadBase = window.loadBase || '',
loadTests = window.loadTests,
loaded = false;
function addEvent(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.attachEvent) {
obj.attachEvent('on'+ type, fn);
}
}
addEvent(window, 'load', function() {
loaded = true;
});
// Load Paper.js library bit by bit, in chunks defined by inderdependent files.
var items = [
[
'lib/bootstrap.js',
'lib/parse-js.js'
], [
'src/paper.js'
], [
'src/basic/Point.js',
'src/basic/Size.js',
'src/basic/Rectangle.js',
'src/basic/Matrix.js',
'src/basic/Line.js'
], [
'src/document/DocumentView.js',
'src/document/Document.js',
'src/document/Symbol.js'
], [
'src/item/Item.js'
], [
'src/item/Group.js',
'src/item/Raster.js',
'src/item/PlacedSymbol.js',
'src/item/PathStyle.js',
'src/path/PathItem.js',
'src/path/Segment.js',
'src/path/Curve.js'
], [
// Requires Group
'src/item/Layer.js',
// Requires PathItem
'src/path/Path.js',
'src/path/CompoundPath.js'
], [
'src/path/Path.Constructors.js',
'src/color/Color.js'
], [
// Requires Color
'src/color/RGBColor.js',
'src/color/GrayColor.js',
'src/color/GradientColor.js',
'src/color/Gradient.js',
'src/color/GradientStop.js'
], [
'src/tool/ToolEvent.js',
'src/tool/ToolHandler.js'
], [
// Requires ToolHandler
base + 'src/tool/Tool.js' + id,
base + 'src/util/BlendMode.js' + id,
base + 'src/util/CanvasProvider.js' + id,
base + 'src/util/Numerical.js' + id,
base + 'src/util/Events.js' + id
).then(
base + 'src/util/PaperScript.js' + id
).thenRun(
'src/tool/Tool.js',
'src/util/BlendMode.js',
'src/util/CanvasProvider.js',
'src/util/Numerical.js',
'src/util/Events.js'
], [
// Requires Events
'src/util/PaperScript.js'
]
];
// Load unit tests after library if asked to do so
if (loadTests) {
items.push(
[
'test/lib/qunit/qunit.js',
'test/lib/test_functions.js'
],
// Load each test seperately
[ 'test/tests/Point.js' ],
[ 'test/tests/Size.js' ],
[ 'test/tests/Rectangle.js' ],
[ 'test/tests/Color.js' ],
[ 'test/tests/Document.js' ],
[ 'test/tests/Item.js' ],
[ 'test/tests/Layer.js' ],
[ 'test/tests/Group.js' ],
[ 'test/tests/Segment.js' ],
[ 'test/tests/Path.js' ],
[ 'test/tests/Path_Shapes.js' ],
[ 'test/tests/Path_Drawing_Commands.js' ],
[ 'test/tests/Path_Bounds.js' ],
[ 'test/tests/Path_Length.js' ],
[ 'test/tests/PathStyle.js' ],
[ 'test/tests/PlacedSymbol.js' ]
);
}
// This bit of code is required to convert the above lists of grouped sources
// to the odd load.js format:
var loader = null;
for (var i = 0; i < items.length; i++) {
var sources = items[i];
for (var j = 0; j < sources.length; j++) {
sources[j] = loadBase + sources[j] + id;
}
if (!loader) {
loader = load.apply(window, sources);
} else {
loader.then.apply(loader, sources);
}
}
// At the end of loading, run PaperScript and QUnit if required
loader.thenRun(
function() {
PaperScript.install();
if (loaded) {
PaperScript.load();
if (loadTests) {
QUnit.load();
}
}
}
);

View file

@ -3,56 +3,13 @@
<head>
<title>Paper.js Tests</title>
<link rel="stylesheet" href="lib/qunit/qunit.css" type="text/css" media="screen">
<!-- Libraries -->
<script type="text/javascript" src="../lib/bootstrap.js"></script>
<script type="text/javascript" src="../src/Paper.js"></script>
<script type="text/javascript" src="../src/tool/ToolEvent.js"></script>
<script type="text/javascript" src="../src/tool/ToolHandler.js"></script>
<script type="text/javascript" src="../src/tool/Tool.js"></script>
<script type="text/javascript" src="../src/basic/Point.js"></script>
<script type="text/javascript" src="../src/basic/Rectangle.js"></script>
<script type="text/javascript" src="../src/basic/Size.js"></script>
<script type="text/javascript" src="../src/basic/Matrix.js"></script>
<script type="text/javascript" src="../src/document/DocumentView.js"></script>
<script type="text/javascript" src="../src/document/Document.js"></script>
<script type="text/javascript" src="../src/document/Symbol.js"></script>
<script type="text/javascript" src="../src/item/Item.js"></script>
<script type="text/javascript" src="../src/item/Group.js"></script>
<script type="text/javascript" src="../src/item/Layer.js"></script>
<script type="text/javascript" src="../src/item/PlacedSymbol.js"></script>
<script type="text/javascript" src="../src/item/PathStyle.js"></script>
<script type="text/javascript" src="../src/path/Segment.js"></script>
<script type="text/javascript" src="../src/path/Curve.js"></script>
<script type="text/javascript" src="../src/path/PathItem.js"></script>
<script type="text/javascript" src="../src/path/Path.js"></script>
<script type="text/javascript" src="../src/path/Path.Constructors.js"></script>
<script type="text/javascript" src="../src/color/Color.js"></script>
<script type="text/javascript" src="../src/color/RGBColor.js"></script>
<script type="text/javascript" src="../src/color/GrayColor.js"></script>
<script type="text/javascript" src="../src/util/CanvasProvider.js"></script>
<script type="text/javascript" src="../src/util/Numerical.js"></script>
<script type="text/javascript" src="lib/qunit/qunit.js"></script>
<!-- Test Helpers -->
<script type="text/javascript" src="lib/test_functions.js"></script>
<!-- Tests -->
<script type="text/javascript" src="tests/Point.js"></script>
<script type="text/javascript" src="tests/Size.js"></script>
<script type="text/javascript" src="tests/Rectangle.js"></script>
<script type="text/javascript" src="tests/Color.js"></script>
<script type="text/javascript" src="tests/Document.js"></script>
<script type="text/javascript" src="tests/Item.js"></script>
<script type="text/javascript" src="tests/Layer.js"></script>
<script type="text/javascript" src="tests/Group.js"></script>
<script type="text/javascript" src="tests/Segment.js"></script>
<script type="text/javascript" src="tests/Path.js"></script>
<script type="text/javascript" src="tests/Path_Shapes.js"></script>
<script type="text/javascript" src="tests/Path_Drawing_Commands.js"></script>
<script type="text/javascript" src="tests/Path_Bounds.js"></script>
<script type="text/javascript" src="tests/Path_Length.js"></script>
<script type="text/javascript" src="tests/PathStyle.js"></script>
<script type="text/javascript" src="tests/PlacedSymbol.js"></script>
<!-- Paper.js Loading -->
<script type="text/javascript">
var loadBase = '../',
loadTests = true;
</script>
<script type="text/javascript" src="../lib/load.js"></script>
<script type="text/javascript" src="../src/load.js"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test Suite</h1>

View file

@ -612,28 +612,7 @@ extend(QUnit, {
});
},
// Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes
begin: function() {},
// done: { failed, passed, total, runtime }
done: function() {},
// log: { result, actual, expected, message }
log: function() {},
// testStart: { name }
testStart: function() {},
// testDone: { name, failed, passed, total }
testDone: function() {},
// moduleStart: { name }
moduleStart: function() {},
// moduleDone: { name, failed, passed, total }
moduleDone: function() {}
});
if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true;
}
addEvent(window, "load", function() {
load: function() {
QUnit.begin({});
// Initialize the config, saving the execution queue
@ -696,8 +675,31 @@ addEvent(window, "load", function() {
if (config.autostart) {
QUnit.start();
}
},
// Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes
begin: function() {},
// done: { failed, passed, total, runtime }
done: function() {},
// log: { result, actual, expected, message }
log: function() {},
// testStart: { name }
testStart: function() {},
// testDone: { name, failed, passed, total }
testDone: function() {},
// moduleStart: { name }
moduleStart: function() {},
// moduleDone: { name, failed, passed, total }
moduleDone: function() {}
});
if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true;
}
addEvent(window, "load", QUnit.load);
function done() {
config.autorun = true;