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 */ /* 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
//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);
}

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(), var id = '?' + Math.random(),
base = loadBase || ''; loadBase = window.loadBase || '',
load( loadTests = window.loadTests,
base + 'lib/bootstrap.js' + id, loaded = false;
base + 'lib/parse-js.js' + id
).then( function addEvent(obj, type, fn) {
base + 'src/paper.js' + id if (obj.addEventListener) {
).then( obj.addEventListener(type, fn, false);
base + 'src/basic/Point.js' + id, } else if (obj.attachEvent) {
base + 'src/basic/Size.js' + id, obj.attachEvent('on'+ type, fn);
base + 'src/basic/Rectangle.js' + id, }
base + 'src/basic/Matrix.js' + id, }
base + 'src/basic/Line.js' + id
).then( addEvent(window, 'load', function() {
base + 'src/document/DocumentView.js' + id, loaded = true;
base + 'src/document/Document.js' + id, });
base + 'src/document/Symbol.js' + id
).then( // Load Paper.js library bit by bit, in chunks defined by inderdependent files.
base + 'src/item/Item.js' + id var items = [
).then( [
base + 'src/item/Group.js' + id, 'lib/bootstrap.js',
base + 'src/item/Raster.js' + id, 'lib/parse-js.js'
base + 'src/item/PlacedSymbol.js' + id, ], [
base + 'src/item/PathStyle.js' + id, 'src/paper.js'
base + 'src/path/PathItem.js' + id, ], [
base + 'src/path/Segment.js' + id, 'src/basic/Point.js',
base + 'src/path/Curve.js' + id 'src/basic/Size.js',
).then( 'src/basic/Rectangle.js',
// Needs Group 'src/basic/Matrix.js',
base + 'src/item/Layer.js' + id, 'src/basic/Line.js'
// Needs PathItem ], [
base + 'src/path/Path.js' + id, 'src/document/DocumentView.js',
base + 'src/path/CompoundPath.js' + id 'src/document/Document.js',
).then( 'src/document/Symbol.js'
base + 'src/path/Path.Constructors.js' + id, ], [
base + 'src/color/Color.js' + id 'src/item/Item.js'
).then( ], [
base + 'src/color/RGBColor.js' + id, 'src/item/Group.js',
base + 'src/color/GrayColor.js' + id, 'src/item/Raster.js',
base + 'src/color/GradientColor.js' + id, 'src/item/PlacedSymbol.js',
base + 'src/color/Gradient.js' + id, 'src/item/PathStyle.js',
base + 'src/color/GradientStop.js' + id 'src/path/PathItem.js',
).then( 'src/path/Segment.js',
base + 'src/tool/ToolEvent.js' + id, 'src/path/Curve.js'
base + 'src/tool/ToolHandler.js' + id ], [
).then( // Requires Group
// Requires ToolHandler 'src/item/Layer.js',
base + 'src/tool/Tool.js' + id, // Requires PathItem
base + 'src/util/BlendMode.js' + id, 'src/path/Path.js',
base + 'src/util/CanvasProvider.js' + id, 'src/path/CompoundPath.js'
base + 'src/util/Numerical.js' + id, ], [
base + 'src/util/Events.js' + id 'src/path/Path.Constructors.js',
).then( 'src/color/Color.js'
base + 'src/util/PaperScript.js' + id ], [
).thenRun( // 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
'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() { function() {
PaperScript.install(); if (loaded) {
PaperScript.load();
if (loadTests) {
QUnit.load();
}
}
} }
); );

View file

@ -3,56 +3,13 @@
<head> <head>
<title>Paper.js Tests</title> <title>Paper.js Tests</title>
<link rel="stylesheet" href="lib/qunit/qunit.css" type="text/css" media="screen"> <link rel="stylesheet" href="lib/qunit/qunit.css" type="text/css" media="screen">
<!-- Libraries --> <!-- Paper.js Loading -->
<script type="text/javascript" src="../lib/bootstrap.js"></script> <script type="text/javascript">
<script type="text/javascript" src="../src/Paper.js"></script> var loadBase = '../',
<script type="text/javascript" src="../src/tool/ToolEvent.js"></script> loadTests = true;
<script type="text/javascript" src="../src/tool/ToolHandler.js"></script> </script>
<script type="text/javascript" src="../src/tool/Tool.js"></script> <script type="text/javascript" src="../lib/load.js"></script>
<script type="text/javascript" src="../src/basic/Point.js"></script> <script type="text/javascript" src="../src/load.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>
</head> </head>
<body> <body>
<h1 id="qunit-header">QUnit Test Suite</h1> <h1 id="qunit-header">QUnit Test Suite</h1>

View file

@ -611,7 +611,72 @@ extend(QUnit, {
message: output message: output
}); });
}, },
load: function() {
QUnit.begin({});
// Initialize the config, saving the execution queue
var oldconfig = extend({}, config);
QUnit.init();
extend(config, oldconfig);
config.blocking = false;
var userAgent = id("qunit-userAgent");
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
var banner = id("qunit-header");
if ( banner ) {
var paramsIndex = location.href.lastIndexOf(location.search);
if ( paramsIndex > -1 ) {
var mainPageLocation = location.href.slice(0, paramsIndex);
if ( mainPageLocation == location.href ) {
banner.innerHTML = '<a href=""> ' + banner.innerHTML + '</a> ';
} else {
var testName = decodeURIComponent(location.search.slice(1));
banner.innerHTML = '<a href="' + mainPageLocation + '">' + banner.innerHTML + '</a> &#8250; <a href="">' + testName + '</a>';
}
}
}
var toolbar = id("qunit-testrunner-toolbar");
if ( toolbar ) {
var filter = document.createElement("input");
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
addEvent( filter, "click", function() {
var li = document.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ) {
if ( li[i].className.indexOf("pass") > -1 ) {
li[i].style.display = filter.checked ? "none" : "";
}
}
if ( defined.sessionStorage ) {
sessionStorage.setItem("qunit-filter-passed-tests", filter.checked ? "true" : "");
}
});
if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
filter.checked = true;
}
toolbar.appendChild( filter );
var label = document.createElement("label");
label.setAttribute("for", "qunit-filter-pass");
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
}
var main = id('main') || id('qunit-fixture');
if ( main ) {
config.fixture = main.innerHTML;
}
if (config.autostart) {
QUnit.start();
}
},
// Logging callbacks; all receive a single argument with the listed properties // Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes // run test/logs.html for any related changes
begin: function() {}, begin: function() {},
@ -633,70 +698,7 @@ if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true; config.autorun = true;
} }
addEvent(window, "load", function() { addEvent(window, "load", QUnit.load);
QUnit.begin({});
// Initialize the config, saving the execution queue
var oldconfig = extend({}, config);
QUnit.init();
extend(config, oldconfig);
config.blocking = false;
var userAgent = id("qunit-userAgent");
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
var banner = id("qunit-header");
if ( banner ) {
var paramsIndex = location.href.lastIndexOf(location.search);
if ( paramsIndex > -1 ) {
var mainPageLocation = location.href.slice(0, paramsIndex);
if ( mainPageLocation == location.href ) {
banner.innerHTML = '<a href=""> ' + banner.innerHTML + '</a> ';
} else {
var testName = decodeURIComponent(location.search.slice(1));
banner.innerHTML = '<a href="' + mainPageLocation + '">' + banner.innerHTML + '</a> &#8250; <a href="">' + testName + '</a>';
}
}
}
var toolbar = id("qunit-testrunner-toolbar");
if ( toolbar ) {
var filter = document.createElement("input");
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
addEvent( filter, "click", function() {
var li = document.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ) {
if ( li[i].className.indexOf("pass") > -1 ) {
li[i].style.display = filter.checked ? "none" : "";
}
}
if ( defined.sessionStorage ) {
sessionStorage.setItem("qunit-filter-passed-tests", filter.checked ? "true" : "");
}
});
if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
filter.checked = true;
}
toolbar.appendChild( filter );
var label = document.createElement("label");
label.setAttribute("for", "qunit-filter-pass");
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
}
var main = id('main') || id('qunit-fixture');
if ( main ) {
config.fixture = main.innerHTML;
}
if (config.autostart) {
QUnit.start();
}
});
function done() { function done() {
config.autorun = true; config.autorun = true;