19 Commits
Author SHA1 Message Date
Richard Davey 86c872803a Final 0.9.4 release 2013-04-28 21:51:55 +01:00
Richard Davey 21120c8b62 Github Bug Fixes 2013-04-28 21:40:06 +01:00
Richard Davey a3b27fbf32 Fixed daft issue in Camera and fully implemented tilemap collision. 2013-04-28 14:59:44 +01:00
Richard Davey c09cff336d Tilemap collision is now working but all Camera following seems to be broken as a result. Awesome. 2013-04-28 12:25:02 +01:00
Richard Davey 2087b2d76e tidying up 2013-04-26 00:24:58 +01:00
Richard Davey b2e1434f5e Tilemap collision working but needs speeding up 2013-04-25 20:05:56 +01:00
Richard Davey b8ab13fec8 Getting tilemap collision up and running 2013-04-25 01:55:56 +01:00
Richard Davey 53d8e4da2e Fixed Game.boot syntax error. 2013-04-24 09:37:29 +01:00
Richard Davey 33882ae5d1 Small readme update. 2013-04-24 02:57:49 +01:00
Richard Davey 3898faf17e New v0.9.3 release - see the changelog in the README for full details. 2013-04-24 02:48:03 +01:00
Richard Davey 1b6fbc1324 Fixed Game.boot issue and Animation issue reported in github. 2013-04-24 00:47:11 +01:00
Richard Davey 268470ef62 Added blaster example to the Test Suite and fixed a rotation bug in the particle emitter. 2013-04-24 00:18:07 +01:00
Richard Davey 6466361f5f Great new thrust ship example added for ScrollZones. Also added rotationOffset value to GameObject base class. 2013-04-23 21:27:45 +01:00
Richard Davey 00fb20f8c2 And ScrollRegions work too :) 2013-04-23 19:24:16 +01:00
Richard Davey 332f715943 Finally fixed a really annoying bug in ScrollZone and it now works perfectly across the board. 2013-04-23 15:15:34 +01:00
Richard Davey f2678104fa Saving first iteration of the ScrollZone game object. 2013-04-22 01:53:24 +01:00
Richard Davey 2638e598dc Added Stage.disablePauseScreen 2013-04-20 03:50:21 +01:00
Richard Davey 361b8e5779 Version 0.9.2 update. See the change log for full details. 2013-04-20 03:40:17 +01:00
Richard Davey 364492d786 Added grunt file and npm package for OSX debs 2013-04-20 01:24:38 +01:00
315 changed files with 50975 additions and 3987 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+58
View File
@@ -0,0 +1,58 @@
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-typescript');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
typescript: {
base: {
src: ['Phaser/**/*.ts'],
dest: 'build/phaser.js',
options: {
target: 'ES5'
}
}
},
copy: {
main: {
files: [{
src: 'build/phaser.js',
dest: 'Tests/phaser.js'
}]
},
amd: {
files: [{
src: 'build/phaser.js',
dest: 'build/phaser.amd.js'
}],
options: {
processContent: function(content) {
var replacement = [
'(function (root, factory) {',
' if (typeof exports === \'object\') {',
' module.exports = factory();',
' } else if (typeof define === \'function\' && define.amd) {',
' define(factory);',
' } else {',
' root.Phaser = factory();',
' }',
'}(this, function () {',
content,
'return Phaser;',
'}));'
];
return replacement.join('\n');
}
}
}
},
watch: {
files: '**/*.ts',
tasks: ['typescript', 'copy']
}
});
grunt.registerTask('default', ['watch']);
}
+20 -8
View File
@@ -57,6 +57,7 @@ module Phaser {
{
if (this.validateFrames(frames, useNumericIndex) == false)
{
throw Error('Invalid frames given to Animation ' + name);
return;
}
}
@@ -69,6 +70,7 @@ module Phaser {
this._anims[name] = new Animation(this._game, this._parent, this._frameData, name, frames, frameRate, loop);
this.currentAnim = this._anims[name];
this.currentFrame = this.currentAnim.currentFrame;
}
@@ -100,8 +102,18 @@ module Phaser {
if (this._anims[name])
{
this.currentAnim = this._anims[name];
this.currentAnim.play(frameRate, loop);
if (this.currentAnim == this._anims[name])
{
if (this.currentAnim.isPlaying == false)
{
this.currentAnim.play(frameRate, loop);
}
}
else
{
this.currentAnim = this._anims[name];
this.currentAnim.play(frameRate, loop);
}
}
}
@@ -141,10 +153,10 @@ module Phaser {
public set frame(value: number) {
this.currentFrame = this._frameData.getFrame(value);
if (this.currentFrame !== null)
if (this._frameData.getFrame(value) !== null)
{
this.currentFrame = this._frameData.getFrame(value);
this._parent.bounds.width = this.currentFrame.width;
this._parent.bounds.height = this.currentFrame.height;
this._frameIndex = value;
@@ -158,10 +170,10 @@ module Phaser {
public set frameName(value: string) {
this.currentFrame = this._frameData.getFrameByName(value);
if (this.currentFrame !== null)
if (this._frameData.getFrameByName(value) !== null)
{
this.currentFrame = this._frameData.getFrameByName(value);
this._parent.bounds.width = this.currentFrame.width;
this._parent.bounds.height = this.currentFrame.height;
this._frameIndex = this.currentFrame.index;
+16 -13
View File
@@ -26,8 +26,8 @@ module Phaser {
}
private _game: Game;
private _cameras: Camera[];
private _cameraInstance: number = 0;
public current: Camera;
@@ -45,32 +45,35 @@ module Phaser {
public addCamera(x: number, y: number, width: number, height: number): Camera {
var newCam: Camera = new Camera(this._game, this._cameras.length, x, y, width, height);
var newCam: Camera = new Camera(this._game, this._cameraInstance, x, y, width, height);
this._cameras.push(newCam);
this._cameraInstance++;
return newCam;
}
public removeCamera(id: number): bool {
if (this._cameras[id])
for (var c = 0; c < this._cameras.length; c++)
{
if (this.current === this._cameras[id])
if (this._cameras[c].ID == id)
{
this.current = null;
if (this.current.ID === this._cameras[c].ID)
{
this.current = null;
}
this._cameras.splice(c, 1);
return true;
}
this._cameras.splice(id, 1);
return true;
}
else
{
return false;
}
return false;
}
public destroy() {
+542 -387
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -13,7 +13,7 @@ module Phaser {
export class DynamicTexture {
constructor(game: Game, key: string, width: number, height: number) {
constructor(game: Game, width: number, height: number) {
this._game = game;
+41 -13
View File
@@ -28,12 +28,16 @@
/// <reference path="gameobjects/Particle.ts" />
/// <reference path="gameobjects/Sprite.ts" />
/// <reference path="gameobjects/Tilemap.ts" />
/// <reference path="gameobjects/ScrollZone.ts" />
/**
* Phaser - Game
*
* This is where the magic happens. The Game object is the heart of your game, providing quick access to common
* functions and handling the boot process.
* This is where the magic happens. The Game object is the heart of your game,
* providing quick access to common functions and handling the boot process.
*
* "Hell, there are no rules here - we're trying to accomplish something."
* Thomas A. Edison
*/
module Phaser {
@@ -50,11 +54,12 @@ module Phaser {
if (document.readyState === 'complete' || document.readyState === 'interactive')
{
this.boot(parent, width, height);
setTimeout(() => this.boot(parent, width, height));
}
else
{
document.addEventListener('DOMContentLoaded', () => this.boot(parent, width, height), false);
window.addEventListener('load', () => this.boot(parent, width, height), false);
}
}
@@ -75,7 +80,6 @@ module Phaser {
public onRenderCallback = null;
public onPausedCallback = null;
public camera: Camera; // quick reference to the default created camera, access the rest via .world
public cache: Cache;
public collision: Collision;
public input: Input;
@@ -94,6 +98,11 @@ module Phaser {
private boot(parent: string, width: number, height: number) {
if (this.isBooted == true)
{
return;
}
if (!document.body)
{
window.setTimeout(() => this.boot(parent, width, height), 13);
@@ -202,7 +211,20 @@ module Phaser {
if (this.onInitCallback !== null)
{
this.loader.reset();
this.onInitCallback.call(this.callbackContext);
// Is the loader empty?
if (this.loader.queueSize == 0)
{
if (this.onCreateCallback !== null)
{
this.onCreateCallback.call(this.callbackContext);
}
this._loadComplete = true;
}
}
else
{
@@ -293,8 +315,7 @@ module Phaser {
}
else
{
throw Error("Invalid State object given. Must contain at least a create or update function.");
return;
throw new Error("Invalid State object given. Must contain at least a create or update function.");
}
}
@@ -308,7 +329,6 @@ module Phaser {
this.onUpdateCallback = null;
this.onRenderCallback = null;
this.onPausedCallback = null;
this.camera = null;
this.cache = null;
this.input = null;
this.loader = null;
@@ -368,8 +388,8 @@ module Phaser {
return this.world.createSprite(x, y, key);
}
public createDynamicTexture(key: string, width: number, height: number): DynamicTexture {
return this.world.createDynamicTexture(key, width, height);
public createDynamicTexture(width: number, height: number): DynamicTexture {
return this.world.createDynamicTexture(width, height);
}
public createGroup(MaxSize?: number = 0): Group {
@@ -384,16 +404,24 @@ module Phaser {
return this.world.createEmitter(x, y, size);
}
public createTilemap(key: string, mapData: string, format: number, tileWidth?: number, tileHeight?: number): Tilemap {
return this.world.createTilemap(key, mapData, format, tileWidth, tileHeight);
public createScrollZone(key: string, x?: number = 0, y?: number = 0, width?: number = 0, height?: number = 0): ScrollZone {
return this.world.createScrollZone(key, x, y, width, height);
}
public createTilemap(key: string, mapData: string, format: number, resizeWorld: bool = true, tileWidth?: number = 0, tileHeight?: number = 0): Tilemap {
return this.world.createTilemap(key, mapData, format, resizeWorld, tileWidth, tileHeight);
}
public createTween(obj): Tween {
return this.tweens.create(obj);
}
public collide(ObjectOrGroup1: Basic = null, ObjectOrGroup2: Basic = null, NotifyCallback = null): bool {
return this.collision.overlap(ObjectOrGroup1, ObjectOrGroup2, NotifyCallback, Collision.separate);
public collide(objectOrGroup1: Basic = null, objectOrGroup2: Basic = null, notifyCallback = null): bool {
return this.collision.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, Collision.separate);
}
public get camera(): Camera {
return this.world.cameras.current;
}
}
+32
View File
@@ -943,6 +943,38 @@ module Phaser {
return this.sinTable;
}
/**
* Shifts through the sin table data by one value and returns it.
* This effectively moves the position of the data from the start to the end of the table.
* @return The sin value.
*/
public shiftSinTable(): number {
if (this.sinTable)
{
var s = this.sinTable.shift();
this.sinTable.push(s);
return s;
}
}
/**
* Shifts through the cos table data by one value and returns it.
* This effectively moves the position of the data from the start to the end of the table.
* @return The cos value.
*/
public shiftCosTable(): number {
if (this.cosTable)
{
var s = this.cosTable.shift();
this.cosTable.push(s);
return s;
}
}
/**
+28 -4
View File
@@ -286,7 +286,7 @@ module Phaser {
return null;
}
return this.add(new ObjectClass());
return this.add(new ObjectClass(this._game));
}
else
{
@@ -314,7 +314,7 @@ module Phaser {
return null;
}
return this.add(new ObjectClass());
return this.add(new ObjectClass(this._game));
}
}
@@ -450,7 +450,7 @@ module Phaser {
}
}
public forEach(callback, Recurse: bool = false) {
public forEach(callback, recursive: bool = false) {
var basic;
var i: number = 0;
@@ -461,7 +461,7 @@ module Phaser {
if (basic != null)
{
if (Recurse && (basic.isGroup == true))
if (recursive && (basic.isGroup == true))
{
basic.forEach(callback, true);
}
@@ -474,6 +474,30 @@ module Phaser {
}
public forEachAlive(context, callback, recursive: bool = false) {
var basic;
var i: number = 0;
while (i < this.length)
{
basic = this.members[i++];
if (basic != null && basic.alive)
{
if (recursive && (basic.isGroup == true))
{
basic.forEachAlive(context, callback, true);
}
else
{
callback.call(context, basic);
}
}
}
}
/**
* Call this function to retrieve the first object with exists == false in the group.
* This is handy for recycling in general, e.g. respawning enemies.
+33 -26
View File
@@ -18,6 +18,7 @@ module Phaser {
this._keys = [];
this._fileList = {};
this._xhr = new XMLHttpRequest();
this._queueSize = 0;
}
@@ -29,20 +30,18 @@ module Phaser {
private _onFileLoad;
private _progressChunk: number;
private _xhr: XMLHttpRequest;
private _queueSize: number;
public hasLoaded: bool;
public progress: number;
private checkKeyExists(key: string): bool {
public reset() {
this._queueSize = 0;
}
if (this._fileList[key])
{
return true;
}
else
{
return false;
}
public get queueSize(): number {
return this._queueSize;
}
@@ -50,6 +49,7 @@ module Phaser {
if (this.checkKeyExists(key) === false)
{
this._queueSize++;
this._fileList[key] = { type: 'image', key: key, url: url, data: null, error: false, loaded: false };
this._keys.push(key);
}
@@ -60,6 +60,7 @@ module Phaser {
if (this.checkKeyExists(key) === false)
{
this._queueSize++;
this._fileList[key] = { type: 'spritesheet', key: key, url: url, data: null, frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, error: false, loaded: false };
this._keys.push(key);
}
@@ -68,15 +69,12 @@ module Phaser {
public addTextureAtlas(key: string, url: string, jsonURL?: string = null, jsonData? = null) {
//console.log('addTextureAtlas');
//console.log(typeof jsonData);
if (this.checkKeyExists(key) === false)
{
if (jsonURL !== null)
{
//console.log('A URL to a json file has been given');
// A URL to a json file has been given
this._queueSize++;
this._fileList[key] = { type: 'textureatlas', key: key, url: url, data: null, jsonURL: jsonURL, jsonData: null, error: false, loaded: false };
this._keys.push(key);
}
@@ -85,24 +83,21 @@ module Phaser {
// A json string or object has been given
if (typeof jsonData === 'string')
{
//console.log('A json string has been given');
var data = JSON.parse(jsonData);
//console.log(data);
// Malformed?
if (data['frames'])
{
//console.log('frames array found');
this._queueSize++;
this._fileList[key] = { type: 'textureatlas', key: key, url: url, data: null, jsonURL: null, jsonData: data['frames'], error: false, loaded: false };
this._keys.push(key);
}
}
else
{
//console.log('A json object has been given', jsonData);
// Malformed?
if (jsonData['frames'])
{
//console.log('frames array found');
this._queueSize++;
this._fileList[key] = { type: 'textureatlas', key: key, url: url, data: null, jsonURL: null, jsonData: jsonData['frames'], error: false, loaded: false };
this._keys.push(key);
}
@@ -118,6 +113,7 @@ module Phaser {
if (this.checkKeyExists(key) === false)
{
this._queueSize++;
this._fileList[key] = { type: 'audio', key: key, url: url, data: null, buffer: null, error: false, loaded: false };
this._keys.push(key);
}
@@ -128,6 +124,7 @@ module Phaser {
if (this.checkKeyExists(key) === false)
{
this._queueSize++;
this._fileList[key] = { type: 'text', key: key, url: url, data: null, error: false, loaded: false };
this._keys.push(key);
}
@@ -243,7 +240,6 @@ module Phaser {
break;
case 'textureatlas':
//console.log('texture atlas loaded');
if (file.jsonURL == null)
{
this._game.cache.addTextureAtlas(file.key, file.url, file.data, file.jsonData);
@@ -251,7 +247,6 @@ module Phaser {
else
{
// Load the JSON before carrying on with the next file
//console.log('Loading the JSON before carrying on with the next file');
loadNext = false;
this._xhr.open("GET", file.jsonURL, true);
this._xhr.responseType = "text";
@@ -281,12 +276,8 @@ module Phaser {
private jsonLoadComplete(key: string) {
//console.log('json load complete');
var data = JSON.parse(this._xhr.response);
//console.log(data);
// Malformed?
if (data['frames'])
{
@@ -300,8 +291,6 @@ module Phaser {
private jsonLoadError(key: string) {
//console.log('json load error');
var file = this._fileList[key];
file.error = true;
this.nextFile(key, true);
@@ -311,6 +300,11 @@ module Phaser {
private nextFile(previousKey: string, success: bool) {
this.progress = Math.round(this.progress + this._progressChunk);
if (this.progress > 1)
{
this.progress = 1;
}
if (this._onFileLoad)
{
@@ -335,6 +329,19 @@ module Phaser {
}
private checkKeyExists(key: string): bool {
if (this._fileList[key])
{
return true;
}
else
{
return false;
}
}
}
}
+5
View File
@@ -79,6 +79,11 @@ module Phaser {
*/
public velocityFromAngle(angle: number, speed: number): Point {
if (isNaN(speed))
{
speed = 0;
}
var a: number = this._game.math.degreesToRadians(angle);
return new Point((Math.cos(a) * speed), (Math.sin(a) * speed));
+15 -3
View File
@@ -85,6 +85,14 @@
<Content Include="gameobjects\Particle.js">
<DependentUpon>Particle.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="gameobjects\ScrollZone.ts" />
<TypeScriptCompile Include="gameobjects\ScrollRegion.ts" />
<Content Include="gameobjects\ScrollRegion.js">
<DependentUpon>ScrollRegion.ts</DependentUpon>
</Content>
<Content Include="gameobjects\ScrollZone.js">
<DependentUpon>ScrollZone.ts</DependentUpon>
</Content>
<Content Include="gameobjects\Sprite.js">
<DependentUpon>Sprite.ts</DependentUpon>
</Content>
@@ -107,6 +115,10 @@
<Content Include="geom\Point.js">
<DependentUpon>Point.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="geom\Quad.ts" />
<Content Include="geom\Quad.js">
<DependentUpon>Quad.ts</DependentUpon>
</Content>
<Content Include="geom\Rectangle.js">
<DependentUpon>Rectangle.ts</DependentUpon>
</Content>
@@ -154,14 +166,14 @@
<Content Include="system\Tile.js">
<DependentUpon>Tile.ts</DependentUpon>
</Content>
<Content Include="system\TilemapBuffer.js">
<DependentUpon>TilemapBuffer.ts</DependentUpon>
<TypeScriptCompile Include="system\TilemapLayer.ts" />
<Content Include="system\TilemapLayer.js">
<DependentUpon>TilemapLayer.ts</DependentUpon>
</Content>
<Content Include="system\Tween.js">
<DependentUpon>Tween.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="system\Tween.ts" />
<TypeScriptCompile Include="system\TilemapBuffer.ts" />
<TypeScriptCompile Include="system\Tile.ts" />
<TypeScriptCompile Include="system\StageScaleMode.ts" />
<TypeScriptCompile Include="system\RequestAnimationFrame.ts" />
+2 -2
View File
@@ -1,7 +1,7 @@
/**
* Phaser
*
* v0.9.1 - April 19th 2013
* v0.9.4 - April 28th 2013
*
* A small and feature-packed 2D canvas game framework born from the firey pits of Flixel and Kiwi.
*
@@ -16,6 +16,6 @@
module Phaser {
export var VERSION: string = 'Phaser version 0.9.1';
export var VERSION: string = 'Phaser version 0.9.4';
}
+11 -4
View File
@@ -43,8 +43,8 @@ module Phaser {
this.scaleMode = StageScaleMode.NO_SCALE;
this.scale = new StageScaleMode(this._game);
//document.addEventListener('visibilitychange', (event) => this.visibilityChange(event), false);
//document.addEventListener('webkitvisibilitychange', (event) => this.visibilityChange(event), false);
document.addEventListener('visibilitychange', (event) => this.visibilityChange(event), false);
document.addEventListener('webkitvisibilitychange', (event) => this.visibilityChange(event), false);
window.onblur = (event) => this.visibilityChange(event);
window.onfocus = (event) => this.visibilityChange(event);
@@ -62,6 +62,7 @@ module Phaser {
public clear: bool = true;
public canvas: HTMLCanvasElement;
public context: CanvasRenderingContext2D;
public disablePauseScreen: bool = false;
public offset: Point;
public scale: StageScaleMode;
public scaleMode: number;
@@ -92,8 +93,16 @@ module Phaser {
}
//if (document['hidden'] === true || document['webkitHidden'] === true)
private visibilityChange(event) {
//console.log(event);
if (this.disablePauseScreen)
{
return;
}
if (event.type == 'blur' && this._game.paused == false && this._game.isBooted == true)
{
this._game.paused = true;
@@ -104,8 +113,6 @@ module Phaser {
this._game.paused = false;
}
//if (document['hidden'] === true || document['webkitHidden'] === true)
}
public drawInitScreen() {
+8 -4
View File
@@ -66,8 +66,8 @@ module Phaser {
return this.game.world.createSprite(x, y, key);
}
public createDynamicTexture(key: string, width: number, height: number): DynamicTexture {
return this.game.world.createDynamicTexture(key, width, height);
public createDynamicTexture(width: number, height: number): DynamicTexture {
return this.game.world.createDynamicTexture(width, height);
}
public createGroup(MaxSize?: number = 0): Group {
@@ -82,8 +82,12 @@ module Phaser {
return this.game.world.createEmitter(x, y, size);
}
public createTilemap(key: string, mapData: string, format: number, tileWidth?: number, tileHeight?: number): Tilemap {
return this.game.world.createTilemap(key, mapData, format, tileWidth, tileHeight);
public createScrollZone(key: string, x?: number = 0, y?: number = 0, width?: number = 0, height?: number = 0): ScrollZone {
return this.game.world.createScrollZone(key, x, y, width, height);
}
public createTilemap(key: string, mapData: string, format: number, resizeWorld: bool = true, tileWidth?: number = 0, tileHeight?: number = 0): Tilemap {
return this.game.world.createTilemap(key, mapData, format, resizeWorld, tileWidth, tileHeight);
}
public createTween(obj): Tween {
+17 -27
View File
@@ -16,9 +16,9 @@ module Phaser {
this._game = game;
this._cameras = new CameraManager(this._game, 0, 0, width, height);
this.cameras = new CameraManager(this._game, 0, 0, width, height);
this._game.camera = this._cameras.current;
this._game.camera = this.cameras.current;
this.group = new Group(this._game, 0);
@@ -29,8 +29,8 @@ module Phaser {
}
private _game: Game;
private _cameras: CameraManager;
public cameras: CameraManager;
public group: Group;
public bounds: Rectangle;
public worldDivisions: number;
@@ -41,14 +41,14 @@ module Phaser {
this.group.update();
this.group.postUpdate();
this._cameras.update();
this.cameras.update();
}
public render() {
// Unlike in flixel our render process is camera driven, not group driven
this._cameras.render();
this.cameras.render();
}
@@ -56,7 +56,7 @@ module Phaser {
this.group.destroy();
this._cameras.destroy();
this.cameras.destroy();
}
@@ -108,29 +108,19 @@ module Phaser {
// Cameras
public addExistingCamera(cam: Camera): Camera {
//return this._cameras.addCamera(x, y, width, height);
return cam;
}
public createCamera(x: number, y: number, width: number, height: number): Camera {
return this._cameras.addCamera(x, y, width, height);
return this.cameras.addCamera(x, y, width, height);
}
public removeCamera(id: number): bool {
return this._cameras.removeCamera(id);
return this.cameras.removeCamera(id);
}
public getAllCameras(): Camera[] {
return this._cameras.getAll();
return this.cameras.getAll();
}
// Sprites
// Drop this?
public addExistingSprite(sprite: Sprite): Sprite {
return <Sprite> this.group.add(sprite);
}
// Game Objects
public createSprite(x: number, y: number, key?: string = ''): Sprite {
return <Sprite> this.group.add(new Sprite(this._game, x, y, key));
@@ -140,21 +130,21 @@ module Phaser {
return <GeomSprite> this.group.add(new GeomSprite(this._game, x, y));
}
public createDynamicTexture(key: string, width: number, height: number): DynamicTexture {
return new DynamicTexture(this._game, key, width, height);
public createDynamicTexture(width: number, height: number): DynamicTexture {
return new DynamicTexture(this._game, width, height);
}
public createGroup(MaxSize?: number = 0): Group {
return <Group> this.group.add(new Group(this._game, MaxSize));
}
// Tilemaps
public createTilemap(key: string, mapData: string, format: number, tileWidth?: number, tileHeight?: number): Tilemap {
return <Tilemap> this.group.add(new Tilemap(this._game, key, mapData, format, tileWidth, tileHeight));
public createScrollZone(key: string, x?: number = 0, y?: number = 0, width?: number = 0, height?: number = 0): ScrollZone {
return <ScrollZone> this.group.add(new ScrollZone(this._game, key, x, y, width, height));
}
// Emitters
public createTilemap(key: string, mapData: string, format: number, resizeWorld: bool = true, tileWidth?: number = 0, tileHeight?: number = 0): Tilemap {
return <Tilemap> this.group.add(new Tilemap(this._game, key, mapData, format, resizeWorld, tileWidth, tileHeight));
}
public createParticle(): Particle {
return new Particle(this._game);
+11 -10
View File
@@ -27,13 +27,13 @@ module Phaser {
this.y = Y;
this.width = 0;
this.height = 0;
this.minParticleSpeed = new Point(-100, -100);
this.maxParticleSpeed = new Point(100, 100);
this.minParticleSpeed = new MicroPoint(-100, -100);
this.maxParticleSpeed = new MicroPoint(100, 100);
this.minRotation = -360;
this.maxRotation = 360;
this.gravity = 0;
this.particleClass = null;
this.particleDrag = new Point();
this.particleDrag = new MicroPoint();
this.frequency = 0.1;
this.lifespan = 3;
this.bounce = 0;
@@ -41,7 +41,7 @@ module Phaser {
this._counter = 0;
this._explode = true;
this.on = false;
this._point = new Point();
this._point = new MicroPoint();
}
/**
@@ -68,18 +68,18 @@ module Phaser {
* The minimum possible velocity of a particle.
* The default value is (-100,-100).
*/
public minParticleSpeed: Point;
public minParticleSpeed: MicroPoint;
/**
* The maximum possible velocity of a particle.
* The default value is (100,100).
*/
public maxParticleSpeed: Point;
public maxParticleSpeed: MicroPoint;
/**
* The X and Y drag component of particles launched from the emitter.
*/
public particleDrag: Point;
public particleDrag: MicroPoint;
/**
* The minimum possible angular velocity of a particle. The default value is -360.
@@ -149,7 +149,7 @@ module Phaser {
/**
* Internal point object, handy for reusing for memory mgmt purposes.
*/
private _point: Point;
private _point: MicroPoint;
/**
* Clean up memory.
@@ -174,7 +174,7 @@ module Phaser {
*
* @return This Emitter instance (nice for chaining stuff together, if you're into that).
*/
public makeParticles(Graphics, Quantity: number = 50, BakedRotations: number = 16, Multiple: bool = false, Collide: number = 0.8): Emitter {
public makeParticles(Graphics, Quantity: number = 50, BakedRotations: number = 16, Multiple: bool = false, Collide: number = 0): Emitter {
this.maxSize = Quantity;
@@ -236,6 +236,7 @@ module Phaser {
if (Collide > 0)
{
particle.allowCollisions = Collision.ANY;
particle.width *= Collide;
particle.height *= Collide;
//particle.centerOffsets();
@@ -372,7 +373,7 @@ module Phaser {
particle.acceleration.y = this.gravity;
if (this.minRotation != this.maxRotation)
if (this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0)
{
particle.angularVelocity = this.minRotation + this._game.math.random() * (this.maxRotation - this.minRotation);
}
+96 -29
View File
@@ -29,11 +29,12 @@ module Phaser {
this.last = new MicroPoint(x, y);
this.origin = new MicroPoint(this.bounds.halfWidth, this.bounds.halfHeight);
this.align = GameObject.ALIGN_TOP_LEFT;
this.mass = 1.0;
this.elasticity = 0.0;
this.mass = 1;
this.elasticity = 0;
this.health = 1;
this.immovable = false;
this.moves = true;
this.worldBounds = null;
this.touching = Collision.NONE;
this.wasTouching = Collision.NONE;
@@ -50,7 +51,8 @@ module Phaser {
this.angularDrag = 0;
this.maxAngular = 10000;
this.scrollFactor = new MicroPoint(1.0, 1.0);
this.cameraBlacklist = [];
this.scrollFactor = new MicroPoint(1, 1);
}
@@ -66,9 +68,15 @@ module Phaser {
public static ALIGN_BOTTOM_CENTER: number = 7;
public static ALIGN_BOTTOM_RIGHT: number = 8;
public static OUT_OF_BOUNDS_STOP: number = 0;
public static OUT_OF_BOUNDS_KILL: number = 1;
public _point: MicroPoint;
public cameraBlacklist: number[];
public bounds: Rectangle;
public worldBounds: Quad;
public outOfBoundsAction: number = 0;
public align: number;
public facing: number;
public alpha: number;
@@ -76,6 +84,13 @@ module Phaser {
public origin: MicroPoint;
public z: number = 0;
// This value is added to the angle of the GameObject.
// For example if you had a sprite drawn facing straight up then you could set
// rotationOffset to 90 and it would correspond correctly with Phasers rotation system
public rotationOffset: number = 0;
public renderRotation: bool = true;
// Physics properties
public immovable: bool;
@@ -131,6 +146,37 @@ module Phaser {
this.updateMotion();
}
if (this.worldBounds != null)
{
if (this.outOfBoundsAction == GameObject.OUT_OF_BOUNDS_KILL)
{
if (this.x < this.worldBounds.x || this.x > this.worldBounds.right || this.y < this.worldBounds.y || this.y > this.worldBounds.bottom)
{
this.kill();
}
}
else
{
if (this.x < this.worldBounds.x)
{
this.x = this.worldBounds.x;
}
else if (this.x > this.worldBounds.right)
{
this.x = this.worldBounds.right;
}
if (this.y < this.worldBounds.y)
{
this.y = this.worldBounds.y;
}
else if (this.y > this.worldBounds.bottom)
{
this.y = this.worldBounds.bottom;
}
}
}
if (this.inputEnabled)
{
this.updateInput();
@@ -170,7 +216,7 @@ module Phaser {
/**
* Checks to see if some <code>GameObject</code> overlaps this <code>GameObject</code> or <code>Group</code>.
* If the group has a LOT of things in it, it might be faster to use <code>G.overlaps()</code>.
* If the group has a LOT of things in it, it might be faster to use <code>Collision.overlaps()</code>.
* WARNING: Currently tilemaps do NOT support screen space overlap checks!
*
* @param ObjectOrGroup The object or group being tested.
@@ -199,17 +245,6 @@ module Phaser {
}
/*
if (typeof ObjectOrGroup === 'Tilemap')
{
//Since tilemap's have to be the caller, not the target, to do proper tile-based collisions,
// we redirect the call to the tilemap overlap here.
return ObjectOrGroup.overlaps(this, InScreenSpace, Camera);
}
*/
//var object: GameObject = ObjectOrGroup;
if (!InScreenSpace)
{
return (ObjectOrGroup.x + ObjectOrGroup.width > this.x) && (ObjectOrGroup.x < this.x + this.width) &&
@@ -262,20 +297,6 @@ module Phaser {
return results;
}
/*
if (typeof ObjectOrGroup === 'Tilemap')
{
//Since tilemap's have to be the caller, not the target, to do proper tile-based collisions,
// we redirect the call to the tilemap overlap here.
//However, since this is overlapsAt(), we also have to invent the appropriate position for the tilemap.
//So we calculate the offset between the player and the requested position, and subtract that from the tilemap.
var tilemap: Tilemap = ObjectOrGroup;
return tilemap.overlapsAt(tilemap.x - (X - this.x), tilemap.y - (Y - this.y), this, InScreenSpace, Camera);
}
*/
//var object: GameObject = ObjectOrGroup;
if (!InScreenSpace)
{
return (ObjectOrGroup.x + ObjectOrGroup.width > X) && (ObjectOrGroup.x < X + this.width) &&
@@ -484,6 +505,44 @@ module Phaser {
}
/**
* Set the world bounds that this GameObject can exist within. By default a GameObject can exist anywhere
* in the world. But by setting the bounds (which are given in world dimensions, not screen dimensions)
* it can be stopped from leaving the world, or a section of it.
*/
public setBounds(x: number, y: number, width: number, height: number) {
this.worldBounds = new Quad(x, y, width, height);
}
/**
* If you do not wish this object to be visible to a specific camera, pass the camera here.
*/
public hideFromCamera(camera: Camera) {
if (this.cameraBlacklist.indexOf(camera.ID) == -1)
{
this.cameraBlacklist.push(camera.ID);
}
}
public showToCamera(camera: Camera) {
if (this.cameraBlacklist.indexOf(camera.ID) !== -1)
{
this.cameraBlacklist.slice(this.cameraBlacklist.indexOf(camera.ID), 1);
}
}
public clearCameraList() {
this.cameraBlacklist.length = 0;
}
public destroy() {
}
@@ -520,6 +579,14 @@ module Phaser {
this._angle = this._game.math.wrap(value, 360, 0);
}
public set width(value:number) {
this.bounds.width = value;
}
public set height(value:number) {
this.bounds.height = value;
}
public get width(): number {
return this.bounds.width;
}
+1 -1
View File
@@ -190,7 +190,7 @@ module Phaser {
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number): bool {
// Render checks
if (this.type == GeomSprite.UNASSIGNED || this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.inCamera(camera.worldView) == false)
if (this.type == GeomSprite.UNASSIGNED || this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.cameraBlacklist.indexOf(camera.ID) !== -1 || this.inCamera(camera.worldView) == false)
{
return false;
}
+2
View File
@@ -22,6 +22,7 @@ module Phaser {
this.lifespan = 0;
this.friction = 500;
}
/**
@@ -43,6 +44,7 @@ module Phaser {
* be dead yet, and then has some special bounce behavior if there is some gravity on it.
*/
public update() {
//lifespan behavior
if (this.lifespan <= 0)
{
+159
View File
@@ -0,0 +1,159 @@
/// <reference path="../Game.ts" />
/// <reference path="../geom/Quad.ts" />
/**
* Phaser - ScrollRegion
*
* Creates a scrolling region within a ScrollZone.
* It is scrolled via the scrollSpeed.x/y properties.
*/
module Phaser {
export class ScrollRegion{
constructor(x: number, y: number, width: number, height: number, speedX:number, speedY:number) {
// Our seamless scrolling quads
this._A = new Quad(x, y, width, height);
this._B = new Quad(x, y, width, height);
this._C = new Quad(x, y, width, height);
this._D = new Quad(x, y, width, height);
this._scroll = new MicroPoint();
this._bounds = new Quad(x, y, width, height);
this.scrollSpeed = new MicroPoint(speedX, speedY);
}
private _A: Quad;
private _B: Quad;
private _C: Quad;
private _D: Quad;
private _bounds: Quad;
private _scroll: MicroPoint;
private _anchorWidth: number = 0;
private _anchorHeight: number = 0;
private _inverseWidth: number = 0;
private _inverseHeight: number = 0;
public visible: bool = true;
public scrollSpeed: MicroPoint;
public update(delta: number) {
this._scroll.x += this.scrollSpeed.x;
this._scroll.y += this.scrollSpeed.y;
if (this._scroll.x > this._bounds.right)
{
this._scroll.x = this._bounds.x;
}
if (this._scroll.x < this._bounds.x)
{
this._scroll.x = this._bounds.right;
}
if (this._scroll.y > this._bounds.bottom)
{
this._scroll.y = this._bounds.y;
}
if (this._scroll.y < this._bounds.y)
{
this._scroll.y = this._bounds.bottom;
}
// Anchor Dimensions
this._anchorWidth = (this._bounds.width - this._scroll.x) + this._bounds.x;
this._anchorHeight = (this._bounds.height - this._scroll.y) + this._bounds.y;
if (this._anchorWidth > this._bounds.width)
{
this._anchorWidth = this._bounds.width;
}
if (this._anchorHeight > this._bounds.height)
{
this._anchorHeight = this._bounds.height;
}
this._inverseWidth = this._bounds.width - this._anchorWidth;
this._inverseHeight = this._bounds.height - this._anchorHeight;
// Quad A
this._A.setTo(this._scroll.x, this._scroll.y, this._anchorWidth, this._anchorHeight);
// Quad B
this._B.y = this._scroll.y;
this._B.width = this._inverseWidth;
this._B.height = this._anchorHeight;
// Quad C
this._C.x = this._scroll.x;
this._C.width = this._anchorWidth;
this._C.height = this._inverseHeight;
// Quad D
this._D.width = this._inverseWidth;
this._D.height = this._inverseHeight;
}
public render(context:CanvasRenderingContext2D, texture, dx: number, dy: number, dw: number, dh: number) {
if (this.visible == false)
{
return;
}
// dx/dy are the world coordinates to render the FULL ScrollZone into.
// This ScrollRegion may be smaller than that and offset from the dx/dy coordinates.
this.crop(context, texture, this._A.x, this._A.y, this._A.width, this._A.height, dx, dy, dw, dh, 0, 0);
this.crop(context, texture, this._B.x, this._B.y, this._B.width, this._B.height, dx, dy, dw, dh, this._A.width, 0);
this.crop(context, texture, this._C.x, this._C.y, this._C.width, this._C.height, dx, dy, dw, dh, 0, this._A.height);
this.crop(context, texture, this._D.x, this._D.y, this._D.width, this._D.height, dx, dy, dw, dh, this._C.width, this._A.height);
//context.fillStyle = 'rgb(255,255,255)';
//context.font = '18px Arial';
//context.fillText('QuadA: ' + this._A.toString(), 32, 450);
//context.fillText('QuadB: ' + this._B.toString(), 32, 480);
//context.fillText('QuadC: ' + this._C.toString(), 32, 510);
//context.fillText('QuadD: ' + this._D.toString(), 32, 540);
}
private crop(context, texture, srcX, srcY, srcW, srcH, destX, destY, destW, destH, offsetX, offsetY) {
offsetX += destX;
offsetY += destY;
if (srcW > (destX + destW) - offsetX)
{
srcW = (destX + destW) - offsetX;
}
if (srcH > (destY + destH) - offsetY)
{
srcH = (destY + destH) - offsetY;
}
srcX = Math.floor(srcX);
srcY = Math.floor(srcY);
srcW = Math.floor(srcW);
srcH = Math.floor(srcH);
offsetX = Math.floor(offsetX + this._bounds.x);
offsetY = Math.floor(offsetY + this._bounds.y);
if (srcW > 0 && srcH > 0)
{
context.drawImage(texture, srcX, srcY, srcW, srcH, offsetX, offsetY, srcW, srcH);
}
}
}
}
+208
View File
@@ -0,0 +1,208 @@
/// <reference path="../Game.ts" />
/// <reference path="../geom/Quad.ts" />
/// <reference path="ScrollRegion.ts" />
/**
* Phaser - ScrollZone
*
* Creates a scrolling region of the given width and height from an image in the cache.
* The ScrollZone can be positioned anywhere in-world like a normal game object, re-act to physics, collision, etc.
* The image within it is scrolled via ScrollRegions and their scrollSpeed.x/y properties.
* If you create a scroll zone larger than the given source image it will create a DynamicTexture and fill it with a pattern of the source image.
*/
module Phaser {
export class ScrollZone extends GameObject {
constructor(game: Game, key:string, x: number = 0, y: number = 0, width?: number = 0, height?: number = 0) {
super(game, x, y, width, height);
this.regions = [];
if (this._game.cache.getImage(key))
{
this._texture = this._game.cache.getImage(key);
this.width = this._texture.width;
this.height = this._texture.height;
if (width > this._texture.width || height > this._texture.height)
{
// Create our repeating texture (as the source image wasn't large enough for the requested size)
this.createRepeatingTexture(width, height);
this.width = width;
this.height = height;
}
// Create a default ScrollRegion at the requested size
this.addRegion(0, 0, this.width, this.height);
// If the zone is smaller than the image itself then shrink the bounds
if ((width < this._texture.width || height < this._texture.height) && width !== 0 && height !== 0)
{
this.width = width;
this.height = height;
}
}
}
private _texture;
private _dynamicTexture: DynamicTexture = null;
// local rendering related temp vars to help avoid gc spikes
private _dx: number = 0;
private _dy: number = 0;
private _dw: number = 0;
private _dh: number = 0;
public currentRegion: ScrollRegion;
public regions: ScrollRegion[];
public flipped: bool = false;
public addRegion(x: number, y: number, width: number, height: number, speedX?:number = 0, speedY?:number = 0):ScrollRegion {
if (x > this.width || y > this.height || x < 0 || y < 0 || (x + width) > this.width || (y + height) > this.height)
{
throw Error('Invalid ScrollRegion defined. Cannot be larger than parent ScrollZone');
return;
}
this.currentRegion = new ScrollRegion(x, y, width, height, speedX, speedY);
this.regions.push(this.currentRegion);
return this.currentRegion;
}
public setSpeed(x: number, y: number) {
if (this.currentRegion)
{
this.currentRegion.scrollSpeed.setTo(x, y);
}
return this;
}
public update() {
for (var i = 0; i < this.regions.length; i++)
{
this.regions[i].update(this._game.time.delta);
}
}
public inCamera(camera: Rectangle): bool {
if (this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0)
{
this._dx = this.bounds.x - (camera.x * this.scrollFactor.x);
this._dy = this.bounds.y - (camera.y * this.scrollFactor.x);
this._dw = this.bounds.width * this.scale.x;
this._dh = this.bounds.height * this.scale.y;
return (camera.right > this._dx) && (camera.x < this._dx + this._dw) && (camera.bottom > this._dy) && (camera.y < this._dy + this._dh);
}
else
{
return camera.intersects(this.bounds, this.bounds.length);
}
}
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number) {
// Render checks
if (this.visible == false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.cameraBlacklist.indexOf(camera.ID) !== -1 || this.inCamera(camera.worldView) == false)
{
return false;
}
// Alpha
if (this.alpha !== 1)
{
var globalAlpha = this._game.stage.context.globalAlpha;
this._game.stage.context.globalAlpha = this.alpha;
}
this._dx = cameraOffsetX + (this.bounds.topLeft.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.bounds.topLeft.y - camera.worldView.y);
this._dw = this.bounds.width * this.scale.x;
this._dh = this.bounds.height * this.scale.y;
// Apply camera difference
if (this.scrollFactor.x !== 1.0 || this.scrollFactor.y !== 1.0)
{
this._dx -= (camera.worldView.x * this.scrollFactor.x);
this._dy -= (camera.worldView.y * this.scrollFactor.y);
}
// Rotation - needs to work from origin point really, but for now from center
if (this.angle !== 0 || this.flipped == true)
{
this._game.stage.context.save();
this._game.stage.context.translate(this._dx + (this._dw / 2), this._dy + (this._dh / 2));
if (this.angle !== 0)
{
this._game.stage.context.rotate(this.angle * (Math.PI / 180));
}
this._dx = -(this._dw / 2);
this._dy = -(this._dh / 2);
if (this.flipped == true)
{
this._game.stage.context.scale(-1, 1);
}
}
this._dx = Math.round(this._dx);
this._dy = Math.round(this._dy);
this._dw = Math.round(this._dw);
this._dh = Math.round(this._dh);
for (var i = 0; i < this.regions.length; i++)
{
if (this._dynamicTexture)
{
this.regions[i].render(this._game.stage.context, this._dynamicTexture.canvas, this._dx, this._dy, this._dw, this._dh);
}
else
{
this.regions[i].render(this._game.stage.context, this._texture, this._dx, this._dy, this._dw, this._dh);
}
}
if (globalAlpha > -1)
{
this._game.stage.context.globalAlpha = globalAlpha;
}
return true;
}
private createRepeatingTexture(regionWidth: number, regionHeight: number) {
// Work out how many we'll need of the source image to make it tile properly
var tileWidth = Math.ceil(this._texture.width / regionWidth) * regionWidth;
var tileHeight = Math.ceil(this._texture.height / regionHeight) * regionHeight;
this._dynamicTexture = new DynamicTexture(this._game, tileWidth, tileHeight);
this._dynamicTexture.context.rect(0, 0, tileWidth, tileHeight);
this._dynamicTexture.context.fillStyle = this._dynamicTexture.context.createPattern(this._texture, "repeat");
this._dynamicTexture.context.fill();
}
}
}
+28 -21
View File
@@ -1,6 +1,7 @@
/// <reference path="../Game.ts" />
/// <reference path="../AnimationManager.ts" />
/// <reference path="GameObject.ts" />
/// <reference path="../system/Camera.ts" />
/**
* Phaser - Sprite
@@ -51,6 +52,7 @@ module Phaser {
public renderDebug: bool = false;
public renderDebugColor: string = 'rgba(0,255,0,0.5)';
public renderDebugPointColor: string = 'rgba(255,255,255,1)';
public flipped: bool = false;
public loadGraphic(key: string): Sprite {
@@ -125,7 +127,7 @@ module Phaser {
}
public set frame(value?: number) {
public set frame(value: number) {
this.animations.frame = value;
}
@@ -133,7 +135,7 @@ module Phaser {
return this.animations.frame;
}
public set frameName(value?: string) {
public set frameName(value: string) {
this.animations.frameName = value;
}
@@ -144,7 +146,7 @@ module Phaser {
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number): bool {
// Render checks
if (this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.inCamera(camera.worldView) == false)
if (this.visible == false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1 || this.cameraBlacklist.indexOf(camera.ID) !== -1 || this.inCamera(camera.worldView) == false)
{
return false;
}
@@ -156,13 +158,6 @@ module Phaser {
this._game.stage.context.globalAlpha = this.alpha;
}
//if (this.flip === true)
//{
// this.context.save();
// this.context.translate(game.canvas.width, 0);
// this.context.scale(-1, 1);
//}
this._sx = 0;
this._sy = 0;
this._sw = this.bounds.width;
@@ -228,15 +223,24 @@ module Phaser {
this._dy -= (camera.worldView.y * this.scrollFactor.y);
}
// Rotation
if (this.angle !== 0)
// Rotation - needs to work from origin point really, but for now from center
if (this.angle !== 0 || this.rotationOffset !== 0 || this.flipped == true)
{
this._game.stage.context.save();
//this._game.stage.context.translate(this._dx + (this._dw / 2) - this.origin.x, this._dy + (this._dh / 2) - this.origin.y);
this._game.stage.context.translate(this._dx + (this._dw / 2), this._dy + (this._dh / 2));
this._game.stage.context.rotate(this.angle * (Math.PI / 180));
if (this.renderRotation == true && (this.angle !== 0 || this.rotationOffset !== 0))
{
this._game.stage.context.rotate((this.rotationOffset + this.angle) * (Math.PI / 180));
}
this._dx = -(this._dw / 2);
this._dy = -(this._dh / 2);
if (this.flipped == true)
{
this._game.stage.context.scale(-1, 1);
}
}
this._sx = Math.round(this._sx);
@@ -285,16 +289,15 @@ module Phaser {
this._game.stage.context.fillRect(this._dx, this._dy, this._dw, this._dh);
}
if (this.renderDebug)
if (this.flipped === true || this.rotation !== 0 || this.rotationOffset !== 0)
{
this.renderBounds();
//this._game.stage.context.translate(0, 0);
this._game.stage.context.restore();
}
//if (this.flip === true || this.rotation !== 0)
if (this.rotation !== 0)
if (this.renderDebug)
{
this._game.stage.context.translate(0, 0);
this._game.stage.context.restore();
this.renderBounds(camera, cameraOffsetX, cameraOffsetY);
}
if (globalAlpha > -1)
@@ -306,7 +309,11 @@ module Phaser {
}
private renderBounds() {
// Renders the bounding box around this Sprite and the contact points. Useful for visually debugging.
private renderBounds(camera:Camera, cameraOffsetX:number, cameraOffsetY:number) {
this._dx = cameraOffsetX + (this.bounds.topLeft.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.bounds.topLeft.y - camera.worldView.y);
this._game.stage.context.fillStyle = this.renderDebugColor;
this._game.stage.context.fillRect(this._dx, this._dy, this._dw, this._dh);
+154 -160
View File
@@ -1,271 +1,265 @@
/// <reference path="../Game.ts" />
/// <reference path="GameObject.ts" />
/// <reference path="../system/TilemapLayer.ts" />
/// <reference path="../system/Tile.ts" />
/// <reference path="../system/TilemapBuffer.ts" />
/**
* Phaser - Tilemap
*
* This GameObject allows for the display of a tilemap within the game world. Tile maps consist of an image, tile data and a size.
* Internally it creates a TilemapBuffer for each camera in the world.
* Internally it creates a TilemapLayer for each layer in the tilemap.
*/
module Phaser {
export class Tilemap extends GameObject {
constructor(game: Game, key: string, mapData: string, format: number, tileWidth?: number = 0, tileHeight?: number = 0) {
constructor(game: Game, key: string, mapData: string, format: number, resizeWorld: bool = true, tileWidth?: number = 0, tileHeight?: number = 0) {
super(game);
this._texture = this._game.cache.getImage(key);
this._tilemapBuffers = [];
this.isGroup = false;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.boundsInTiles = new Rectangle();
this.tiles = [];
this.layers = [];
this.mapFormat = format;
switch (format)
{
case Tilemap.FORMAT_CSV:
this.parseCSV(game.cache.getText(mapData));
this.parseCSV(game.cache.getText(mapData), key, tileWidth, tileHeight);
break;
case Tilemap.FORMAT_TILED_JSON:
this.parseTiledJSON(game.cache.getText(mapData));
this.parseTiledJSON(game.cache.getText(mapData), key);
break;
}
this.parseTileOffsets();
this.createTilemapBuffers();
if (this.currentLayer && resizeWorld)
{
this._game.world.setSize(this.currentLayer.widthInPixels, this.currentLayer.heightInPixels, true);
}
}
private _texture;
private _tileOffsets;
private _tilemapBuffers: TilemapBuffer[];
private _dx: number = 0;
private _dy: number = 0;
public static FORMAT_CSV: number = 0;
public static FORMAT_TILED_JSON: number = 1;
public mapData;
public tiles : Tile[];
public layers : TilemapLayer[];
public currentLayer: TilemapLayer;
public collisionLayer: TilemapLayer;
public mapFormat: number;
public boundsInTiles: Rectangle;
public tileWidth: number;
public tileHeight: number;
public update() {
}
public widthInTiles: number = 0;
public heightInTiles: number = 0;
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number) {
public widthInPixels: number = 0;
public heightInPixels: number = 0;
if (this.cameraBlacklist.indexOf(camera.ID) == -1)
{
// Loop through the layers
for (var i = 0; i < this.layers.length; i++)
{
this.layers[i].render(camera, cameraOffsetX, cameraOffsetY);
}
}
// How many extra tiles to draw around the edge of the screen (for fast scrolling games, or to optimise mobile performance try increasing this)
// The number is the amount of extra tiles PER SIDE, so a value of 10 would be (10 tiles + screen size + 10 tiles)
public tileBoundary: number = 10;
}
private parseCSV(data: string) {
private parseCSV(data: string, key: string, tileWidth: number, tileHeight: number) {
//console.log('parseMapData');
this.mapData = [];
var layer: TilemapLayer = new TilemapLayer(this._game, this, key, Tilemap.FORMAT_CSV, 'TileLayerCSV' + this.layers.length.toString(), tileWidth, tileHeight);
// Trim any rogue whitespace from the data
data = data.trim();
var rows = data.split("\n");
//console.log('rows', rows);
for (var i = 0; i < rows.length; i++)
{
var column = rows[i].split(",");
//console.log('column', column);
var output = [];
if (column.length > 0)
{
// Set the width based on the first row
if (this.widthInTiles == 0)
{
// Maybe -1?
this.widthInTiles = column.length;
}
// We have a new row of tiles
this.heightInTiles++;
// Parse it
for (var c = 0; c < column.length; c++)
{
output[c] = parseInt(column[c]);
}
this.mapData.push(output);
layer.addColumn(column);
}
}
//console.log('final map array');
//console.log(this.mapData);
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
if (this.widthInTiles > 0)
{
this.widthInPixels = this.tileWidth * this.widthInTiles;
}
this.currentLayer = layer;
this.collisionLayer = layer;
if (this.heightInTiles > 0)
{
this.heightInPixels = this.tileHeight * this.heightInTiles;
}
this.layers.push(layer);
this.boundsInTiles.setTo(0, 0, this.widthInTiles, this.heightInTiles);
this.generateTiles(tileQuantity);
}
private parseTiledJSON(data: string) {
//console.log('parseTiledJSON');
this.mapData = [];
private parseTiledJSON(data: string, key: string) {
// Trim any rogue whitespace from the data
data = data.trim();
// We ought to change this soon, so we have layer support, but for now let's just get it working
var json = JSON.parse(data);
// Right now we assume no errors at all with the parsing (safe I know)
this.tileWidth = json.tilewidth;
this.tileHeight = json.tileheight;
// Parse the first layer only
this.widthInTiles = json.layers[0].width;
this.heightInTiles = json.layers[0].height;
this.widthInPixels = this.widthInTiles * this.tileWidth;
this.heightInPixels = this.heightInTiles * this.tileHeight;
this.boundsInTiles.setTo(0, 0, this.widthInTiles, this.heightInTiles);
//console.log('width in tiles', this.widthInTiles);
//console.log('height in tiles', this.heightInTiles);
//console.log('width in px', this.widthInPixels);
//console.log('height in px', this.heightInPixels);
// Now let's get the data
var c = 0;
var row;
for (var i = 0; i < json.layers[0].data.length; i++)
for (var i = 0; i < json.layers.length; i++)
{
if (c == 0)
var layer: TilemapLayer = new TilemapLayer(this._game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight);
layer.alpha = json.layers[i].opacity;
layer.visible = json.layers[i].visible;
layer.tileMargin = json.tilesets[0].margin;
layer.tileSpacing = json.tilesets[0].spacing;
var c = 0;
var row;
for (var t = 0; t < json.layers[i].data.length; t++)
{
row = [];
if (c == 0)
{
row = [];
}
row.push(json.layers[i].data[t]);
c++;
if (c == json.layers[i].width)
{
layer.addColumn(row);
c = 0;
}
}
row.push(json.layers[0].data[i]);
layer.updateBounds();
c++;
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
if (c == this.widthInTiles)
{
this.mapData.push(row);
c = 0;
}
}
//console.log('mapData');
//console.log(this.mapData);
this.generateTiles(tileQuantity);
}
public getMapSegment(area: Rectangle) {
}
private generateTiles(qty:number) {
private createTilemapBuffers() {
var cams = this._game.world.getAllCameras();
for (var i = 0; i < cams.length; i++)
for (var i = 0; i < qty; i++)
{
this._tilemapBuffers[cams[i].ID] = new TilemapBuffer(this._game, cams[i], this, this._texture, this._tileOffsets);
this.tiles.push(new Tile(this._game, this, i, this.currentLayer.tileWidth, this.currentLayer.tileHeight));
}
}
private parseTileOffsets() {
public get widthInPixels(): number {
return this.currentLayer.widthInPixels;
}
this._tileOffsets = [];
public get heightInPixels(): number {
return this.currentLayer.heightInPixels;
}
var i = 0;
// Tile Collision
if (this.mapFormat == Tilemap.FORMAT_TILED_JSON)
public setCollisionRange(start: number, end: number, collision?:number = Collision.ANY, resetCollisions: bool = false) {
for (var i = start; i < end; i++)
{
// For some reason Tiled counts from 1 not 0
this._tileOffsets[0] = null;
i = 1;
}
for (var ty = 0; ty < this._texture.height; ty += this.tileHeight)
{
for (var tx = 0; tx < this._texture.width; tx += this.tileWidth)
{
this._tileOffsets[i] = { x: tx, y: ty };
i++;
}
this.tiles[i].setCollision(collision, resetCollisions);
}
}
/*
// Use a Signal?
public addTilemapBuffers(camera:Camera) {
console.log('added new camera to tilemap');
this._tilemapBuffers[camera.ID] = new TilemapBuffer(this._game, camera, this, this._texture, this._tileOffsets);
}
*/
public setCollisionByIndex(values:number[], collision?:number = Collision.ANY, resetCollisions: bool = false) {
public update() {
// Check if any of the cameras have scrolled far enough for us to need to refresh a TilemapBuffer
this._tilemapBuffers[0].update();
}
public renderDebugInfo(x: number, y: number, color?: string = 'rgb(255,255,255)') {
this._tilemapBuffers[0].renderDebugInfo(x, y, color);
}
public render(camera: Camera, cameraOffsetX: number, cameraOffsetY: number): bool {
if (this.visible === false || this.scale.x == 0 || this.scale.y == 0 || this.alpha < 0.1)
for (var i = 0; i < values.length; i++)
{
return false;
this.tiles[values[i]].setCollision(collision, resetCollisions);
}
this._dx = cameraOffsetX + (this.bounds.x - camera.worldView.x);
this._dy = cameraOffsetY + (this.bounds.y - camera.worldView.y);
}
this._dx = Math.round(this._dx);
this._dy = Math.round(this._dy);
// Tile Management
if (this._tilemapBuffers[camera.ID])
public getTile(x: number, y: number, layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileIndex(x, y)];
}
public getTileFromWorldXY(x: number, y: number, layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileFromWorldXY(x, y)];
}
public getTileFromInputXY(layer?: number = 0):Tile {
return this.tiles[this.layers[layer].getTileFromWorldXY(this._game.input.worldX, this._game.input.worldY)];
}
public getTileOverlaps(object: GameObject) {
return this.currentLayer.getTileOverlaps(object);
}
// COLLIDE
public collide(objectOrGroup = null, callback = null): bool {
if (objectOrGroup == null)
{
//this._tilemapBuffers[camera.ID].render(this._dx, this._dy);
this._tilemapBuffers[camera.ID].render(cameraOffsetX, cameraOffsetY);
objectOrGroup = this._game.world.group;
}
// Group?
if (objectOrGroup.isGroup == false)
{
return this.collideGameObject(objectOrGroup);
}
else
{
objectOrGroup.forEachAlive(this, this.collideGameObject, true);
}
return true;
}
public collideGameObject(object: GameObject): bool {
if (object == this) { return false; }
if (object.immovable == false && object.exists == true && object.allowCollisions != Collision.NONE)
{
return this.collisionLayer.getTileOverlaps(object);
}
else
{
return false;
}
}
// Set current layer
// Set layer order?
// Get block of tiles
// Swap tiles around
// Delete tiles of certain type
// Erase tiles
}
}
+1 -1
View File
@@ -262,7 +262,7 @@ module Phaser {
**/
get isEmpty(): bool {
if (this._diameter < 1)
if (this._diameter <= 0)
{
return true;
}
+106
View File
@@ -0,0 +1,106 @@
/// <reference path="../Game.ts" />
/**
* Phaser - Quad
*
* A Quad object is an area defined by its position, as indicated by its top-left corner (x,y) and width and height.
* Very much like a Rectangle only without all of the additional methods and properties of that class.
*/
module Phaser {
export class Quad {
/**
* Creates a new Quad object with the top-left corner specified by the x and y parameters and with the specified width and height parameters. If you call this function without parameters, a rectangle with x, y, width, and height properties set to 0 is created.
* @class Quad
* @constructor
* @param {Number} x The x coordinate of the top-left corner of the quad.
* @param {Number} y The y coordinate of the top-left corner of the quad.
* @param {Number} width The width of the quad.
* @param {Number} height The height of the quad.
* @return {Quad } This object
**/
constructor(x: number = 0, y: number = 0, width: number = 0, height: number = 0) {
this.setTo(x, y, width, height);
}
public x: number;
public y: number;
public width: number;
public height: number;
/**
* Sets the Quad to the specified size.
* @method setTo
* @param {Number} x The x coordinate of the top-left corner of the quad.
* @param {Number} y The y coordinate of the top-left corner of the quad.
* @param {Number} width The width of the quad.
* @param {Number} height The height of the quad.
* @return {Quad} This object
**/
public setTo(x: number, y: number, width: number, height: number): Quad {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
}
public get left(): number {
return this.x;
}
public get right(): number {
return this.x + this.width;
}
public get top(): number {
return this.y;
}
public get bottom(): number {
return this.y + this.height;
}
public get halfWidth(): number {
return this.width / 2;
}
public get halfHeight(): number {
return this.height / 2;
}
/**
* Determines whether the object specified intersects (overlaps) with this Quad object.
* This method checks the x, y, width, and height properties of the specified Quad object to see if it intersects with this Quad object.
* @method intersects
* @param {Object} q The object to check for intersection with this Quad. Must have left/right/top/bottom properties (Rectangle, Quad).
* @param {Number} t A tolerance value to allow for an intersection test with padding, default to 0
* @return {Boolean} A value of true if the specified object intersects with this Quad; otherwise false.
**/
public intersects(q, t?: number = 0): bool {
return !(q.left > this.right + t || q.right < this.left - t || q.top > this.bottom + t || q.bottom < this.top - t);
}
/**
* Returns a string representation of this object.
* @method toString
* @return {string} a string representation of the object.
**/
public toString(): string {
return "[{Quad (x=" + this.x + " y=" + this.y + " width=" + this.width + " height=" + this.height + ")}]";
}
}
}
+4 -3
View File
@@ -12,13 +12,14 @@ module Phaser {
export class Rectangle {
/**
* Creates a new Rectangle object with the top-left corner specified by the x and y parameters and with the specified width and height parameters. If you call this function without parameters, a rectangle with x, y, width, and height properties set to 0 is created.
* Creates a new Rectangle object with the top-left corner specified by the x and y parameters and with the specified width and height parameters.
* If you call this function without parameters, a rectangle with x, y, width, and height properties set to 0 is created.
* @class Rectangle
* @constructor
* @param {Number} x The x coordinate of the top-left corner of the rectangle.
* @param {Number} y The y coordinate of the top-left corner of the rectangle.
* @param {Number} width The width of the rectangle in pixels.
* @param {Number} height The height of the rectangle in pixels.
* @param {Number} width The width of the rectangle.
* @param {Number} height The height of the rectangle.
* @return {Rectangle} This rectangle object
**/
constructor(x: number = 0, y: number = 0, width: number = 0, height: number = 0) {
+3
View File
@@ -0,0 +1,3 @@
node_modules
.npm-debug.log
tmp
+5
View File
@@ -0,0 +1,5 @@
language: node_js
node_js:
- 0.8
before_script:
- npm install -g grunt-cli
+4
View File
@@ -0,0 +1,4 @@
"Cowboy" Ben Alman (http://benalman.com/)
Kyle Robinson Young (http://dontkry.com/)
Tyler Kellen (http://goingslowly.com)
Sindre Sorhus (http://sindresorhus.com)
+23
View File
@@ -0,0 +1,23 @@
v0.4.1:
date: 2013-03-13
changes:
- Fix path.join thrown errors with expandMapping rename. Closes gh-725.
- Update copyright date to 2013. Closes gh-660.
- Remove some side effects from manually requiring Grunt. Closes gh-605.
- grunt.log: add formatting support and implicitly cast msg to a string. Closes gh-703.
- Update js-yaml to version 2. Closes gh-683.
- The grunt.util.spawn method now falls back to stdout when the `grunt` option is set. Closes gh-691.
- Making --verbose "Files:" warnings less scary. Closes gh-657.
- Fixing typo: the grunt.fatal method now defaults to FATAL_ERROR. Closes gh-656, gh-707.
- Removed a duplicate line. Closes gh-702.
- Gruntfile name should no longer be case sensitive. Closes gh-685.
- The grunt.file.delete method warns and returns false if file doesn't exist. Closes gh-635, gh-714.
- The grunt.package property is now resolved via require(). Closes gh-704.
- The grunt.util.spawn method no longer breaks on multibyte stdio. Closes gh-710.
- Fix "path.join arguments must be strings" error in file.expand/recurse when options.cwd is not set. Closes gh-722.
- Adding a fairly relevant keyword to package.json (task).
v0.4.0:
date: 2013-02-18
changes:
- Initial release of 0.4.0.
- See http://gruntjs.com/upgrading-from-0.3-to-0.4 for a list of changes / migration guide.
+1
View File
@@ -0,0 +1 @@
Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.
+22
View File
@@ -0,0 +1,22 @@
Copyright (c) 2013 "Cowboy" Ben Alman
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+13
View File
@@ -0,0 +1,13 @@
# Grunt: The JavaScript Task Runner [![Build Status](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)
### Documentation
Visit the [gruntjs.com](http://gruntjs.com/) website for all the things.
### Support / Contributing
Before you make an issue, please read our [Contributing](http://gruntjs.com/contributing) guide.
You can find the grunt team in [#grunt on irc.freenode.net](irc://irc.freenode.net/#grunt).
### Release History
See the [CHANGELOG](CHANGELOG).
+1
View File
@@ -0,0 +1 @@
Visit the [gruntjs.com](http://gruntjs.com/) website for all the things.
+1
View File
@@ -0,0 +1 @@
../coffee-script/bin/cake
+1
View File
@@ -0,0 +1 @@
../coffee-script/bin/coffee
+1
View File
@@ -0,0 +1 @@
../js-yaml/bin/js-yaml.js
+1
View File
@@ -0,0 +1 @@
../lodash/build.js
+1
View File
@@ -0,0 +1 @@
../nopt/bin/nopt.js
+1
View File
@@ -0,0 +1 @@
../which/bin/which
@@ -0,0 +1,9 @@
[submodule "deps/nodeunit"]
path = deps/nodeunit
url = git://github.com/caolan/nodeunit.git
[submodule "deps/UglifyJS"]
path = deps/UglifyJS
url = https://github.com/mishoo/UglifyJS.git
[submodule "deps/nodelint"]
path = deps/nodelint
url = https://github.com/tav/nodelint.git
+4
View File
@@ -0,0 +1,4 @@
deps
dist
test
nodelint.cfg
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2010 Caolan McMahon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+25
View File
@@ -0,0 +1,25 @@
PACKAGE = asyncjs
NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node)
CWD := $(shell pwd)
NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit
UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs
NODELINT = $(CWD)/node_modules/nodelint/nodelint
BUILDDIR = dist
all: clean test build
build: $(wildcard lib/*.js)
mkdir -p $(BUILDDIR)
$(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js
test:
$(NODEUNIT) test
clean:
rm -rf $(BUILDDIR)
lint:
$(NODELINT) --config nodelint.cfg lib/async.js
.PHONY: test build all
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
*.coffee
*.html
.DS_Store
.git*
Cakefile
documentation/
examples/
extras/coffee-script.js
raw/
src/
test/
+1
View File
@@ -0,0 +1 @@
coffeescript.org
+22
View File
@@ -0,0 +1,22 @@
Copyright (c) 2009-2012 Jeremy Ashkenas
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+51
View File
@@ -0,0 +1,51 @@
{
} } {
{ { } }
} }{ {
{ }{ } } _____ __ __
( }{ }{ { ) / ____| / _|/ _|
.- { { } { }} -. | | ___ | |_| |_ ___ ___
( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
|`-..________ ..-'| | |___| (_) | | | || __/ __/
| | \_____\___/|_| |_| \___|\___|
| ;--.
| (__ \ _____ _ _
| | ) ) / ____| (_) | |
| |/ / | (___ ___ _ __ _ _ __ | |_
| ( / \___ \ / __| '__| | '_ \| __|
| |/ ____) | (__| | | | |_) | |_
| | |_____/ \___|_| |_| .__/ \__|
`-.._________..-' | |
|_|
CoffeeScript is a little language that compiles into JavaScript.
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
npm install -g coffee-script
(Leave off the -g if you don't wish to install globally.)
Execute a script:
coffee /path/to/script.coffee
Compile a script:
coffee -c /path/to/script.coffee
For documentation, usage, and examples, see:
http://coffeescript.org/
To suggest a feature, report a bug, or general discussion:
http://github.com/jashkenas/coffee-script/issues/
If you'd like to chat, drop by #coffeescript on Freenode IRC,
or on webchat.freenode.net.
The source repository:
git://github.com/jashkenas/coffee-script.git
All contributors are listed here:
http://github.com/jashkenas/coffee-script/contributors
+78
View File
@@ -0,0 +1,78 @@
require 'rubygems'
require 'erb'
require 'fileutils'
require 'rake/testtask'
require 'json'
desc "Build the documentation page"
task :doc do
source = 'documentation/index.html.erb'
child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" }
at_exit { Process.kill("INT", child) }
Signal.trap("INT") { exit }
loop do
mtime = File.stat(source).mtime
if !@mtime || mtime > @mtime
rendered = ERB.new(File.read(source)).result(binding)
File.open('index.html', 'w+') {|f| f.write(rendered) }
end
@mtime = mtime
sleep 1
end
end
desc "Build coffee-script-source gem"
task :gem do
require 'rubygems'
require 'rubygems/package'
gemspec = Gem::Specification.new do |s|
s.name = 'coffee-script-source'
s.version = JSON.parse(File.read('package.json'))["version"]
s.date = Time.now.strftime("%Y-%m-%d")
s.homepage = "http://jashkenas.github.com/coffee-script/"
s.summary = "The CoffeeScript Compiler"
s.description = <<-EOS
CoffeeScript is a little language that compiles into JavaScript.
Underneath all of those embarrassing braces and semicolons,
JavaScript has always had a gorgeous object model at its heart.
CoffeeScript is an attempt to expose the good parts of JavaScript
in a simple way.
EOS
s.files = [
'lib/coffee_script/coffee-script.js',
'lib/coffee_script/source.rb'
]
s.authors = ['Jeremy Ashkenas']
s.email = 'jashkenas@gmail.com'
s.rubyforge_project = 'coffee-script-source'
end
file = File.open("coffee-script-source.gem", "w")
Gem::Package.open(file, 'w') do |pkg|
pkg.metadata = gemspec.to_yaml
path = "lib/coffee_script/source.rb"
contents = <<-ERUBY
module CoffeeScript
module Source
def self.bundled_path
File.expand_path("../coffee-script.js", __FILE__)
end
end
end
ERUBY
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
contents = File.read("extras/coffee-script.js")
path = "lib/coffee_script/coffee-script.js"
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
end
end
+44
View File
@@ -0,0 +1,44 @@
# JavaScriptLint configuration file for CoffeeScript.
+no_return_value # function {0} does not always return a value
+duplicate_formal # duplicate formal argument {0}
-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
+var_hides_arg # variable {0} hides argument
+redeclared_var # redeclaration of {0} {1}
-anon_no_return_value # anonymous function does not always return a value
+missing_semicolon # missing semicolon
+meaningless_block # meaningless block; curly braces have no impact
-comma_separated_stmts # multiple statements separated by commas (use semicolons?)
+unreachable_code # unreachable code
+missing_break # missing break statement
-missing_break_for_last_case # missing break statement for last case in switch
-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
-useless_void # use of the void type may be unnecessary (void is always undefined)
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
+use_of_label # use of label
-block_without_braces # block statement without curly braces
+leading_decimal_point # leading decimal point may indicate a number or an object member
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
+octal_number # leading zeros make an octal number
+nested_comment # nested comment
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
+empty_statement # empty statement or extra semicolon
-missing_option_explicit # the "option explicit" control comment is missing
+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
+dup_option_explicit # duplicate "option explicit" control comment
+useless_assign # useless assignment
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
-missing_default_case # missing default case in switch statement
+duplicate_case_in_switch # duplicate case in switch statements
+default_not_at_end # the default case is not at the end of the switch statement
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
+useless_comparison # useless comparison; comparing identical expressions
+with_statement # with statement hides undeclared variables; use temporary variable instead
+trailing_comma_in_array # extra comma is not recommended in array initializers
+assign_to_function_call # assignment to a function call
+parseint_missing_radix # parseInt missing radix parameter
+lambda_assign_requires_semicolon
+49
View File
@@ -0,0 +1,49 @@
{
"name": "coffee-script",
"description": "Unfancy JavaScript",
"keywords": [
"javascript",
"language",
"coffeescript",
"compiler"
],
"author": {
"name": "Jeremy Ashkenas"
},
"version": "1.3.3",
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
}
],
"engines": {
"node": ">=0.4.0"
},
"directories": {
"lib": "./lib/coffee-script"
},
"main": "./lib/coffee-script/coffee-script",
"bin": {
"coffee": "./bin/coffee",
"cake": "./bin/cake"
},
"homepage": "http://coffeescript.org",
"bugs": "https://github.com/jashkenas/coffee-script/issues",
"repository": {
"type": "git",
"url": "git://github.com/jashkenas/coffee-script.git"
},
"devDependencies": {
"uglify-js": ">=1.0.0",
"jison": ">=0.2.0"
},
"readme": "\n {\n } } {\n { { } }\n } }{ {\n { }{ } } _____ __ __\n ( }{ }{ { ) / ____| / _|/ _|\n .- { { } { }} -. | | ___ | |_| |_ ___ ___\n ( ( } { } { } } ) | | / _ \\| _| _/ _ \\/ _ \\\n |`-..________ ..-'| | |___| (_) | | | || __/ __/\n | | \\_____\\___/|_| |_| \\___|\\___|\n | ;--.\n | (__ \\ _____ _ _\n | | ) ) / ____| (_) | |\n | |/ / | (___ ___ _ __ _ _ __ | |_\n | ( / \\___ \\ / __| '__| | '_ \\| __|\n | |/ ____) | (__| | | | |_) | |_\n | | |_____/ \\___|_| |_| .__/ \\__|\n `-.._________..-' | |\n |_|\n\n\n CoffeeScript is a little language that compiles into JavaScript.\n\n Install Node.js, and then the CoffeeScript compiler:\n sudo bin/cake install\n\n Or, if you have the Node Package Manager installed:\n npm install -g coffee-script\n (Leave off the -g if you don't wish to install globally.)\n\n Execute a script:\n coffee /path/to/script.coffee\n\n Compile a script:\n coffee -c /path/to/script.coffee\n\n For documentation, usage, and examples, see:\n http://coffeescript.org/\n\n To suggest a feature, report a bug, or general discussion:\n http://github.com/jashkenas/coffee-script/issues/\n\n If you'd like to chat, drop by #coffeescript on Freenode IRC,\n or on webchat.freenode.net.\n\n The source repository:\n git://github.com/jashkenas/coffee-script.git\n\n All contributors are listed here:\n http://github.com/jashkenas/coffee-script/contributors\n",
"readmeFilename": "README",
"_id": "coffee-script@1.3.3",
"dist": {
"shasum": "d41e076292bcf98fbb2753e76e1a07a8be5db9b7"
},
"_from": "coffee-script@~1.3.3",
"_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz"
}
+22
View File
@@ -0,0 +1,22 @@
Copyright (c) 2010
Marak Squires
Alexis Sellier (cloudhead)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+77
View File
@@ -0,0 +1,77 @@
# colors.js - get color and style in your node.js console ( and browser ) like what
<img src="http://i.imgur.com/goJdO.png" border = "0"/>
## Installation
npm install colors
## colors and styles!
- bold
- italic
- underline
- inverse
- yellow
- cyan
- white
- magenta
- green
- red
- grey
- blue
- rainbow
- zebra
- random
## Usage
``` js
var colors = require('./colors');
console.log('hello'.green); // outputs green text
console.log('i like cake and pies'.underline.red) // outputs red underlined text
console.log('inverse the color'.inverse); // inverses the color
console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)
```
# Creating Custom themes
```js
var require('colors');
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
console.log("this is an error".error);
// outputs yellow text
console.log("this is a warning".warn);
```
### Contributors
Marak (Marak Squires)
Alexis Sellier (cloudhead)
mmalecki (Maciej Małecki)
nicoreed (Nico Reed)
morganrallen (Morgan Allen)
JustinCampbell (Justin Campbell)
ded (Dustin Diaz)
#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded)
+74
View File
@@ -0,0 +1,74 @@
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Colors Example</title>
<script src="colors.js"></script>
</head>
<body>
<script>
var test = colors.red("hopefully colorless output");
document.write('Rainbows are fun!'.rainbow + '<br/>');
document.write('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
document.write('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
//document.write('zalgo time!'.zalgo);
document.write(test.stripColors);
document.write("a".grey + " b".black);
document.write("Zebras are so fun!".zebra);
document.write(colors.rainbow('Rainbows are fun!'));
document.write(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
document.write(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
//document.write(colors.zalgo('zalgo time!'));
document.write(colors.stripColors(test));
document.write(colors.grey("a") + colors.black(" b"));
colors.addSequencer("america", function(letter, i, exploded) {
if(letter === " ") return letter;
switch(i%3) {
case 0: return letter.red;
case 1: return letter.white;
case 2: return letter.blue;
}
});
colors.addSequencer("random", (function() {
var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
return function(letter, i, exploded) {
return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]];
};
})());
document.write("AMERICA! F--K YEAH!".america);
document.write("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random);
//
// Custom themes
//
colors.setTheme({
silly: 'rainbow',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
debug: 'blue',
error: 'red'
});
// outputs red text
document.write("this is an error".error);
// outputs yellow text
document.write("this is a warning".warn);
</script>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
{
"name": "colors",
"description": "get colors in your node.js console like what",
"version": "0.6.0-1",
"author": {
"name": "Marak Squires"
},
"repository": {
"type": "git",
"url": "http://github.com/Marak/colors.js.git"
},
"engines": {
"node": ">=0.1.90"
},
"main": "colors",
"readme": "# colors.js - get color and style in your node.js console ( and browser ) like what\n\n<img src=\"http://i.imgur.com/goJdO.png\" border = \"0\"/>\n\n\n## Installation\n\n npm install colors\n\n## colors and styles!\n\n- bold\n- italic\n- underline\n- inverse\n- yellow\n- cyan\n- white\n- magenta\n- green\n- red\n- grey\n- blue\n- rainbow\n- zebra\n- random\n\n## Usage\n\n``` js\nvar colors = require('./colors');\n\nconsole.log('hello'.green); // outputs green text\nconsole.log('i like cake and pies'.underline.red) // outputs red underlined text\nconsole.log('inverse the color'.inverse); // inverses the color\nconsole.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)\n```\n\n# Creating Custom themes\n\n```js\n\nvar require('colors');\n\ncolors.setTheme({\n silly: 'rainbow',\n input: 'grey',\n verbose: 'cyan',\n prompt: 'grey',\n info: 'green',\n data: 'grey',\n help: 'cyan',\n warn: 'yellow',\n debug: 'blue',\n error: 'red'\n});\n\n// outputs red text\nconsole.log(\"this is an error\".error);\n\n// outputs yellow text\nconsole.log(\"this is a warning\".warn);\n```\n\n\n### Contributors \n\nMarak (Marak Squires)\nAlexis Sellier (cloudhead)\nmmalecki (Maciej Małecki)\nnicoreed (Nico Reed)\nmorganrallen (Morgan Allen)\nJustinCampbell (Justin Campbell)\nded (Dustin Diaz)\n\n\n#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded)\n",
"readmeFilename": "ReadMe.md",
"_id": "colors@0.6.0-1",
"dist": {
"shasum": "322d52c6f629babb21b1713e6365d1b6ec1937bd"
},
"_from": "colors@~0.6.0-1",
"_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.0-1.tgz"
}
+67
View File
@@ -0,0 +1,67 @@
# node-dateformat
A node.js package for Steven Levithan's excellent [dateFormat()][dateformat] function.
## Modifications
* Removed the `Date.prototype.format` method. Sorry folks, but extending native prototypes is for suckers.
* Added a `module.exports = dateFormat;` statement at the bottom
## Usage
As taken from Steven's post, modified to match the Modifications listed above:
var dateFormat = require('dateformat');
var now = new Date();
// Basic usage
dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");
// Saturday, June 9th, 2007, 5:46:21 PM
// You can use one of several named masks
dateFormat(now, "isoDateTime");
// 2007-06-09T17:46:21
// ...Or add your own
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
dateFormat(now, "hammerTime");
// 17:46! Can't touch this!
// When using the standalone dateFormat function,
// you can also provide the date as a string
dateFormat("Jun 9 2007", "fullDate");
// Saturday, June 9, 2007
// Note that if you don't include the mask argument,
// dateFormat.masks.default is used
dateFormat(now);
// Sat Jun 09 2007 17:46:21
// And if you don't include the date argument,
// the current date and time is used
dateFormat();
// Sat Jun 09 2007 17:46:22
// You can also skip the date argument (as long as your mask doesn't
// contain any numbers), in which case the current date/time is used
dateFormat("longTime");
// 5:46:22 PM EST
// And finally, you can convert local time to UTC time. Simply pass in
// true as an additional argument (no argument skipping allowed in this case):
dateFormat(now, "longTime", true);
// 10:46:21 PM UTC
// ...Or add the prefix "UTC:" to your mask.
dateFormat(now, "UTC:h:MM:ss TT Z");
// 10:46:21 PM UTC
// You can also get the ISO 8601 week of the year:
dateFormat(now, "W");
// 42
## License
(c) 2007-2009 Steven Levithan [stevenlevithan.com][stevenlevithan], MIT license.
[dateformat]: http://blog.stevenlevithan.com/archives/date-time-format
[stevenlevithan]: http://stevenlevithan.com/
+24
View File
@@ -0,0 +1,24 @@
{
"name": "dateformat",
"description": "A node.js package for Steven Levithan's excellent dateFormat() function.",
"maintainers": "Felix Geisendörfer <felix@debuggable.com>",
"homepage": "https://github.com/felixge/node-dateformat",
"author": {
"name": "Steven Levithan"
},
"version": "1.0.2-1.2.3",
"main": "./lib/dateformat",
"dependencies": {},
"devDependencies": {},
"engines": {
"node": "*"
},
"readme": "# node-dateformat\n\nA node.js package for Steven Levithan's excellent [dateFormat()][dateformat] function.\n\n## Modifications\n\n* Removed the `Date.prototype.format` method. Sorry folks, but extending native prototypes is for suckers.\n* Added a `module.exports = dateFormat;` statement at the bottom\n\n## Usage\n\nAs taken from Steven's post, modified to match the Modifications listed above:\n\n var dateFormat = require('dateformat');\n var now = new Date();\n\n // Basic usage\n dateFormat(now, \"dddd, mmmm dS, yyyy, h:MM:ss TT\");\n // Saturday, June 9th, 2007, 5:46:21 PM\n\n // You can use one of several named masks\n dateFormat(now, \"isoDateTime\");\n // 2007-06-09T17:46:21\n\n // ...Or add your own\n dateFormat.masks.hammerTime = 'HH:MM! \"Can\\'t touch this!\"';\n dateFormat(now, \"hammerTime\");\n // 17:46! Can't touch this!\n\n // When using the standalone dateFormat function,\n // you can also provide the date as a string\n dateFormat(\"Jun 9 2007\", \"fullDate\");\n // Saturday, June 9, 2007\n\n // Note that if you don't include the mask argument,\n // dateFormat.masks.default is used\n dateFormat(now);\n // Sat Jun 09 2007 17:46:21\n\n // And if you don't include the date argument,\n // the current date and time is used\n dateFormat();\n // Sat Jun 09 2007 17:46:22\n\n // You can also skip the date argument (as long as your mask doesn't\n // contain any numbers), in which case the current date/time is used\n dateFormat(\"longTime\");\n // 5:46:22 PM EST\n\n // And finally, you can convert local time to UTC time. Simply pass in\n // true as an additional argument (no argument skipping allowed in this case):\n dateFormat(now, \"longTime\", true);\n // 10:46:21 PM UTC\n\n // ...Or add the prefix \"UTC:\" to your mask.\n dateFormat(now, \"UTC:h:MM:ss TT Z\");\n // 10:46:21 PM UTC\n\n // You can also get the ISO 8601 week of the year:\n dateFormat(now, \"W\");\n // 42\n## License\n\n(c) 2007-2009 Steven Levithan [stevenlevithan.com][stevenlevithan], MIT license.\n\n[dateformat]: http://blog.stevenlevithan.com/archives/date-time-format\n[stevenlevithan]: http://stevenlevithan.com/\n",
"readmeFilename": "Readme.md",
"_id": "dateformat@1.0.2-1.2.3",
"dist": {
"shasum": "692290ea53102d50a82968882eab448a048a7f23"
},
"_from": "dateformat@1.0.2-1.2.3",
"_resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz"
}
@@ -0,0 +1,27 @@
#!/bin/bash
# this just takes php's date() function as a reference to check if week of year
# is calculated correctly in the range from 1970 .. 2038 by brute force...
SEQ="seq"
SYSTEM=`uname`
if [ "$SYSTEM" = "Darwin" ]; then
SEQ="jot"
fi
for YEAR in {1970..2038}; do
for MONTH in {1..12}; do
DAYS=$(cal $MONTH $YEAR | egrep "28|29|30|31" |tail -1 |awk '{print $NF}')
for DAY in $( $SEQ $DAYS ); do
DATE=$YEAR-$MONTH-$DAY
echo -n $DATE ...
NODEVAL=$(node test_weekofyear.js $DATE)
PHPVAL=$(php -r "echo intval(date('W', strtotime('$DATE')));")
if [ "$NODEVAL" -ne "$PHPVAL" ]; then
echo "MISMATCH: node: $NODEVAL vs php: $PHPVAL for date $DATE"
else
echo " OK"
fi
done
done
done
+13
View File
@@ -0,0 +1,13 @@
#ignore these files
*.swp
*~
*.lock
*.DS_Store
node_modules
npm-debug.log
*.out
*.o
*.tmp
+212
View File
@@ -0,0 +1,212 @@
# EventEmitter2
EventEmitter2 is a an implementation of the EventEmitter found in Node.js
## Features
- Namespaces/Wildcards.
- Times To Listen (TTL), extends the `once` concept with `many`.
- Browser environment compatibility.
- Demonstrates good performance in benchmarks
```
EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled)
EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled)
EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled)
EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled)
Fastest is EventEmitter2
```
## Differences (Non breaking, compatible with existing EventEmitter)
- The constructor takes a configuration object.
```javascript
var EventEmitter2 = require('eventemitter2').EventEmitter2;
var server = new EventEmitter2({
wildcard: true, // should the event emitter use wildcards.
delimiter: '::', // the delimiter used to segment namespaces, defaults to `.`.
newListener: false, // if you want to emit the newListener event set to true.
maxListeners: 20, // the max number of listeners that can be assigned to an event, defaults to 10.
});
```
- Getting the actual event that fired.
```javascript
server.on('foo.*', function(value1, value2) {
console.log(this.event, value1, value2);
});
```
- Fire an event N times and then remove it, an extension of the `once` concept.
```javascript
server.many('foo', 4, function() {
console.log('hello');
});
```
- Pass in a namespaced event as an array rather than a delimited string.
```javascript
server.many(['foo', 'bar', 'bazz'], function() {
console.log('hello');
});
```
## API
When an `EventEmitter` instance experiences an error, the typical action is
to emit an `error` event. Error events are treated as a special case.
If there is no listener for it, then the default action is to print a stack
trace and exit the program.
All EventEmitters emit the event `newListener` when new listeners are
added.
**Namespaces** with **Wildcards**
To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter constructor.
When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated
by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a
constructor option.
An event name passed to any event emitter method can contain a wild card (the `*` character).
If the event name is a string, a wildcard may appear as `foo.*`. If the event name is an array,
the wildcard may appear as `['foo', '*']`.
If either of the above described events were passed to the `on` method, subsequent emits such
as the following would be observed...
```javascript
emitter.emit('foo.bazz');
emitter.emit(['foo', 'bar']);
```
#### emitter.addListener(event, listener)
#### emitter.on(event, listener)
Adds a listener to the end of the listeners array for the specified event.
```javascript
server.on('data', function(value1, value2, value3 /* accepts any number of expected values... */) {
console.log('The event was raised!');
});
```
```javascript
server.on('data', function(value) {
console.log('The event was raised!');
});
```
#### emitter.onAny(listener)
Adds a listener that will be fired when any event is emitted.
```javascript
server.onAny(function(value) {
console.log('All events trigger this.');
});
```
#### emitter.offAny(listener)
Removes the listener that will be fired when any event is emitted.
```javascript
server.offAny(function(value) {
console.log('The event was raised!');
});
```
#### emitter.once(event, listener)
Adds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed.
```javascript
server.once('get', function (value) {
console.log('Ah, we have our first value!');
});
```
#### emitter.many(event, timesToListen, listener)
Adds a listener that will execute **n times** for the event before being removed. The listener is invoked only the first time the event is fired, after which it is removed.
```javascript
server.many('get', 4, function (value) {
console.log('This event will be listened to exactly four times.');
});
```
#### emitter.removeListener(event, listener)
#### emitter.off(event, listener)
Remove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener.
```javascript
var callback = function(value) {
console.log('someone connected!');
};
server.on('get', callback);
// ...
server.removeListener('get', callback);
```
#### emitter.removeAllListeners([event])
Removes all listeners, or those of the specified event.
#### emitter.setMaxListeners(n)
By default EventEmitters will print a warning if more than 10 listeners are added to it. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited.
#### emitter.listeners(event)
Returns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners.
```javascript
server.on('get', function(value) {
console.log('someone connected!');
});
console.log(console.log(server.listeners('get')); // [ [Function] ]
```
#### emitter.listenersAny()
Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners.
```javascript
server.onAny(function(value) {
console.log('someone connected!');
});
console.log(console.log(server.listenersAny()[0]); // [ [Function] ] // someone connected!
```
#### emitter.emit(event, [arg1], [arg2], [...])
Execute each of the listeners that may be listening for the specified event name in order with the list of arguments.
## Test coverage
There is a test suite that tries to cover each use case, it can be found <a href="https://github.com/hij1nx/EventEmitter2/tree/master/test">here</a>.
## Licence
(The MIT License)
Copyright (c) 2011 hij1nx <http://www.twitter.com/hij1nx>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File diff suppressed because one or more lines are too long
+16
View File
@@ -0,0 +1,16 @@
{
"loopfunc": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"node": true,
"es5": true
}
View File
+22
View File
@@ -0,0 +1,22 @@
Copyright (c) 2013 "Cowboy" Ben Alman
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+44
View File
@@ -0,0 +1,44 @@
# findup-sync
Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
## Getting Started
Install the module with: `npm install findup-sync`
```js
var findup = require('findup-sync');
// Start looking in the CWD.
var filepath1 = findup('{a,b}*.txt');
// Start looking somewhere else, and ignore case (probably a good idea).
var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true});
```
## Usage
```js
findup(patternOrPatterns [, minimatchOptions])
```
### patternOrPatterns
Type: `String` or `Array`
Default: none
One or more wildcard glob patterns. Or just filenames.
### minimatchOptions
Type: `Object`
Default: `{}`
Options to be passed to [minimatch](https://github.com/isaacs/minimatch).
Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here.
## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
## Release History
2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform.
2012-11-15 - v0.1.1 - Now works without an options object.
2012-11-01 - v0.1.0 - Initial release.
+1
View File
@@ -0,0 +1 @@
../lodash/build.js
@@ -0,0 +1,22 @@
Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js 1.4.3, copyright 2009-2013 Jeremy Ashkenas,
DocumentCloud Inc. <http://underscorejs.org/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,276 @@
# Lo-Dash <sup>v1.0.1</sup>
[![build status](https://secure.travis-ci.org/bestiejs/lodash.png)](http://travis-ci.org/bestiejs/lodash)
An alternative to Underscore.js, delivering consistency, [customization](https://github.com/bestiejs/lodash#custom-builds), [performance](http://lodash.com/benchmarks), and [extra features](https://github.com/bestiejs/lodash#features).
## Download
* Lo-Dash builds (for modern environments):<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.min.js)
* Lo-Dash compatibility builds (for legacy and modern environments):<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.compat.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.compat.min.js)
* Underscore compatibility builds:<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.underscore.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.1/dist/lodash.underscore.min.js)
* CDN copies of ≤ v1.0.1s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
[Lo-Dash dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.js),
[Lo-Dash prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.min.js),<br>
[Lo-Dash compat-dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.compat.js),
[Lo-Dash compat-prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.compat.min.js),<br>
[Underscore compat-dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.underscore.js), and
[Underscore compat-prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.underscore.min.js)
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
## Dive in
Weve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
## Resources
For more information check out these articles, screencasts, and other videos over Lo-Dash:
* Posts
- [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
* Videos
- [Introducing Lo-Dash](https://vimeo.com/44154599)
- [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
- [Lo-Dashs origin and why its a better utility belt](https://vimeo.com/44154600)
- [Unit testing in Lo-Dash](https://vimeo.com/45865290)
- [Lo-Dashs approach to native method use](https://vimeo.com/48576012)
- [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk)
## Features
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
* [_(…)](http://lodash.com/docs#_) supports intuitive chaining
* [_.at](http://lodash.com/docs#at) for cherry-picking collection values
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
* [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays and objects
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an objects own and inherited properties
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an objects own properties
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
* [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend)
* [_.partial](http://lodash.com/docs#partial) and [_.partialRight](http://lodash.com/docs#partialRight) for partial application without `this` binding
* [_.template](http://lodash.com/docs#template) supports [*“imports”* options](http://lodash.com/docs#templateSettings_imports), [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6), and [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
* [_.where](http://lodash.com/docs#where) supports deep object comparisons
* [_.clone](http://lodash.com/docs#clone), [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick),
[and more…](http://lodash.com/docs "_.assign, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept `callback` and `thisArg` arguments
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
[and more…](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
* [_.filter](http://lodash.com/docs#filter), [_.find](http://lodash.com/docs#find), [_.map](http://lodash.com/docs#map),
[and more…](http://lodash.com/docs "_.countBy, _.every, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* and *“_.where”* `callback` shorthands
## Support
Lo-Dash has been tested in at least Chrome 5~24, Firefox 1~18, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.20, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
## Custom builds
Custom builds make it easy to create lightweight versions of Lo-Dash containing only the methods you need.
To top it off, we handle all method dependency and alias mapping for you.
* Backbone builds, with only methods required by Backbone, may be created using the `backbone` modifier argument.
```bash
lodash backbone
```
* CSP builds, supporting default [Content Security Policy](https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html) restrictions, may be created using the `csp` modifier argument.
The `csp` modifier is an alais of the `mobile` modifier. Lo-Dash may be used in Chrome extensions by using either the `csp`, `mobile`, or `underscore` build and using precompiled templates, or loading Lo-Dash in a [sandbox](http://developer.chrome.com/stable/extensions/sandboxingEval.html).
```bash
lodash csp
```
* Legacy builds, tailored for older environments without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
```bash
lodash legacy
```
* Modern builds, tailored for newer environments with ES5 support, may be created using the `modern` modifier argument.
```bash
lodash modern
```
* Mobile builds, without method compilation and most bug fixes for old browsers, may be created using the `mobile` modifier argument.
```bash
lodash mobile
```
* Strict builds, with `_.bindAll`, `_.defaults`, and `_.extend` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
```bash
lodash strict
```
* Underscore builds, tailored for projects already using Underscore, may be created using the `underscore` modifier argument.
```bash
lodash underscore
```
Custom builds may be created using the following commands:
* Use the `category` argument to pass comma separated categories of methods to include in the build.<br>
Valid categories (case-insensitive) are *“arrays”*, *“chaining”*, *“collections”*, *“functions”*, *“objects”*, and *“utilities”*.
```bash
lodash category=collections,functions
lodash category="collections, functions"
```
* Use the `exports` argument to pass comma separated names of ways to export the `LoDash` function.<br>
Valid exports are *“amd”*, *“commonjs”*, *“global”*, *“node”*, and *“none”*.
```bash
lodash exports=amd,commonjs,node
lodash exports="amd, commonjs, node"
```
* Use the `iife` argument to specify code to replace the immediately-invoked function expression that wraps Lo-Dash.
```bash
lodash iife="!function(window,undefined){%output%}(this)"
```
* Use the `include` argument to pass comma separated method/category names to include in the build.
```bash
lodash include=each,filter,map
lodash include="each, filter, map"
```
* Use the `minus` argument to pass comma separated method/category names to remove from those included in the build.
```bash
lodash underscore minus=result,shuffle
lodash underscore minus="result, shuffle"
```
* Use the `plus` argument to pass comma separated method/category names to add to those included in the build.
```bash
lodash backbone plus=random,template
lodash backbone plus="random, template"
```
* Use the `template` argument to pass the file path pattern used to match template files to precompile.
```bash
lodash template="./*.jst"
```
* Use the `settings` argument to pass the template settings used when precompiling templates.
```bash
lodash settings="{interpolate:/\{\{([\s\S]+?)\}\}/g}"
```
* Use the `moduleId` argument to specify the AMD module ID of Lo-Dash, which defaults to “lodash”, used by precompiled templates.
```bash
lodash moduleId="underscore"
```
All arguments, except `legacy` with `csp`, `mobile`, `modern`, or `underscore`, may be combined.<br>
Unless specified by `-o` or `--output`, all files created are saved to the current working directory.
The following options are also supported:
* `-c`, `--stdout` ......... Write output to standard output
* `-d`, `--debug` ........... Write only the non-minified development output
* `-h`, `--help` ............. Display help information
* `-m`, `--minify` ......... Write only the minified production output
* `-o`, `--output` ......... Write output to a given path/filename
* `-p`, `--source-map` .. Generate a source map for the minified output, using an optional source map URL
* `-s`, `--silent` ......... Skip status updates normally logged to the console
* `-V`, `--version` ....... Output current version of Lo-Dash
The `lodash` command-line utility is available when Lo-Dash is installed as a global package (i.e. `npm install -g lodash`).
## Installation and usage
In browsers:
```html
<script src="lodash.js"></script>
```
Using [`npm`](http://npmjs.org/):
```bash
npm install lodash
npm install -g lodash
npm link lodash
```
To avoid potential issues, update `npm` before installing Lo-Dash:
```bash
npm install npm -g
```
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
```js
var _ = require('lodash');
// or as a drop-in replacement for Underscore
var _ = require('lodash/lodash.underscore');
```
**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your projects root directory before requiring it.
In [RingoJS v0.7.0-](http://ringojs.org/):
```js
var _ = require('lodash')._;
```
In [Rhino](http://www.mozilla.org/rhino/):
```js
load('lodash.js');
```
In an AMD loader like [RequireJS](http://requirejs.org/):
```js
require({
'paths': {
'underscore': 'path/to/lodash'
}
},
['underscore'], function(_) {
console.log(_.VERSION);
});
```
## Release Notes
### <sup>v1.0.1</sup>
* Add support for specifying source map URLs in `-p`/`--source-map` build options
* Ensured the second argument passed to `_.assign` is not treated as a `callback`
* Ensured `-p`/`--source-map` build options correctly set the `sourceMappingURL`
* Made `-p`/`--source-map` build options set source map *“sources”* keys based on the builds performed
* Made `_.defer` use `setImmediate`, in Node.js, when available
* Made `_.where` search arrays for values regardless of their index position
* Removed dead code from `_.template`
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
## BestieJS
Lo-Dash is part of the BestieJS *“Best in Class”* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
## Contributors
* [Kit Cambridge](http://kitcambridge.github.com/)
[![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter")
* [Mathias Bynens](http://mathiasbynens.be/)
[![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter")
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
<ul>
<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>
</ul>
@@ -0,0 +1 @@
<% print("Hello " + epithet); %>.
@@ -0,0 +1 @@
Hello ${ name }!
@@ -0,0 +1 @@
Hello {{ name }}!
@@ -0,0 +1,20 @@
Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
# QUnit CLIB <sup>v1.2.0</sup>
## command-line interface boilerplate
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
## Screenshot
![QUnit CLIB brings QUnit to your favorite shell.](http://i.imgur.com/jpu9l.png)
## Support
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.19, Narwhal v0.3.2, PhantomJS 1.8.1, RingoJS v0.9, and Rhino v1.7RC5.
## Usage
```js
(function(window) {
// use a single "load" function
var load = typeof require == 'function' ? require : window.load;
// load QUnit and CLIB if needed
var QUnit =
window.QUnit || (
window.addEventListener || (window.addEventListener = Function.prototype),
window.setTimeout || (window.setTimeout = Function.prototype),
window.QUnit = load('path/to/qunit.js') || window.QUnit,
load('path/to/qunit-clib.js'),
window.addEventListener === Function.prototype && delete window.addEventListener,
window.QUnit
);
// explicitly call `QUnit.module()` instead of `module()`
// in case we are in a CLI environment
QUnit.module('A Test Module');
test('A Test', function() {
// ...
});
// must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any
// version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS
if (!window.document) {
QUnit.start();
}
}(typeof global == 'object' && global || this));
```
## Footnotes
1. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0
2. Rhino v1.7RC4 does not support timeout fallbacks `clearTimeout` and `setTimeout`
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
@@ -0,0 +1,62 @@
[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
================================
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
project to test its code and plugins but is capable of testing any generic
JavaScript code (and even capable of testing JavaScript code on the server-side).
QUnit is especially useful for regression testing: Whenever a bug is reported,
write a test that asserts the existence of that particular bug. Then fix it and
commit both. Every time you work on the code again, run the tests. If the bug
comes up again - a regression - you'll spot it immediately and know how to fix
it, because you know what code you just changed.
Having good unit test coverage makes safe refactoring easy and cheap. You can
run the tests after each small refactoring step and always know what change
broke something.
QUnit is similar to other unit testing frameworks like JUnit, but makes use of
the features JavaScript provides and helps with testing code in the browser, e.g.
with its stop/start facilities for testing asynchronous code.
If you are interested in helping developing QUnit, you are in the right place.
For related discussions, visit the
[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing).
Development
-----------
To submit patches, fork the repository, create a branch for the change. Then implement
the change, run `grunt` to lint and test it, then commit, push and create a pull request.
Include some background for the change in the commit message and `Fixes #nnn`, referring
to the issue number you're addressing.
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
grunt binary. For additional grunt tasks, also run `npm install`.
Releases
--------
Install git-extras and run `git changelog` to update History.md.
Update qunit/qunit.js|css and package.json to the release version, commit and
tag, update them again to the next version, commit and push commits and tags
(`git push --tags origin master`).
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
or whitespace cleanups.
To upload to code.jquery.com (replace $version accordingly), ssh to code.origin.jquery.com:
cp qunit/qunit.js /var/www/html/code.jquery.com/qunit/qunit-$version.js
cp qunit/qunit.css /var/www/html/code.jquery.com/qunit/qunit-$version.css
Then update /var/www/html/code.jquery.com/index.html and purge it with:
curl -s http://code.origin.jquery.com/?reload
Update web-base-template to link to those files for qunitjs.com.
Publish to npm via
npm publish
@@ -0,0 +1,50 @@
# node-tar
Tar for Node.js.
## Goals of this project
1. Be able to parse and reasonably extract the contents of any tar file
created by any program that creates tar files, period.
At least, this includes every version of:
* bsdtar
* gnutar
* solaris posix tar
* Joerg Schilling's star ("Schilly tar")
2. Create tar files that can be extracted by any of the following tar
programs:
* bsdtar/libarchive version 2.6.2
* gnutar 1.15 and above
* SunOS Posix tar
* Joerg Schilling's star ("Schilly tar")
3. 100% test coverage. Speed is important. Correctness is slightly
more important.
4. Create the kind of tar interface that Node users would want to use.
5. Satisfy npm's needs for a portable tar implementation with a
JavaScript interface.
6. No excuses. No complaining. No tolerance for failure.
## But isn't there already a tar.js?
Yes, there are a few. This one is going to be better, and it will be
fanatically maintained, because npm will depend on it.
That's why I need to write it from scratch. Creating and extracting
tarballs is such a large part of what npm does, I simply can't have it
be a black box any longer.
## Didn't you have something already? Where'd it go?
It's in the "old" folder. It's not functional. Don't use it.
It was a useful exploration to learn the issues involved, but like most
software of any reasonable complexity, node-tar won't be useful until
it's been written at least 3 times.
@@ -0,0 +1,25 @@
Copyright (c) Isaac Z. Schlueter
All rights reserved.
The BSD License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,14 @@
# block-stream
A stream of blocks.
Write data into it, and it'll output data in buffer blocks the size you
specify, padding with zeroes if necessary.
```javascript
var block = new BlockStream(512)
fs.createReadStream("some-file").pipe(block)
block.pipe(fs.createWriteStream("block-file"))
```
When `.end()` or `.flush()` is called, it'll pad the block with zeroes.
@@ -0,0 +1,25 @@
Copyright (c) Isaac Z. Schlueter
All rights reserved.
The BSD License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,76 @@
Like FS streams, but with stat on them, and supporting directories and
symbolic links, as well as normal files. Also, you can use this to set
the stats on a file, even if you don't change its contents, or to create
a symlink, etc.
So, for example, you can "write" a directory, and it'll call `mkdir`. You
can specify a uid and gid, and it'll call `chown`. You can specify a
`mtime` and `atime`, and it'll call `utimes`. You can call it a symlink
and provide a `linkpath` and it'll call `symlink`.
Note that it won't automatically resolve symbolic links. So, if you
call `fstream.Reader('/some/symlink')` then you'll get an object
that stats and then ends immediately (since it has no data). To follow
symbolic links, do this: `fstream.Reader({path:'/some/symlink', follow:
true })`.
There are various checks to make sure that the bytes emitted are the
same as the intended size, if the size is set.
## Examples
```javascript
fstream
.Writer({ path: "path/to/file"
, mode: 0755
, size: 6
})
.write("hello\n")
.end()
```
This will create the directories if they're missing, and then write
`hello\n` into the file, chmod it to 0755, and assert that 6 bytes have
been written when it's done.
```javascript
fstream
.Writer({ path: "path/to/file"
, mode: 0755
, size: 6
, flags: "a"
})
.write("hello\n")
.end()
```
You can pass flags in, if you want to append to a file.
```javascript
fstream
.Writer({ path: "path/to/symlink"
, linkpath: "./file"
, SymbolicLink: true
, mode: "0755" // octal strings supported
})
.end()
```
If isSymbolicLink is a function, it'll be called, and if it returns
true, then it'll treat it as a symlink. If it's not a function, then
any truish value will make a symlink, or you can set `type:
'SymbolicLink'`, which does the same thing.
Note that the linkpath is relative to the symbolic link location, not
the parent dir or cwd.
```javascript
fstream
.Reader("path/to/dir")
.pipe(fstream.Writer("path/to/other/dir"))
```
This will do like `cp -Rp path/to/dir path/to/other/dir`. If the other
dir exists and isn't a directory, then it'll emit an error. It'll also
set the uid, gid, mode, etc. to be identical. In this way, it's more
like `rsync -a` than simply a copy.
@@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
Just like node's `fs` module, but it does an incremental back-off when
EMFILE is encountered.
Useful in asynchronous situations where one needs to try to open lots
and lots of files.
@@ -0,0 +1,51 @@
A dead simple way to do inheritance in JS.
var inherits = require("inherits")
function Animal () {
this.alive = true
}
Animal.prototype.say = function (what) {
console.log(what)
}
inherits(Dog, Animal)
function Dog () {
Dog.super.apply(this)
}
Dog.prototype.sniff = function () {
this.say("sniff sniff")
}
Dog.prototype.bark = function () {
this.say("woof woof")
}
inherits(Chihuahua, Dog)
function Chihuahua () {
Chihuahua.super.apply(this)
}
Chihuahua.prototype.bark = function () {
this.say("yip yip")
}
// also works
function Cat () {
Cat.super.apply(this)
}
Cat.prototype.hiss = function () {
this.say("CHSKKSS!!")
}
inherits(Cat, Animal, {
meow: function () { this.say("miao miao") }
})
Cat.prototype.purr = function () {
this.say("purr purr")
}
var c = new Chihuahua
assert(c instanceof Chihuahua)
assert(c instanceof Dog)
assert(c instanceof Animal)
The actual function is laughably small. 10-lines small.
@@ -0,0 +1,21 @@
Copyright 2010 James Halliday (mail@substack.net)
This project is free software released under the MIT/X11 license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,61 @@
mkdirp
======
Like `mkdir -p`, but in node.js!
[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)
example
=======
pow.js
------
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', function (err) {
if (err) console.error(err)
else console.log('pow!')
});
Output
pow!
And now /tmp/foo/bar/baz exists, huzzah!
methods
=======
var mkdirp = require('mkdirp');
mkdirp(dir, mode, cb)
---------------------
Create a new directory and any necessary subdirectories at `dir` with octal
permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
`cb(err, made)` fires with the error or the first directory `made`
that had to be created, if any.
mkdirp.sync(dir, mode)
----------------------
Synchronously create a new directory and any necessary subdirectories at `dir`
with octal permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
Returns the first directory that had to be created, if any.
install
=======
With [npm](http://npmjs.org) do:
npm install mkdirp
license
=======
MIT/X11
@@ -0,0 +1,6 @@
# Authors sorted by whether or not they're me.
Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)
Wayne Larsen <wayne@larsen.st> (http://github.com/wvl)
ritch <skawful@gmail.com>
Marcel Laverdet
Yosef Dinerstein <yosefd@microsoft.com>
@@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,21 @@
A `rm -rf` for node.
Install with `npm install rimraf`, or just drop rimraf.js somewhere.
## API
`rimraf(f, callback)`
The callback will be called with an error if there is one. Certain
errors are handled for you:
* `EBUSY` - rimraf will back off a maximum of opts.maxBusyTries times
before giving up.
* `EMFILE` - If too many file descriptors get opened, rimraf will
patiently wait until more become available.
## rimraf.sync
It can remove stuff synchronously, too. But that's not so good. Use
the async API. It's better.
@@ -0,0 +1,22 @@
Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
__
/\ \ __
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
\ \____/
\/___/
Underscore.js is a utility-belt library for JavaScript that provides
support for the usual functional suspects (each, map, reduce, filter...)
without extending any core JavaScript objects.
For Docs, License, Tests, and pre-packed downloads, see:
http://underscorejs.org
Many thanks to our contributors:
https://github.com/documentcloud/underscore/contributors

Some files were not shown because too many files have changed in this diff Show More