mirror of
https://github.com/Hopiu/postal.js.git
synced 2026-03-16 22:20:23 +00:00
Reformatted code to more closely (but not exactly) line up with jQuery core formatting standards. Updated postal.socket dependencies in the node example, etc.
This commit is contained in:
parent
e25d9196ec
commit
951738d56b
715 changed files with 144577 additions and 120084 deletions
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"source": "src/diags",
|
||||
"output": "lib/standard",
|
||||
"lint": {},
|
||||
"uglify": {},
|
||||
"extensions": { "uglify": "min" }
|
||||
"source" : "src/diags",
|
||||
"output" : "lib/standard",
|
||||
"lint" : {},
|
||||
"uglify" : {},
|
||||
"extensions" : {
|
||||
"uglify" : "min"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
"source": "src/main",
|
||||
"output": "lib/standard",
|
||||
"lint": {},
|
||||
"uglify": {},
|
||||
"extensions": { "uglify": "min" },
|
||||
"hosts": {
|
||||
"source" : "src/main",
|
||||
"output" : "lib/standard",
|
||||
"lint" : {},
|
||||
"uglify" : {},
|
||||
"extensions" : {
|
||||
"uglify" : "min"
|
||||
},
|
||||
"hosts" : {
|
||||
"/" : "./"
|
||||
},
|
||||
"port" : 8080
|
||||
|
|
|
|||
|
|
@ -1,50 +1,50 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Postal Examples (AMD/require.js Lib Format)</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script data-main="js/main" src="js/libs/require/require.js"></script>
|
||||
<title>Postal Examples (AMD/require.js Lib Format)</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script data-main="js/main" src="js/libs/require/require.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
Example 1 - The World's Simplest Subscription
|
||||
<div class="results" id="example1"></div>
|
||||
</div>
|
||||
<div>
|
||||
Example 1 - The World's Simplest Subscription
|
||||
<div class="results" id="example1"></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 2 - Subscribing with the "#" wildcard character
|
||||
<ul class="results" id="example2"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 2 - Subscribing with the "#" wildcard character
|
||||
<ul class="results" id="example2"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 3 - Subscribing with the "*" wildcard character
|
||||
<ul class="results" id="example3"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 3 - Subscribing with the "*" wildcard character
|
||||
<ul class="results" id="example3"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 4 - using ignoreDuplicates()
|
||||
<ul class="results" id="example4"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 4 - using ignoreDuplicates()
|
||||
<ul class="results" id="example4"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 5 - using disposeAfter(X)
|
||||
<ul class="results" id="example5"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 5 - using disposeAfter(X)
|
||||
<ul class="results" id="example5"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 6 - using withConstraint() to apply a predicate to subscription callback
|
||||
<ul class="results" id="example6"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 6 - using withConstraint() to apply a predicate to subscription callback
|
||||
<ul class="results" id="example6"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 7 - using withContext to set the "this" context
|
||||
<ul class="results" id="example7"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 7 - using withContext to set the "this" context
|
||||
<ul class="results" id="example7"></ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Example 8 - using withDelay to delay evaluation of subscription
|
||||
<ul class="results" id="example8"></ul>
|
||||
</div>
|
||||
<div>
|
||||
Example 8 - using withDelay to delay evaluation of subscription
|
||||
<ul class="results" id="example8"></ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
define(['postal', 'postaldiags'], function(postal, diags){
|
||||
define( ['postal', 'postaldiags'], function ( postal, diags ) {
|
||||
|
||||
// The world's simplest subscription
|
||||
var channel = postal.channel("Name.Changed");
|
||||
var channel = postal.channel( "Name.Changed" );
|
||||
// subscribe
|
||||
var subscription = channel.subscribe(function(data) { $("#example1").html("Name: " + data.name); });
|
||||
var subscription = channel.subscribe( function ( data ) {
|
||||
$( "#example1" ).html( "Name: " + data.name );
|
||||
} );
|
||||
// And someone publishes a first name change:
|
||||
channel.publish({ name: "Dr. Who" });
|
||||
channel.publish( { name : "Dr. Who" } );
|
||||
subscription.unsubscribe();
|
||||
|
||||
|
||||
|
|
@ -13,14 +15,14 @@ define(['postal', 'postaldiags'], function(postal, diags){
|
|||
// The # symbol represents "one word" in a topic (i.e - the text between two periods of a topic).
|
||||
// By subscribing to "#.Changed", the binding will match
|
||||
// Name.Changed & Location.Changed but *not* for Changed.Companion
|
||||
var hashChannel = postal.channel("#.Changed"),
|
||||
chgSubscription = hashChannel.subscribe(function(data) {
|
||||
$('<li>' + data.type + " Changed: " + data.value + '</li>').appendTo("#example2");
|
||||
});
|
||||
postal.channel("Name.Changed")
|
||||
.publish({ type: "Name", value:"John Smith" });
|
||||
postal.channel("Location.Changed")
|
||||
.publish({ type: "Location", value: "Early 20th Century England" });
|
||||
var hashChannel = postal.channel( "#.Changed" ),
|
||||
chgSubscription = hashChannel.subscribe( function ( data ) {
|
||||
$( '<li>' + data.type + " Changed: " + data.value + '</li>' ).appendTo( "#example2" );
|
||||
} );
|
||||
postal.channel( "Name.Changed" )
|
||||
.publish( { type : "Name", value : "John Smith" } );
|
||||
postal.channel( "Location.Changed" )
|
||||
.publish( { type : "Location", value : "Early 20th Century England" } );
|
||||
chgSubscription.unsubscribe();
|
||||
|
||||
|
||||
|
|
@ -28,94 +30,101 @@ define(['postal', 'postaldiags'], function(postal, diags){
|
|||
// The * symbol represents any number of characters/words in a topic string.
|
||||
// By subscribing to "DrWho.*.Changed", the binding will match
|
||||
// DrWho.NinthDoctor.Companion.Changed & DrWho.Location.Changed but *not* Changed
|
||||
var starChannel = postal.channel("DrWho.*.Changed"),
|
||||
starSubscription = starChannel.subscribe(function(data) {
|
||||
$('<li>' + data.type + " Changed: " + data.value + '</li>').appendTo("#example3");
|
||||
});
|
||||
postal.channel("DrWho.NinthDoctor.Companion.Changed")
|
||||
.publish({ type: "Companion Name", value:"Rose" });
|
||||
postal.channel("DrWho.TenthDoctor.Companion.Changed")
|
||||
.publish({ type: "Companion Name", value:"Martha" });
|
||||
postal.channel("DrWho.Eleventh.Companion.Changed")
|
||||
.publish({ type: "Companion Name", value:"Amy" });
|
||||
postal.channel("DrWho.Location.Changed")
|
||||
.publish({ type: "Location", value: "The Library" });
|
||||
postal.channel("TheMaster.DrumBeat.Changed")
|
||||
.publish({ type: "DrumBeat", value: "This won't trigger any subscriptions" });
|
||||
postal.channel("Changed")
|
||||
.publish({ type: "Useless", value: "This won't trigger any subscriptions either" });
|
||||
var starChannel = postal.channel( "DrWho.*.Changed" ),
|
||||
starSubscription = starChannel.subscribe( function ( data ) {
|
||||
$( '<li>' + data.type + " Changed: " + data.value + '</li>' ).appendTo( "#example3" );
|
||||
} );
|
||||
postal.channel( "DrWho.NinthDoctor.Companion.Changed" )
|
||||
.publish( { type : "Companion Name", value : "Rose" } );
|
||||
postal.channel( "DrWho.TenthDoctor.Companion.Changed" )
|
||||
.publish( { type : "Companion Name", value : "Martha" } );
|
||||
postal.channel( "DrWho.Eleventh.Companion.Changed" )
|
||||
.publish( { type : "Companion Name", value : "Amy" } );
|
||||
postal.channel( "DrWho.Location.Changed" )
|
||||
.publish( { type : "Location", value : "The Library" } );
|
||||
postal.channel( "TheMaster.DrumBeat.Changed" )
|
||||
.publish( { type : "DrumBeat", value : "This won't trigger any subscriptions" } );
|
||||
postal.channel( "Changed" )
|
||||
.publish( { type : "Useless", value : "This won't trigger any subscriptions either" } );
|
||||
starSubscription.unsubscribe();
|
||||
|
||||
// Applying ignoreDuplicates to a subscription
|
||||
var dupChannel = postal.channel("WeepingAngel.*"),
|
||||
dupSubscription = dupChannel.subscribe(function(data) {
|
||||
$('<li>' + data.value + '</li>').appendTo("#example4");
|
||||
}).ignoreDuplicates();
|
||||
postal.channel("WeepingAngel.DontBlink")
|
||||
.publish({ value:"Don't Blink" });
|
||||
postal.channel("WeepingAngel.DontBlink")
|
||||
.publish({ value:"Don't Blink" });
|
||||
postal.channel("WeepingAngel.DontEvenBlink")
|
||||
.publish({ value:"Don't Even Blink" });
|
||||
postal.channel("WeepingAngel.DontBlink")
|
||||
.publish({ value:"Don't Close Your Eyes" });
|
||||
var dupChannel = postal.channel( "WeepingAngel.*" ),
|
||||
dupSubscription = dupChannel.subscribe(
|
||||
function ( data ) {
|
||||
$( '<li>' + data.value + '</li>' ).appendTo( "#example4" );
|
||||
} ).ignoreDuplicates();
|
||||
postal.channel( "WeepingAngel.DontBlink" )
|
||||
.publish( { value : "Don't Blink" } );
|
||||
postal.channel( "WeepingAngel.DontBlink" )
|
||||
.publish( { value : "Don't Blink" } );
|
||||
postal.channel( "WeepingAngel.DontEvenBlink" )
|
||||
.publish( { value : "Don't Even Blink" } );
|
||||
postal.channel( "WeepingAngel.DontBlink" )
|
||||
.publish( { value : "Don't Close Your Eyes" } );
|
||||
dupSubscription.unsubscribe();
|
||||
|
||||
// Using disposeAfter(X) to remove subscription automagically after X number of receives
|
||||
var daChannel = postal.channel("Donna.Noble.*"),
|
||||
daSubscription = daChannel.subscribe(function(data) {
|
||||
$('<li>' + data.value + '</li>').appendTo("#example5");
|
||||
}).disposeAfter(2);
|
||||
postal.channel("Donna.Noble.ScreamingAgain")
|
||||
.publish({ value:"Donna Noble has left the library." });
|
||||
postal.channel("Donna.Noble.ScreamingAgain")
|
||||
.publish({ value:"Donna Noble has left the library." });
|
||||
postal.channel("Donna.Noble.ScreamingAgain")
|
||||
.publish({ value:"Donna Noble has left the library." });
|
||||
postal.channel("Donna.Noble.ScreamingAgain")
|
||||
.publish({ value:"Donna Noble has left the library." });
|
||||
postal.channel("Donna.Noble.ScreamingAgain")
|
||||
.publish({ value:"Donna Noble has left the library." });
|
||||
var daChannel = postal.channel( "Donna.Noble.*" ),
|
||||
daSubscription = daChannel.subscribe(
|
||||
function ( data ) {
|
||||
$( '<li>' + data.value + '</li>' ).appendTo( "#example5" );
|
||||
} ).disposeAfter( 2 );
|
||||
postal.channel( "Donna.Noble.ScreamingAgain" )
|
||||
.publish( { value : "Donna Noble has left the library." } );
|
||||
postal.channel( "Donna.Noble.ScreamingAgain" )
|
||||
.publish( { value : "Donna Noble has left the library." } );
|
||||
postal.channel( "Donna.Noble.ScreamingAgain" )
|
||||
.publish( { value : "Donna Noble has left the library." } );
|
||||
postal.channel( "Donna.Noble.ScreamingAgain" )
|
||||
.publish( { value : "Donna Noble has left the library." } );
|
||||
postal.channel( "Donna.Noble.ScreamingAgain" )
|
||||
.publish( { value : "Donna Noble has left the library." } );
|
||||
daSubscription.unsubscribe();
|
||||
|
||||
// Using withConstraint to apply a predicate to the subscription
|
||||
var drIsInTheTardis = false,
|
||||
wcChannel = postal.channel("Tardis.Depart"),
|
||||
wcSubscription = wcChannel.subscribe(function(data) {
|
||||
$('<li>' + data.value + '</li>').appendTo("#example6");
|
||||
}).withConstraint(function() { return drIsInTheTardis; } );
|
||||
postal.channel("Tardis.Depart")
|
||||
.publish({ value:"Time for time travel....fantastic!" });
|
||||
postal.channel("Tardis.Depart")
|
||||
.publish({ value:"Time for time travel....fantastic!" });
|
||||
wcChannel = postal.channel( "Tardis.Depart" ),
|
||||
wcSubscription = wcChannel.subscribe(
|
||||
function ( data ) {
|
||||
$( '<li>' + data.value + '</li>' ).appendTo( "#example6" );
|
||||
} ).withConstraint( function () {
|
||||
return drIsInTheTardis;
|
||||
} );
|
||||
postal.channel( "Tardis.Depart" )
|
||||
.publish( { value : "Time for time travel....fantastic!" } );
|
||||
postal.channel( "Tardis.Depart" )
|
||||
.publish( { value : "Time for time travel....fantastic!" } );
|
||||
drIsInTheTardis = true;
|
||||
postal.channel("Tardis.Depart")
|
||||
.publish({ value:"Time for time travel....fantastic!" });
|
||||
postal.channel( "Tardis.Depart" )
|
||||
.publish( { value : "Time for time travel....fantastic!" } );
|
||||
wcSubscription.unsubscribe();
|
||||
|
||||
// Using withContext to set the "this" context
|
||||
var ctxChannel = postal.channel("Dalek.Meet.CyberMen"),
|
||||
ctxSubscription = ctxChannel.subscribe(function(data) {
|
||||
$('<li>' + data.value + '</li>').appendTo(this);
|
||||
}).withContext($("#example7"));
|
||||
postal.channel("Dalek.Meet.CyberMen")
|
||||
.publish({ value:"Exterminate!" });
|
||||
postal.channel("Dalek.Meet.CyberMen")
|
||||
.publish({ value:"Delete!" });
|
||||
var ctxChannel = postal.channel( "Dalek.Meet.CyberMen" ),
|
||||
ctxSubscription = ctxChannel.subscribe(
|
||||
function ( data ) {
|
||||
$( '<li>' + data.value + '</li>' ).appendTo( this );
|
||||
} ).withContext( $( "#example7" ) );
|
||||
postal.channel( "Dalek.Meet.CyberMen" )
|
||||
.publish( { value : "Exterminate!" } );
|
||||
postal.channel( "Dalek.Meet.CyberMen" )
|
||||
.publish( { value : "Delete!" } );
|
||||
ctxSubscription.unsubscribe();
|
||||
|
||||
// Using withDelay() to delay the subscription evaluation
|
||||
var wdChannel = postal.channel("He.Will.Knock.Four.Times"),
|
||||
wdSubscription = wdChannel.subscribe(function(data) {
|
||||
$('<li>' + data.value + '</li>').appendTo($("#example8"));
|
||||
}).withDelay(5000);
|
||||
postal.channel("He.Will.Knock.Four.Times")
|
||||
.publish({ value:"Knock!" });
|
||||
postal.channel("He.Will.Knock.Four.Times")
|
||||
.publish({ value:"Knock!" });
|
||||
postal.channel("He.Will.Knock.Four.Times")
|
||||
.publish({ value:"Knock!" });
|
||||
postal.channel("He.Will.Knock.Four.Times")
|
||||
.publish({ value:"Knock!" });
|
||||
var wdChannel = postal.channel( "He.Will.Knock.Four.Times" ),
|
||||
wdSubscription = wdChannel.subscribe(
|
||||
function ( data ) {
|
||||
$( '<li>' + data.value + '</li>' ).appendTo( $( "#example8" ) );
|
||||
} ).withDelay( 5000 );
|
||||
postal.channel( "He.Will.Knock.Four.Times" )
|
||||
.publish( { value : "Knock!" } );
|
||||
postal.channel( "He.Will.Knock.Four.Times" )
|
||||
.publish( { value : "Knock!" } );
|
||||
postal.channel( "He.Will.Knock.Four.Times" )
|
||||
.publish( { value : "Knock!" } );
|
||||
postal.channel( "He.Will.Knock.Four.Times" )
|
||||
.publish( { value : "Knock!" } );
|
||||
wdSubscription.unsubscribe();
|
||||
});
|
||||
} );
|
||||
3322
example/amd/js/libs/jquery/jquery-min.js
vendored
3322
example/amd/js/libs/jquery/jquery-min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -47,7 +47,9 @@ define( [ "postal", "underscore" ], function ( postal, _, undefined ) {
|
|||
}
|
||||
} );
|
||||
|
||||
postal.diagnostics = {
|
||||
postal.diagnostics = postal.diagnostics || {};
|
||||
|
||||
postal.diagnostics.console = {
|
||||
clearFilters : function () {
|
||||
filters = [];
|
||||
},
|
||||
|
|
@ -60,13 +62,13 @@ define( [ "postal", "underscore" ], function ( postal, _, undefined ) {
|
|||
if ( !_.isArray( constraint ) ) {
|
||||
constraint = [ constraint ];
|
||||
}
|
||||
_.each( constraint, function( item ){
|
||||
_.each( constraint, function ( item ) {
|
||||
if ( filters.length === 0 || !_.any( filters, function ( filter ) {
|
||||
return _.isEqual( filter, item );
|
||||
} ) ) {
|
||||
filters.push( item );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
},
|
||||
getCurrentFilters : function () {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
define(["postal","underscore"],function(a,b,c){var d=[],e=function(a,c){var d=0,f=0;return b.each(a,function(a,g){c[g]&&(f++,b.isObject(c[g])&&!b.isArray(c[g])?e(a,c[g])&&d++:b.isEqual(c[g],a)&&d++)}),d===f},f=a.addWireTap(function(a,c){if(!d.length||b.any(d,function(a){return e(a,c)})){if(!JSON)throw"This browser or environment does not provide JSON support";try{console.log(JSON.stringify(c))}catch(f){try{var g=b.extend({},c);delete g.data,console.log(JSON.stringify(g)+"\n "+"JSON.stringify Error: "+f.message)}catch(h){console.log("Unable to parse data to JSON: "+f)}}}});a.diagnostics={clearFilters:function(){d=[]},removeFilter:function(a){d=b.filter(d,function(c){return!b.isEqual(c,a)})},addFilter:function(a){b.isArray(a)||(a=[a]),b.each(a,function(a){(d.length===0||!b.any(d,function(c){return b.isEqual(c,a)}))&&d.push(a)})},getCurrentFilters:function(){return d},removeWireTap:function(){f&&f()}}})
|
||||
define(["postal","underscore"],function(a,b,c){var d=[],e=function(a,c){var d=0,f=0;return b.each(a,function(a,g){c[g]&&(f++,b.isObject(c[g])&&!b.isArray(c[g])?e(a,c[g])&&d++:b.isEqual(c[g],a)&&d++)}),d===f},f=a.addWireTap(function(a,c){if(!d.length||b.any(d,function(a){return e(a,c)})){if(!JSON)throw"This browser or environment does not provide JSON support";try{console.log(JSON.stringify(c))}catch(f){try{var g=b.extend({},c);delete g.data,console.log(JSON.stringify(g)+"\n "+"JSON.stringify Error: "+f.message)}catch(h){console.log("Unable to parse data to JSON: "+f)}}}});a.diagnostics=a.diagnostics||{},a.diagnostics.console={clearFilters:function(){d=[]},removeFilter:function(a){d=b.filter(d,function(c){return!b.isEqual(c,a)})},addFilter:function(a){b.isArray(a)||(a=[a]),b.each(a,function(a){(d.length===0||!b.any(d,function(c){return b.isEqual(c,a)}))&&d.push(a)})},getCurrentFilters:function(){return d},removeWireTap:function(){f&&f()}}})
|
||||
|
|
@ -1,225 +1,228 @@
|
|||
/*
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
*/
|
||||
|
||||
// This is the amd-module version of postal.js
|
||||
// If you need the standard lib style version, go to http://github.com/ifandelse/postal.js
|
||||
define(["underscore"], function(_, undefined) {
|
||||
define( ["underscore"], function ( _, undefined ) {
|
||||
|
||||
var DEFAULT_CHANNEL = "/",
|
||||
DEFAULT_PRIORITY = 50,
|
||||
DEFAULT_DISPOSEAFTER = 0,
|
||||
SYSTEM_CHANNEL = "postal",
|
||||
NO_OP = function() { };
|
||||
NO_OP = function () {
|
||||
};
|
||||
|
||||
var DistinctPredicate = function() {
|
||||
var DistinctPredicate = function () {
|
||||
var previous;
|
||||
return function(data) {
|
||||
return function ( data ) {
|
||||
var eq = false;
|
||||
if(_.isString(data)) {
|
||||
if ( _.isString( data ) ) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
eq = _.isEqual( data, previous );
|
||||
previous = _.clone( data );
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var ChannelDefinition = function(channelName, defaultTopic) {
|
||||
var ChannelDefinition = function ( channelName, defaultTopic ) {
|
||||
this.channel = channelName || DEFAULT_CHANNEL;
|
||||
this._topic = defaultTopic || "";
|
||||
};
|
||||
|
||||
ChannelDefinition.prototype = {
|
||||
subscribe: function() {
|
||||
subscribe : function () {
|
||||
var len = arguments.length;
|
||||
if(len === 1) {
|
||||
return new SubscriptionDefinition(this.channel, this._topic, arguments[0]);
|
||||
if ( len === 1 ) {
|
||||
return new SubscriptionDefinition( this.channel, this._topic, arguments[0] );
|
||||
}
|
||||
else if (len === 2) {
|
||||
return new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
|
||||
else if ( len === 2 ) {
|
||||
return new SubscriptionDefinition( this.channel, arguments[0], arguments[1] );
|
||||
}
|
||||
},
|
||||
|
||||
publish: function(obj) {
|
||||
publish : function ( obj ) {
|
||||
var envelope = {
|
||||
channel: this.channel,
|
||||
topic: this._topic,
|
||||
data: obj || {}
|
||||
channel : this.channel,
|
||||
topic : this._topic,
|
||||
data : obj || {}
|
||||
};
|
||||
// If this is an envelope....
|
||||
if( obj.topic && obj.data ) {
|
||||
if ( obj.topic && obj.data ) {
|
||||
envelope = obj;
|
||||
envelope.channel = envelope.channel || this.channel;
|
||||
}
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
|
||||
topic: function(topic) {
|
||||
if(topic === this._topic) {
|
||||
topic : function ( topic ) {
|
||||
if ( topic === this._topic ) {
|
||||
return this;
|
||||
}
|
||||
return new ChannelDefinition(this.channel, topic);
|
||||
return new ChannelDefinition( this.channel, topic );
|
||||
}
|
||||
};
|
||||
|
||||
var SubscriptionDefinition = function(channel, topic, callback) {
|
||||
var SubscriptionDefinition = function ( channel, topic, callback ) {
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.callback = callback;
|
||||
this.priority = DEFAULT_PRIORITY;
|
||||
this.constraints = new Array(0);
|
||||
this.constraints = new Array( 0 );
|
||||
this.maxCalls = DEFAULT_DISPOSEAFTER;
|
||||
this.onHandled = NO_OP;
|
||||
this.context = null;
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.created",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.created",
|
||||
channel: channel,
|
||||
topic: topic
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.created",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.created",
|
||||
channel : channel,
|
||||
topic : topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
postal.configuration.bus.subscribe(this);
|
||||
postal.configuration.bus.subscribe( this );
|
||||
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function() {
|
||||
postal.configuration.bus.unsubscribe(this);
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.removed",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.removed",
|
||||
channel: this.channel,
|
||||
topic: this.topic
|
||||
unsubscribe : function () {
|
||||
postal.configuration.bus.unsubscribe( this );
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.removed",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.removed",
|
||||
channel : this.channel,
|
||||
topic : this.topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
defer: function() {
|
||||
defer : function () {
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(fn,0,data);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( fn, 0, data );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
disposeAfter: function(maxCalls) {
|
||||
if(_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
disposeAfter : function ( maxCalls ) {
|
||||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
|
||||
var fn = this.onHandled;
|
||||
var dispose = _.after(maxCalls, _.bind(function() {
|
||||
this.unsubscribe(this);
|
||||
}, this));
|
||||
var dispose = _.after( maxCalls, _.bind( function () {
|
||||
this.unsubscribe( this );
|
||||
}, this ) );
|
||||
|
||||
this.onHandled = function() {
|
||||
fn.apply(this.context, arguments);
|
||||
this.onHandled = function () {
|
||||
fn.apply( this.context, arguments );
|
||||
dispose();
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
ignoreDuplicates: function() {
|
||||
this.withConstraint(new DistinctPredicate());
|
||||
ignoreDuplicates : function () {
|
||||
this.withConstraint( new DistinctPredicate() );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraint: function(predicate) {
|
||||
if(! _.isFunction(predicate)) {
|
||||
withConstraint : function ( predicate ) {
|
||||
if ( !_.isFunction( predicate ) ) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
this.constraints.push(predicate);
|
||||
this.constraints.push( predicate );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraints: function(predicates) {
|
||||
withConstraints : function ( predicates ) {
|
||||
var self = this;
|
||||
if(_.isArray(predicates)) {
|
||||
_.each(predicates, function(predicate) { self.withConstraint(predicate); } );
|
||||
if ( _.isArray( predicates ) ) {
|
||||
_.each( predicates, function ( predicate ) {
|
||||
self.withConstraint( predicate );
|
||||
} );
|
||||
}
|
||||
return self;
|
||||
},
|
||||
|
||||
withContext: function(context) {
|
||||
withContext : function ( context ) {
|
||||
this.context = context;
|
||||
return this;
|
||||
},
|
||||
|
||||
withDebounce: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDebounce : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.debounce(fn, milliseconds);
|
||||
this.callback = _.debounce( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
withDelay: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDelay : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(function(){
|
||||
fn(data);
|
||||
}, milliseconds);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( function () {
|
||||
fn( data );
|
||||
}, milliseconds );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
withPriority: function(priority) {
|
||||
if(_.isNaN(priority)) {
|
||||
withPriority : function ( priority ) {
|
||||
if ( _.isNaN( priority ) ) {
|
||||
throw "Priority must be a number";
|
||||
}
|
||||
this.priority = priority;
|
||||
return this;
|
||||
},
|
||||
|
||||
withThrottle: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withThrottle : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.throttle(fn, milliseconds);
|
||||
this.callback = _.throttle( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
subscribe: function(callback) {
|
||||
subscribe : function ( callback ) {
|
||||
this.callback = callback;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
var bindingsResolver = {
|
||||
cache: { },
|
||||
cache : { },
|
||||
|
||||
compare: function(binding, topic) {
|
||||
if(this.cache[topic] && this.cache[topic][binding]) {
|
||||
compare : function ( binding, topic ) {
|
||||
if ( this.cache[topic] && this.cache[topic][binding] ) {
|
||||
return true;
|
||||
}
|
||||
// binding.replace(/\./g,"\\.") // escape actual periods
|
||||
// .replace(/\*/g, ".*") // asterisks match any value
|
||||
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
|
||||
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
|
||||
result = rgx.test(topic);
|
||||
if(result) {
|
||||
if(!this.cache[topic]) {
|
||||
var rgx = new RegExp( "^" + binding.replace( /\./g, "\\." ).replace( /\*/g, ".*" ).replace( /#/g, "[A-Z,a-z,0-9]*" ) + "$" ),
|
||||
result = rgx.test( topic );
|
||||
if ( result ) {
|
||||
if ( !this.cache[topic] ) {
|
||||
this.cache[topic] = {};
|
||||
}
|
||||
this.cache[topic][binding] = true;
|
||||
|
|
@ -227,91 +230,93 @@ var bindingsResolver = {
|
|||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
this.cache = {};
|
||||
}
|
||||
};
|
||||
|
||||
var localBus = {
|
||||
|
||||
addWireTap: function(callback) {
|
||||
addWireTap : function ( callback ) {
|
||||
var self = this;
|
||||
self.wireTaps.push(callback);
|
||||
return function() {
|
||||
var idx = self.wireTaps.indexOf(callback);
|
||||
if(idx !== -1) {
|
||||
self.wireTaps.splice(idx,1);
|
||||
self.wireTaps.push( callback );
|
||||
return function () {
|
||||
var idx = self.wireTaps.indexOf( callback );
|
||||
if ( idx !== -1 ) {
|
||||
self.wireTaps.splice( idx, 1 );
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
publish: function(envelope) {
|
||||
_.each(this.wireTaps,function(tap) {
|
||||
tap(envelope.data, envelope);
|
||||
});
|
||||
publish : function ( envelope ) {
|
||||
_.each( this.wireTaps, function ( tap ) {
|
||||
tap( envelope.data, envelope );
|
||||
} );
|
||||
|
||||
_.each(this.subscriptions[envelope.channel], function(topic) {
|
||||
_.each(topic, function(subDef){
|
||||
if(postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
||||
if(_.all(subDef.constraints, function(constraint) { return constraint(envelope.data,envelope); })) {
|
||||
if(typeof subDef.callback === 'function') {
|
||||
subDef.callback.apply(subDef.context, [envelope.data, envelope]);
|
||||
_.each( this.subscriptions[envelope.channel], function ( topic ) {
|
||||
_.each( topic, function ( subDef ) {
|
||||
if ( postal.configuration.resolver.compare( subDef.topic, envelope.topic ) ) {
|
||||
if ( _.all( subDef.constraints, function ( constraint ) {
|
||||
return constraint( envelope.data, envelope );
|
||||
} ) ) {
|
||||
if ( typeof subDef.callback === 'function' ) {
|
||||
subDef.callback.apply( subDef.context, [envelope.data, envelope] );
|
||||
subDef.onHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if( this.subscriptions ) {
|
||||
_.each( this.subscriptions , function( channel ){
|
||||
_.each( channel, function( topic ){
|
||||
while( topic.length ) {
|
||||
reset : function () {
|
||||
if ( this.subscriptions ) {
|
||||
_.each( this.subscriptions, function ( channel ) {
|
||||
_.each( channel, function ( topic ) {
|
||||
while ( topic.length ) {
|
||||
topic.pop().unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
this.subscriptions = {};
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(subDef) {
|
||||
subscribe : function ( subDef ) {
|
||||
var idx, found, fn, channel = this.subscriptions[subDef.channel], subs;
|
||||
|
||||
if(!channel) {
|
||||
if ( !channel ) {
|
||||
channel = this.subscriptions[subDef.channel] = {};
|
||||
}
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
||||
if(!subs) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array(0);
|
||||
if ( !subs ) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array( 0 );
|
||||
}
|
||||
|
||||
idx = subs.length - 1;
|
||||
for(; idx >= 0; idx--) {
|
||||
if(subs[idx].priority <= subDef.priority) {
|
||||
subs.splice(idx + 1, 0, subDef);
|
||||
for ( ; idx >= 0; idx-- ) {
|
||||
if ( subs[idx].priority <= subDef.priority ) {
|
||||
subs.splice( idx + 1, 0, subDef );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
subs.unshift(subDef);
|
||||
if ( !found ) {
|
||||
subs.unshift( subDef );
|
||||
}
|
||||
return subDef;
|
||||
},
|
||||
|
||||
subscriptions: {},
|
||||
subscriptions : {},
|
||||
|
||||
wireTaps: new Array(0),
|
||||
wireTaps : new Array( 0 ),
|
||||
|
||||
unsubscribe: function(config) {
|
||||
if(this.subscriptions[config.channel][config.topic]) {
|
||||
unsubscribe : function ( config ) {
|
||||
if ( this.subscriptions[config.channel][config.topic] ) {
|
||||
var len = this.subscriptions[config.channel][config.topic].length,
|
||||
idx = 0;
|
||||
for ( ; idx < len; idx++ ) {
|
||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
||||
if ( this.subscriptions[config.channel][config.topic][idx] === config ) {
|
||||
this.subscriptions[config.channel][config.topic].splice( idx, 1 );
|
||||
break;
|
||||
}
|
||||
|
|
@ -321,50 +326,50 @@ var localBus = {
|
|||
};
|
||||
|
||||
var publishPicker = {
|
||||
"1" : function(envelope) {
|
||||
if(!envelope) {
|
||||
throw new Error("publishing from the 'global' postal.publish call requires a valid envelope.");
|
||||
"1" : function ( envelope ) {
|
||||
if ( !envelope ) {
|
||||
throw new Error( "publishing from the 'global' postal.publish call requires a valid envelope." );
|
||||
}
|
||||
envelope.channel = envelope.channel || DEFAULT_CHANNEL;
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
return envelope;
|
||||
},
|
||||
"2" : function(topic, data) {
|
||||
var envelope = { channel: DEFAULT_CHANNEL, topic: topic, timeStamp: new Date(), data: data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function(channel, topic, data) {
|
||||
var envelope = { channel: channel, topic: topic, timeStamp: new Date(), data: data };
|
||||
"2" : function ( topic, data ) {
|
||||
var envelope = { channel : DEFAULT_CHANNEL, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function ( channel, topic, data ) {
|
||||
var envelope = { channel : channel, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
}
|
||||
},
|
||||
channelPicker = {
|
||||
"1" : function( chn ) {
|
||||
"1" : function ( chn ) {
|
||||
var channel = chn, topic, options = {};
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
}
|
||||
else {
|
||||
channel = chn.channel || DEFAULT_CHANNEL;
|
||||
topic = chn.topic;
|
||||
topic = chn.topic;
|
||||
options = chn.options || options;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"2" : function( chn, tpc ) {
|
||||
"2" : function ( chn, tpc ) {
|
||||
var channel = chn, topic = tpc, options = {};
|
||||
if( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
if ( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
options = tpc;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"3" : function( channel, topic, options ) {
|
||||
"3" : function ( channel, topic, options ) {
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
}
|
||||
},
|
||||
|
|
@ -374,110 +379,110 @@ var publishPicker = {
|
|||
localBus.subscriptions[SYSTEM_CHANNEL] = {};
|
||||
|
||||
var postal = {
|
||||
configuration: {
|
||||
bus: localBus,
|
||||
resolver: bindingsResolver,
|
||||
getSessionIdAction: function( callback ) {
|
||||
configuration : {
|
||||
bus : localBus,
|
||||
resolver : bindingsResolver,
|
||||
getSessionIdAction : function ( callback ) {
|
||||
callback( sessionInfo );
|
||||
},
|
||||
setSessionIdAction: function( info, callback ) {
|
||||
setSessionIdAction : function ( info, callback ) {
|
||||
sessionInfo = info;
|
||||
callback( sessionInfo );
|
||||
},
|
||||
DEFAULT_CHANNEL: DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY: DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER: DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL: SYSTEM_CHANNEL
|
||||
DEFAULT_CHANNEL : DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY : DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER : DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL : SYSTEM_CHANNEL
|
||||
},
|
||||
|
||||
channelTypes: {
|
||||
local: ChannelDefinition
|
||||
channelTypes : {
|
||||
local : ChannelDefinition
|
||||
},
|
||||
|
||||
channel: function() {
|
||||
channel : function () {
|
||||
var len = arguments.length;
|
||||
if(channelPicker[len]) {
|
||||
return channelPicker[len].apply(this, arguments);
|
||||
if ( channelPicker[len] ) {
|
||||
return channelPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(options) {
|
||||
subscribe : function ( options ) {
|
||||
var callback = options.callback,
|
||||
topic = options.topic,
|
||||
channel = options.channel || DEFAULT_CHANNEL;
|
||||
return new SubscriptionDefinition(channel, topic, callback);
|
||||
return new SubscriptionDefinition( channel, topic, callback );
|
||||
},
|
||||
|
||||
publish: function() {
|
||||
publish : function () {
|
||||
var len = arguments.length;
|
||||
if(publishPicker[len]) {
|
||||
return publishPicker[len].apply(this, arguments);
|
||||
if ( publishPicker[len] ) {
|
||||
return publishPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
addWireTap: function(callback) {
|
||||
return this.configuration.bus.addWireTap(callback);
|
||||
addWireTap : function ( callback ) {
|
||||
return this.configuration.bus.addWireTap( callback );
|
||||
},
|
||||
|
||||
linkChannels: function(sources, destinations) {
|
||||
linkChannels : function ( sources, destinations ) {
|
||||
var result = [];
|
||||
if(!_.isArray(sources)) {
|
||||
if ( !_.isArray( sources ) ) {
|
||||
sources = [sources];
|
||||
}
|
||||
if(!_.isArray(destinations)) {
|
||||
if ( !_.isArray( destinations ) ) {
|
||||
destinations = [destinations];
|
||||
}
|
||||
_.each(sources, function(source){
|
||||
_.each( sources, function ( source ) {
|
||||
var sourceTopic = source.topic || "*";
|
||||
_.each(destinations, function(destination) {
|
||||
_.each( destinations, function ( destination ) {
|
||||
var destChannel = destination.channel || DEFAULT_CHANNEL;
|
||||
result.push(
|
||||
postal.subscribe({
|
||||
channel: source.channel || DEFAULT_CHANNEL,
|
||||
topic: source.topic || "*",
|
||||
callback : function(data, env) {
|
||||
postal.subscribe( {
|
||||
channel : source.channel || DEFAULT_CHANNEL,
|
||||
topic : source.topic || "*",
|
||||
callback : function ( data, env ) {
|
||||
var newEnv = env;
|
||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
||||
newEnv.topic = _.isFunction( destination.topic ) ? destination.topic( env.topic ) : destination.topic || env.topic;
|
||||
newEnv.channel = destChannel;
|
||||
newEnv.data = data;
|
||||
postal.publish(newEnv);
|
||||
postal.publish( newEnv );
|
||||
}
|
||||
})
|
||||
} )
|
||||
);
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
return result;
|
||||
},
|
||||
|
||||
utils: {
|
||||
getSessionId: function( callback ) {
|
||||
utils : {
|
||||
getSessionId : function ( callback ) {
|
||||
postal.configuration.getSessionIdAction.call( this, callback );
|
||||
},
|
||||
|
||||
setSessionId: function( value, callback ) {
|
||||
postal.utils.getSessionId( function( info ) {
|
||||
setSessionId : function ( value, callback ) {
|
||||
postal.utils.getSessionId( function ( info ) {
|
||||
// get the session info to move id to last id
|
||||
info.lastId = info.id;
|
||||
info.id = value;
|
||||
// invoke the callback the user provided to handle storing session
|
||||
postal.configuration.setSessionIdAction( info, function( session ) {
|
||||
postal.configuration.setSessionIdAction( info, function ( session ) {
|
||||
callback( session );
|
||||
// publish postal event msg about the change
|
||||
postal.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "sessionId.changed",
|
||||
data: session
|
||||
});
|
||||
postal.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "sessionId.changed",
|
||||
data : session
|
||||
} );
|
||||
} );
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
getSubscribersFor: function() {
|
||||
getSubscribersFor : function () {
|
||||
var channel = arguments[ 0 ],
|
||||
tpc = arguments[ 1 ],
|
||||
result = [];
|
||||
if( arguments.length === 1 ) {
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( arguments.length === 1 ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = postal.configuration.DEFAULT_CHANNEL;
|
||||
tpc = arguments[ 0 ];
|
||||
}
|
||||
|
|
@ -486,14 +491,14 @@ var postal = {
|
|||
tpc = arguments[ 0 ].topic;
|
||||
}
|
||||
}
|
||||
if( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc )) {
|
||||
if ( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc ) ) {
|
||||
result = postal.configuration.bus.subscriptions[ channel ][ tpc ];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
postal.configuration.bus.reset();
|
||||
postal.configuration.resolver.reset();
|
||||
}
|
||||
|
|
@ -501,4 +506,4 @@ var postal = {
|
|||
};
|
||||
|
||||
return postal;
|
||||
});
|
||||
} );
|
||||
Binary file not shown.
|
|
@ -2,30 +2,620 @@
|
|||
RequireJS 1.0.2 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
|
||||
Available via the MIT or new BSD license.
|
||||
see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
var requirejs,require,define;
|
||||
(function(){function J(a){return M.call(a)==="[object Function]"}function E(a){return M.call(a)==="[object Array]"}function Z(a,c,h){for(var k in c)if(!(k in K)&&(!(k in a)||h))a[k]=c[k];return d}function N(a,c,d){a=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+a);if(d)a.originalError=d;return a}function $(a,c,d){var k,j,q;for(k=0;q=c[k];k++){q=typeof q==="string"?{name:q}:q;j=q.location;if(d&&(!j||j.indexOf("/")!==0&&j.indexOf(":")===-1))j=d+"/"+(j||q.name);a[q.name]={name:q.name,location:j||
|
||||
q.name,main:(q.main||"main").replace(ea,"").replace(aa,"")}}}function V(a,c){a.holdReady?a.holdReady(c):c?a.readyWait+=1:a.ready(!0)}function fa(a){function c(b,l){var f,a;if(b&&b.charAt(0)===".")if(l){p.pkgs[l]?l=[l]:(l=l.split("/"),l=l.slice(0,l.length-1));f=b=l.concat(b.split("/"));var c;for(a=0;c=f[a];a++)if(c===".")f.splice(a,1),a-=1;else if(c==="..")if(a===1&&(f[2]===".."||f[0]===".."))break;else a>0&&(f.splice(a-1,2),a-=2);a=p.pkgs[f=b[0]];b=b.join("/");a&&b===f+"/"+a.main&&(b=f)}else b.indexOf("./")===
|
||||
0&&(b=b.substring(2));return b}function h(b,l){var f=b?b.indexOf("!"):-1,a=null,d=l?l.name:null,i=b,e,h;f!==-1&&(a=b.substring(0,f),b=b.substring(f+1,b.length));a&&(a=c(a,d));b&&(a?e=(f=m[a])&&f.normalize?f.normalize(b,function(b){return c(b,d)}):c(b,d):(e=c(b,d),h=E[e],h||(h=g.nameToUrl(e,null,l),E[e]=h)));return{prefix:a,name:e,parentMap:l,url:h,originalName:i,fullName:a?a+"!"+(e||""):e}}function k(){var b=!0,l=p.priorityWait,f,a;if(l){for(a=0;f=l[a];a++)if(!s[f]){b=!1;break}b&&delete p.priorityWait}return b}
|
||||
function j(b,l,f){return function(){var a=ga.call(arguments,0),c;if(f&&J(c=a[a.length-1]))c.__requireJsBuild=!0;a.push(l);return b.apply(null,a)}}function q(b,l){var a=j(g.require,b,l);Z(a,{nameToUrl:j(g.nameToUrl,b),toUrl:j(g.toUrl,b),defined:j(g.requireDefined,b),specified:j(g.requireSpecified,b),isBrowser:d.isBrowser});return a}function o(b){var l,a,c,C=b.callback,i=b.map,e=i.fullName,ba=b.deps;c=b.listeners;if(C&&J(C)){if(p.catchError.define)try{a=d.execCb(e,b.callback,ba,m[e])}catch(k){l=k}else a=
|
||||
d.execCb(e,b.callback,ba,m[e]);if(e)(C=b.cjsModule)&&C.exports!==void 0&&C.exports!==m[e]?a=m[e]=b.cjsModule.exports:a===void 0&&b.usingExports?a=m[e]:(m[e]=a,F[e]&&(Q[e]=!0))}else e&&(a=m[e]=C,F[e]&&(Q[e]=!0));if(D[b.id])delete D[b.id],b.isDone=!0,g.waitCount-=1,g.waitCount===0&&(I=[]);delete R[e];if(d.onResourceLoad&&!b.placeholder)d.onResourceLoad(g,i,b.depArray);if(l)return a=(e?h(e).url:"")||l.fileName||l.sourceURL,c=l.moduleTree,l=N("defineerror",'Error evaluating module "'+e+'" at location "'+
|
||||
a+'":\n'+l+"\nfileName:"+a+"\nlineNumber: "+(l.lineNumber||l.line),l),l.moduleName=e,l.moduleTree=c,d.onError(l);for(l=0;C=c[l];l++)C(a)}function r(b,a){return function(f){b.depDone[a]||(b.depDone[a]=!0,b.deps[a]=f,b.depCount-=1,b.depCount||o(b))}}function u(b,a){var f=a.map,c=f.fullName,h=f.name,i=L[b]||(L[b]=m[b]),e;if(!a.loading)a.loading=!0,e=function(b){a.callback=function(){return b};o(a);s[a.id]=!0;w()},e.fromText=function(b,a){var l=O;s[b]=!1;g.scriptCount+=1;g.fake[b]=!0;l&&(O=!1);d.exec(a);
|
||||
l&&(O=!0);g.completeLoad(b)},c in m?e(m[c]):i.load(h,q(f.parentMap,!0),e,p)}function v(b){D[b.id]||(D[b.id]=b,I.push(b),g.waitCount+=1)}function B(b){this.listeners.push(b)}function t(b,a){var f=b.fullName,c=b.prefix,d=c?L[c]||(L[c]=m[c]):null,i,e;f&&(i=R[f]);if(!i&&(e=!0,i={id:(c&&!d?M++ +"__p@:":"")+(f||"__r@"+M++),map:b,depCount:0,depDone:[],depCallbacks:[],deps:[],listeners:[],add:B},y[i.id]=!0,f&&(!c||L[c])))R[f]=i;c&&!d?(f=t(h(c),!0),f.add(function(){var a=h(b.originalName,b.parentMap),a=t(a,
|
||||
!0);i.placeholder=!0;a.add(function(b){i.callback=function(){return b};o(i)})})):e&&a&&(s[i.id]=!1,g.paused.push(i),v(i));return i}function x(b,a,f,c){var b=h(b,c),d=b.name,i=b.fullName,e=t(b),k=e.id,j=e.deps,n;if(i){if(i in m||s[k]===!0||i==="jquery"&&p.jQuery&&p.jQuery!==f().fn.jquery)return;y[k]=!0;s[k]=!0;i==="jquery"&&f&&S(f())}e.depArray=a;e.callback=f;for(f=0;f<a.length;f++)if(k=a[f])k=h(k,d?b:c),n=k.fullName,a[f]=n,n==="require"?j[f]=q(b):n==="exports"?(j[f]=m[i]={},e.usingExports=!0):n===
|
||||
"module"?e.cjsModule=j[f]={id:d,uri:d?g.nameToUrl(d,null,c):void 0,exports:m[i]}:n in m&&!(n in D)&&(!(i in F)||i in F&&Q[n])?j[f]=m[n]:(i in F&&(F[n]=!0,delete m[n],T[k.url]=!1),e.depCount+=1,e.depCallbacks[f]=r(e,f),t(k,!0).add(e.depCallbacks[f]));e.depCount?v(e):o(e)}function n(b){x.apply(null,b)}function z(b,a){if(!b.isDone){var c=b.map.fullName,d=b.depArray,g,i,e,k;if(c){if(a[c])return m[c];a[c]=!0}if(d)for(g=0;g<d.length;g++)if(i=d[g])if((e=h(i).prefix)&&(k=D[e])&&z(k,a),(e=D[i])&&!e.isDone&&
|
||||
s[i])i=z(e,a),b.depCallbacks[g](i);return c?m[c]:void 0}}function A(){var b=p.waitSeconds*1E3,a=b&&g.startTime+b<(new Date).getTime(),b="",c=!1,h=!1,j;if(!(g.pausedCount>0)){if(p.priorityWait)if(k())w();else return;for(j in s)if(!(j in K)&&(c=!0,!s[j]))if(a)b+=j+" ";else{h=!0;break}if(c||g.waitCount){if(a&&b)return j=N("timeout","Load timeout for modules: "+b),j.requireType="timeout",j.requireModules=b,d.onError(j);if(h||g.scriptCount){if((G||ca)&&!W)W=setTimeout(function(){W=0;A()},50)}else{if(g.waitCount){for(H=
|
||||
0;b=I[H];H++)z(b,{});g.paused.length&&w();X<5&&(X+=1,A())}X=0;d.checkReadyState()}}}}var g,w,p={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},catchError:{}},P=[],y={require:!0,exports:!0,module:!0},E={},m={},s={},D={},I=[],T={},M=0,R={},L={},F={},Q={},Y=0;S=function(b){if(!g.jQuery&&(b=b||(typeof jQuery!=="undefined"?jQuery:null))&&!(p.jQuery&&b.fn.jquery!==p.jQuery)&&("holdReady"in b||"readyWait"in b))if(g.jQuery=b,n(["jquery",[],function(){return jQuery}]),g.scriptCount)V(b,!0),g.jQueryIncremented=
|
||||
!0};w=function(){var b,a,c,h,j,i;Y+=1;if(g.scriptCount<=0)g.scriptCount=0;for(;P.length;)if(b=P.shift(),b[0]===null)return d.onError(N("mismatch","Mismatched anonymous define() module: "+b[b.length-1]));else n(b);if(!p.priorityWait||k())for(;g.paused.length;){j=g.paused;g.pausedCount+=j.length;g.paused=[];for(h=0;b=j[h];h++)a=b.map,c=a.url,i=a.fullName,a.prefix?u(a.prefix,b):!T[c]&&!s[i]&&(d.load(g,i,c),c.indexOf("empty:")!==0&&(T[c]=!0));g.startTime=(new Date).getTime();g.pausedCount-=j.length}Y===
|
||||
1&&A();Y-=1};g={contextName:a,config:p,defQueue:P,waiting:D,waitCount:0,specified:y,loaded:s,urlMap:E,urlFetched:T,scriptCount:0,defined:m,paused:[],pausedCount:0,plugins:L,needFullExec:F,fake:{},fullExec:Q,managerCallbacks:R,makeModuleMap:h,normalize:c,configure:function(b){var a,c,d;b.baseUrl&&b.baseUrl.charAt(b.baseUrl.length-1)!=="/"&&(b.baseUrl+="/");a=p.paths;d=p.pkgs;Z(p,b,!0);if(b.paths){for(c in b.paths)c in K||(a[c]=b.paths[c]);p.paths=a}if((a=b.packagePaths)||b.packages){if(a)for(c in a)c in
|
||||
K||$(d,a[c],c);b.packages&&$(d,b.packages);p.pkgs=d}if(b.priority)c=g.requireWait,g.requireWait=!1,g.takeGlobalQueue(),w(),g.require(b.priority),w(),g.requireWait=c,p.priorityWait=b.priority;if(b.deps||b.callback)g.require(b.deps||[],b.callback)},requireDefined:function(b,a){return h(b,a).fullName in m},requireSpecified:function(b,a){return h(b,a).fullName in y},require:function(b,c,f){if(typeof b==="string"){if(J(c))return d.onError(N("requireargs","Invalid require call"));if(d.get)return d.get(g,
|
||||
b,c);c=h(b,c);b=c.fullName;return!(b in m)?d.onError(N("notloaded","Module name '"+c.fullName+"' has not been loaded yet for context: "+a)):m[b]}(b&&b.length||c)&&x(null,b,c,f);if(!g.requireWait)for(;!g.scriptCount&&g.paused.length;)g.takeGlobalQueue(),w();return g.require},takeGlobalQueue:function(){U.length&&(ha.apply(g.defQueue,[g.defQueue.length-1,0].concat(U)),U=[])},completeLoad:function(b){var a;for(g.takeGlobalQueue();P.length;)if(a=P.shift(),a[0]===null){a[0]=b;break}else if(a[0]===b)break;
|
||||
else n(a),a=null;a?n(a):n([b,[],b==="jquery"&&typeof jQuery!=="undefined"?function(){return jQuery}:null]);S();d.isAsync&&(g.scriptCount-=1);w();d.isAsync||(g.scriptCount-=1)},toUrl:function(a,c){var d=a.lastIndexOf("."),h=null;d!==-1&&(h=a.substring(d,a.length),a=a.substring(0,d));return g.nameToUrl(a,h,c)},nameToUrl:function(a,h,f){var j,k,i,e,m=g.config,a=c(a,f&&f.fullName);if(d.jsExtRegExp.test(a))h=a+(h?h:"");else{j=m.paths;k=m.pkgs;f=a.split("/");for(e=f.length;e>0;e--)if(i=f.slice(0,e).join("/"),
|
||||
j[i]){f.splice(0,e,j[i]);break}else if(i=k[i]){a=a===i.name?i.location+"/"+i.main:i.location;f.splice(0,e,a);break}h=f.join("/")+(h||".js");h=(h.charAt(0)==="/"||h.match(/^\w+:/)?"":m.baseUrl)+h}return m.urlArgs?h+((h.indexOf("?")===-1?"?":"&")+m.urlArgs):h}};g.jQueryCheck=S;g.resume=w;return g}function ia(){var a,c,d;if(n&&n.readyState==="interactive")return n;a=document.getElementsByTagName("script");for(c=a.length-1;c>-1&&(d=a[c]);c--)if(d.readyState==="interactive")return n=d;return null}var ja=
|
||||
/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ka=/require\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/^\.\//,aa=/\.js$/,M=Object.prototype.toString,r=Array.prototype,ga=r.slice,ha=r.splice,G=!!(typeof window!=="undefined"&&navigator&&document),ca=!G&&typeof importScripts!=="undefined",la=G&&navigator.platform==="PLAYSTATION 3"?/^complete$/:/^(complete|loaded)$/,da=typeof opera!=="undefined"&&opera.toString()==="[object Opera]",K={},t={},U=[],n=null,X=0,O=!1,d,r={},I,v,x,y,u,z,A,H,B,S,W;if(typeof define==="undefined"){if(typeof requirejs!==
|
||||
"undefined")if(J(requirejs))return;else r=requirejs,requirejs=void 0;typeof require!=="undefined"&&!J(require)&&(r=require,require=void 0);d=requirejs=function(a,c,d){var k="_",j;!E(a)&&typeof a!=="string"&&(j=a,E(c)?(a=c,c=d):a=[]);if(j&&j.context)k=j.context;d=t[k]||(t[k]=fa(k));j&&d.configure(j);return d.require(a,c)};d.config=function(a){return d(a)};require||(require=d);d.toUrl=function(a){return t._.toUrl(a)};d.version="1.0.2";d.jsExtRegExp=/^\/|:|\?|\.js$/;v=d.s={contexts:t,skipAsync:{}};if(d.isAsync=
|
||||
d.isBrowser=G)if(x=v.head=document.getElementsByTagName("head")[0],y=document.getElementsByTagName("base")[0])x=v.head=y.parentNode;d.onError=function(a){throw a;};d.load=function(a,c,h){d.resourcesReady(!1);a.scriptCount+=1;d.attach(h,a,c);if(a.jQuery&&!a.jQueryIncremented)V(a.jQuery,!0),a.jQueryIncremented=!0};define=function(a,c,d){var k,j;typeof a!=="string"&&(d=c,c=a,a=null);E(c)||(d=c,c=[]);!c.length&&J(d)&&d.length&&(d.toString().replace(ja,"").replace(ka,function(a,d){c.push(d)}),c=(d.length===
|
||||
1?["require"]:["require","exports","module"]).concat(c));if(O&&(k=I||ia()))a||(a=k.getAttribute("data-requiremodule")),j=t[k.getAttribute("data-requirecontext")];(j?j.defQueue:U).push([a,c,d])};define.amd={multiversion:!0,plugins:!0,jQuery:!0};d.exec=function(a){return eval(a)};d.execCb=function(a,c,d,k){return c.apply(k,d)};d.addScriptToDom=function(a){I=a;y?x.insertBefore(a,y):x.appendChild(a);I=null};d.onScriptLoad=function(a){var c=a.currentTarget||a.srcElement,h;if(a.type==="load"||c&&la.test(c.readyState))n=
|
||||
null,a=c.getAttribute("data-requirecontext"),h=c.getAttribute("data-requiremodule"),t[a].completeLoad(h),c.detachEvent&&!da?c.detachEvent("onreadystatechange",d.onScriptLoad):c.removeEventListener("load",d.onScriptLoad,!1)};d.attach=function(a,c,h,k,j,n){var o;if(G)return k=k||d.onScriptLoad,o=c&&c.config&&c.config.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),o.type=j||"text/javascript",o.charset="utf-8",o.async=!v.skipAsync[a],c&&o.setAttribute("data-requirecontext",
|
||||
c.contextName),o.setAttribute("data-requiremodule",h),o.attachEvent&&!da?(O=!0,n?o.onreadystatechange=function(){if(o.readyState==="loaded")o.onreadystatechange=null,o.attachEvent("onreadystatechange",k),n(o)}:o.attachEvent("onreadystatechange",k)):o.addEventListener("load",k,!1),o.src=a,n||d.addScriptToDom(o),o;else ca&&(importScripts(a),c.completeLoad(h));return null};if(G){u=document.getElementsByTagName("script");for(H=u.length-1;H>-1&&(z=u[H]);H--){if(!x)x=z.parentNode;if(A=z.getAttribute("data-main")){if(!r.baseUrl)u=
|
||||
A.split("/"),z=u.pop(),u=u.length?u.join("/")+"/":"./",r.baseUrl=u,A=z.replace(aa,"");r.deps=r.deps?r.deps.concat(A):[A];break}}}d.checkReadyState=function(){var a=v.contexts,c;for(c in a)if(!(c in K)&&a[c].waitCount)return;d.resourcesReady(!0)};d.resourcesReady=function(a){var c,h;d.resourcesDone=a;if(d.resourcesDone)for(h in a=v.contexts,a)if(!(h in K)&&(c=a[h],c.jQueryIncremented))V(c.jQuery,!1),c.jQueryIncremented=!1};d.pageLoaded=function(){if(document.readyState!=="complete")document.readyState=
|
||||
"complete"};if(G&&document.addEventListener&&!document.readyState)document.readyState="loading",window.addEventListener("load",d.pageLoaded,!1);d(r);if(d.isAsync&&typeof setTimeout!=="undefined")B=v.contexts[r.context||"_"],B.requireWait=!0,setTimeout(function(){B.requireWait=!1;B.takeGlobalQueue();B.jQueryCheck();B.scriptCount||B.resume();d.checkReadyState()},0)}})();
|
||||
*/
|
||||
var requirejs, require, define;
|
||||
(function () {
|
||||
function J( a ) {
|
||||
return M.call( a ) === "[object Function]"
|
||||
}
|
||||
|
||||
function E( a ) {
|
||||
return M.call( a ) === "[object Array]"
|
||||
}
|
||||
|
||||
function Z( a, c, h ) {
|
||||
for ( var k in c ) {
|
||||
if ( !(k in K) && (!(k in a) || h) ) {
|
||||
a[k] = c[k];
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
function N( a, c, d ) {
|
||||
a = Error( c + "\nhttp://requirejs.org/docs/errors.html#" + a );
|
||||
if ( d ) {
|
||||
a.originalError = d;
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
function $( a, c, d ) {
|
||||
var k, j, q;
|
||||
for ( k = 0; q = c[k]; k++ ) {
|
||||
q = typeof q === "string" ? {name : q} : q;
|
||||
j = q.location;
|
||||
if ( d && (!j || j.indexOf( "/" ) !== 0 && j.indexOf( ":" ) === -1) ) {
|
||||
j = d + "/" + (j || q.name);
|
||||
}
|
||||
a[q.name] = {name : q.name, location : j ||
|
||||
q.name, main : (q.main || "main").replace( ea, "" ).replace( aa, "" )}
|
||||
}
|
||||
}
|
||||
|
||||
function V( a, c ) {
|
||||
a.holdReady ? a.holdReady( c ) : c ? a.readyWait += 1 : a.ready( !0 )
|
||||
}
|
||||
|
||||
function fa( a ) {
|
||||
function c( b, l ) {
|
||||
var f, a;
|
||||
if ( b && b.charAt( 0 ) === "." ) {
|
||||
if ( l ) {
|
||||
p.pkgs[l] ? l = [l] : (l = l.split( "/" ), l = l.slice( 0, l.length - 1 ));
|
||||
f = b = l.concat( b.split( "/" ) );
|
||||
var c;
|
||||
for ( a = 0; c = f[a]; a++ ) {
|
||||
if ( c === "." ) {
|
||||
f.splice( a, 1 ), a -= 1;
|
||||
} else if ( c === ".." ) {
|
||||
if ( a === 1 && (f[2] === ".." || f[0] === "..") ) {
|
||||
break;
|
||||
} else {
|
||||
a > 0 && (f.splice( a - 1, 2 ), a -= 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
a = p.pkgs[f = b[0]];
|
||||
b = b.join( "/" );
|
||||
a && b === f + "/" + a.main && (b = f)
|
||||
} else {
|
||||
b.indexOf( "./" ) ===
|
||||
0 && (b = b.substring( 2 ));
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
function h( b, l ) {
|
||||
var f = b ? b.indexOf( "!" ) : -1, a = null, d = l ? l.name : null, i = b, e, h;
|
||||
f !== -1 && (a = b.substring( 0, f ), b = b.substring( f + 1, b.length ));
|
||||
a && (a = c( a, d ));
|
||||
b && (a ? e = (f = m[a]) && f.normalize ? f.normalize( b, function ( b ) {
|
||||
return c( b, d )
|
||||
} ) : c( b, d ) : (e = c( b, d ), h = E[e], h || (h = g.nameToUrl( e, null, l ), E[e] = h)));
|
||||
return{prefix : a, name : e, parentMap : l, url : h, originalName : i, fullName : a ? a + "!" + (e || "") : e}
|
||||
}
|
||||
|
||||
function k() {
|
||||
var b = !0, l = p.priorityWait, f, a;
|
||||
if ( l ) {
|
||||
for ( a = 0; f = l[a]; a++ ) {
|
||||
if ( !s[f] ) {
|
||||
b = !1;
|
||||
break
|
||||
}
|
||||
}
|
||||
b && delete p.priorityWait
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
function j( b, l, f ) {
|
||||
return function () {
|
||||
var a = ga.call( arguments, 0 ), c;
|
||||
if ( f && J( c = a[a.length - 1] ) ) {
|
||||
c.__requireJsBuild = !0;
|
||||
}
|
||||
a.push( l );
|
||||
return b.apply( null, a )
|
||||
}
|
||||
}
|
||||
|
||||
function q( b, l ) {
|
||||
var a = j( g.require, b, l );
|
||||
Z( a, {nameToUrl : j( g.nameToUrl, b ), toUrl : j( g.toUrl, b ), defined : j( g.requireDefined, b ), specified : j( g.requireSpecified, b ), isBrowser : d.isBrowser} );
|
||||
return a
|
||||
}
|
||||
|
||||
function o( b ) {
|
||||
var l, a, c, C = b.callback, i = b.map, e = i.fullName, ba = b.deps;
|
||||
c = b.listeners;
|
||||
if ( C && J( C ) ) {
|
||||
if ( p.catchError.define ) {
|
||||
try {
|
||||
a = d.execCb( e, b.callback, ba, m[e] )
|
||||
} catch ( k ) {
|
||||
l = k
|
||||
}
|
||||
} else {
|
||||
a =
|
||||
d.execCb( e, b.callback, ba, m[e] );
|
||||
}
|
||||
if ( e ) {
|
||||
(C = b.cjsModule) && C.exports !== void 0 && C.exports !== m[e] ? a = m[e] = b.cjsModule.exports : a === void 0 && b.usingExports ? a = m[e] : (m[e] = a, F[e] && (Q[e] = !0))
|
||||
}
|
||||
} else {
|
||||
e && (a = m[e] = C, F[e] && (Q[e] = !0));
|
||||
}
|
||||
if ( D[b.id] ) {
|
||||
delete D[b.id], b.isDone = !0, g.waitCount -= 1, g.waitCount === 0 && (I = []);
|
||||
}
|
||||
delete R[e];
|
||||
if ( d.onResourceLoad && !b.placeholder ) {
|
||||
d.onResourceLoad( g, i, b.depArray );
|
||||
}
|
||||
if ( l ) {
|
||||
return a = (e ? h( e ).url : "") || l.fileName || l.sourceURL, c = l.moduleTree, l = N( "defineerror", 'Error evaluating module "' + e + '" at location "' +
|
||||
a + '":\n' + l + "\nfileName:" + a + "\nlineNumber: " + (l.lineNumber || l.line), l ), l.moduleName = e, l.moduleTree = c, d.onError( l );
|
||||
}
|
||||
for ( l = 0; C = c[l]; l++ ) {
|
||||
C( a )
|
||||
}
|
||||
}
|
||||
|
||||
function r( b, a ) {
|
||||
return function ( f ) {
|
||||
b.depDone[a] || (b.depDone[a] = !0, b.deps[a] = f, b.depCount -= 1, b.depCount || o( b ))
|
||||
}
|
||||
}
|
||||
|
||||
function u( b, a ) {
|
||||
var f = a.map, c = f.fullName, h = f.name, i = L[b] || (L[b] = m[b]), e;
|
||||
if ( !a.loading ) {
|
||||
a.loading = !0, e = function ( b ) {
|
||||
a.callback = function () {
|
||||
return b
|
||||
};
|
||||
o( a );
|
||||
s[a.id] = !0;
|
||||
w()
|
||||
}, e.fromText = function ( b, a ) {
|
||||
var l = O;
|
||||
s[b] = !1;
|
||||
g.scriptCount += 1;
|
||||
g.fake[b] = !0;
|
||||
l && (O = !1);
|
||||
d.exec( a );
|
||||
l && (O = !0);
|
||||
g.completeLoad( b )
|
||||
}, c in m ? e( m[c] ) : i.load( h, q( f.parentMap, !0 ), e, p )
|
||||
}
|
||||
}
|
||||
|
||||
function v( b ) {
|
||||
D[b.id] || (D[b.id] = b, I.push( b ), g.waitCount += 1)
|
||||
}
|
||||
|
||||
function B( b ) {
|
||||
this.listeners.push( b )
|
||||
}
|
||||
|
||||
function t( b, a ) {
|
||||
var f = b.fullName, c = b.prefix, d = c ? L[c] || (L[c] = m[c]) : null, i, e;
|
||||
f && (i = R[f]);
|
||||
if ( !i && (e = !0, i = {id : (c && !d ? M++ + "__p@:" : "") + (f || "__r@" + M++), map : b, depCount : 0, depDone : [], depCallbacks : [], deps : [], listeners : [], add : B}, y[i.id] = !0, f && (!c || L[c])) ) {
|
||||
R[f] = i;
|
||||
}
|
||||
c && !d ? (f = t( h( c ), !0 ), f.add( function () {
|
||||
var a = h( b.originalName, b.parentMap ), a = t( a,
|
||||
!0 );
|
||||
i.placeholder = !0;
|
||||
a.add( function ( b ) {
|
||||
i.callback = function () {
|
||||
return b
|
||||
};
|
||||
o( i )
|
||||
} )
|
||||
} )) : e && a && (s[i.id] = !1, g.paused.push( i ), v( i ));
|
||||
return i
|
||||
}
|
||||
|
||||
function x( b, a, f, c ) {
|
||||
var b = h( b, c ), d = b.name, i = b.fullName, e = t( b ), k = e.id, j = e.deps, n;
|
||||
if ( i ) {
|
||||
if ( i in m || s[k] === !0 || i === "jquery" && p.jQuery && p.jQuery !== f().fn.jquery ) {
|
||||
return;
|
||||
}
|
||||
y[k] = !0;
|
||||
s[k] = !0;
|
||||
i === "jquery" && f && S( f() )
|
||||
}
|
||||
e.depArray = a;
|
||||
e.callback = f;
|
||||
for ( f = 0; f < a.length; f++ ) {
|
||||
if ( k = a[f] ) {
|
||||
k = h( k, d ? b : c ), n = k.fullName, a[f] = n, n === "require" ? j[f] = q( b ) : n === "exports" ? (j[f] = m[i] = {}, e.usingExports = !0) : n ===
|
||||
"module" ? e.cjsModule = j[f] = {id : d, uri : d ? g.nameToUrl( d, null, c ) : void 0, exports : m[i]} : n in m && !(n in D) && (!(i in F) || i in F && Q[n]) ? j[f] = m[n] : (i in F && (F[n] = !0, delete m[n], T[k.url] = !1), e.depCount += 1, e.depCallbacks[f] = r( e, f ), t( k, !0 ).add( e.depCallbacks[f] ));
|
||||
}
|
||||
}
|
||||
e.depCount ? v( e ) : o( e )
|
||||
}
|
||||
|
||||
function n( b ) {
|
||||
x.apply( null, b )
|
||||
}
|
||||
|
||||
function z( b, a ) {
|
||||
if ( !b.isDone ) {
|
||||
var c = b.map.fullName, d = b.depArray, g, i, e, k;
|
||||
if ( c ) {
|
||||
if ( a[c] ) {
|
||||
return m[c];
|
||||
}
|
||||
a[c] = !0
|
||||
}
|
||||
if ( d ) {
|
||||
for ( g = 0; g < d.length; g++ ) {
|
||||
if ( i = d[g] ) {
|
||||
if ( (e = h( i ).prefix) && (k = D[e]) && z( k, a ), (e = D[i]) && !e.isDone &&
|
||||
s[i] ) {
|
||||
i = z( e, a ), b.depCallbacks[g]( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return c ? m[c] : void 0
|
||||
}
|
||||
}
|
||||
|
||||
function A() {
|
||||
var b = p.waitSeconds * 1E3, a = b && g.startTime + b < (new Date).getTime(), b = "", c = !1, h = !1, j;
|
||||
if ( !(g.pausedCount > 0) ) {
|
||||
if ( p.priorityWait ) {
|
||||
if ( k() ) {
|
||||
w();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for ( j in s ) {
|
||||
if ( !(j in K) && (c = !0, !s[j]) ) {
|
||||
if ( a ) {
|
||||
b += j + " ";
|
||||
} else {
|
||||
h = !0;
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( c || g.waitCount ) {
|
||||
if ( a && b ) {
|
||||
return j = N( "timeout", "Load timeout for modules: " + b ), j.requireType = "timeout", j.requireModules = b, d.onError( j );
|
||||
}
|
||||
if ( h || g.scriptCount ) {
|
||||
if ( (G || ca) && !W ) {
|
||||
W = setTimeout( function () {
|
||||
W = 0;
|
||||
A()
|
||||
}, 50 )
|
||||
}
|
||||
} else {
|
||||
if ( g.waitCount ) {
|
||||
for ( H =
|
||||
0; b = I[H]; H++ ) {
|
||||
z( b, {} );
|
||||
}
|
||||
g.paused.length && w();
|
||||
X < 5 && (X += 1, A())
|
||||
}
|
||||
X = 0;
|
||||
d.checkReadyState()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var g, w, p = {waitSeconds : 7, baseUrl : "./", paths : {}, pkgs : {}, catchError : {}}, P = [], y = {require : !0, exports : !0, module : !0}, E = {}, m = {}, s = {}, D = {}, I = [], T = {}, M = 0, R = {}, L = {}, F = {}, Q = {}, Y = 0;
|
||||
S = function ( b ) {
|
||||
if ( !g.jQuery && (b = b || (typeof jQuery !== "undefined" ? jQuery : null)) && !(p.jQuery && b.fn.jquery !== p.jQuery) && ("holdReady"in b || "readyWait"in b) ) {
|
||||
if ( g.jQuery = b, n( ["jquery", [], function () {
|
||||
return jQuery
|
||||
}] ), g.scriptCount ) {
|
||||
V( b, !0 ), g.jQueryIncremented =
|
||||
!0
|
||||
}
|
||||
}
|
||||
};
|
||||
w = function () {
|
||||
var b, a, c, h, j, i;
|
||||
Y += 1;
|
||||
if ( g.scriptCount <= 0 ) {
|
||||
g.scriptCount = 0;
|
||||
}
|
||||
for ( ; P.length; ) {
|
||||
if ( b = P.shift(), b[0] === null ) {
|
||||
return d.onError( N( "mismatch", "Mismatched anonymous define() module: " + b[b.length - 1] ) );
|
||||
} else {
|
||||
n( b );
|
||||
}
|
||||
}
|
||||
if ( !p.priorityWait || k() ) {
|
||||
for ( ; g.paused.length; ) {
|
||||
j = g.paused;
|
||||
g.pausedCount += j.length;
|
||||
g.paused = [];
|
||||
for ( h = 0; b = j[h]; h++ ) {
|
||||
a = b.map, c = a.url, i = a.fullName, a.prefix ? u( a.prefix, b ) : !T[c] && !s[i] && (d.load( g, i, c ), c.indexOf( "empty:" ) !== 0 && (T[c] = !0));
|
||||
}
|
||||
g.startTime = (new Date).getTime();
|
||||
g.pausedCount -= j.length
|
||||
}
|
||||
}
|
||||
Y ===
|
||||
1 && A();
|
||||
Y -= 1
|
||||
};
|
||||
g = {contextName : a, config : p, defQueue : P, waiting : D, waitCount : 0, specified : y, loaded : s, urlMap : E, urlFetched : T, scriptCount : 0, defined : m, paused : [], pausedCount : 0, plugins : L, needFullExec : F, fake : {}, fullExec : Q, managerCallbacks : R, makeModuleMap : h, normalize : c, configure : function ( b ) {
|
||||
var a, c, d;
|
||||
b.baseUrl && b.baseUrl.charAt( b.baseUrl.length - 1 ) !== "/" && (b.baseUrl += "/");
|
||||
a = p.paths;
|
||||
d = p.pkgs;
|
||||
Z( p, b, !0 );
|
||||
if ( b.paths ) {
|
||||
for ( c in b.paths ) {
|
||||
c in K || (a[c] = b.paths[c]);
|
||||
}
|
||||
p.paths = a
|
||||
}
|
||||
if ( (a = b.packagePaths) || b.packages ) {
|
||||
if ( a ) {
|
||||
for ( c in a ) {
|
||||
c in
|
||||
K || $( d, a[c], c );
|
||||
}
|
||||
}
|
||||
b.packages && $( d, b.packages );
|
||||
p.pkgs = d
|
||||
}
|
||||
if ( b.priority ) {
|
||||
c = g.requireWait, g.requireWait = !1, g.takeGlobalQueue(), w(), g.require( b.priority ), w(), g.requireWait = c, p.priorityWait = b.priority;
|
||||
}
|
||||
if ( b.deps || b.callback ) {
|
||||
g.require( b.deps || [], b.callback )
|
||||
}
|
||||
}, requireDefined : function ( b, a ) {
|
||||
return h( b, a ).fullName in m
|
||||
}, requireSpecified : function ( b, a ) {
|
||||
return h( b, a ).fullName in y
|
||||
}, require : function ( b, c, f ) {
|
||||
if ( typeof b === "string" ) {
|
||||
if ( J( c ) ) {
|
||||
return d.onError( N( "requireargs", "Invalid require call" ) );
|
||||
}
|
||||
if ( d.get ) {
|
||||
return d.get( g,
|
||||
b, c );
|
||||
}
|
||||
c = h( b, c );
|
||||
b = c.fullName;
|
||||
return!(b in m) ? d.onError( N( "notloaded", "Module name '" + c.fullName + "' has not been loaded yet for context: " + a ) ) : m[b]
|
||||
}
|
||||
(b && b.length || c) && x( null, b, c, f );
|
||||
if ( !g.requireWait ) {
|
||||
for ( ; !g.scriptCount && g.paused.length; ) {
|
||||
g.takeGlobalQueue(), w();
|
||||
}
|
||||
}
|
||||
return g.require
|
||||
}, takeGlobalQueue : function () {
|
||||
U.length && (ha.apply( g.defQueue, [g.defQueue.length - 1, 0].concat( U ) ), U = [])
|
||||
}, completeLoad : function ( b ) {
|
||||
var a;
|
||||
for ( g.takeGlobalQueue(); P.length; ) {
|
||||
if ( a = P.shift(), a[0] === null ) {
|
||||
a[0] = b;
|
||||
break
|
||||
} else if ( a[0] === b ) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
n( a ), a = null;
|
||||
}
|
||||
}
|
||||
a ? n( a ) : n( [b, [], b === "jquery" && typeof jQuery !== "undefined" ? function () {
|
||||
return jQuery
|
||||
} : null] );
|
||||
S();
|
||||
d.isAsync && (g.scriptCount -= 1);
|
||||
w();
|
||||
d.isAsync || (g.scriptCount -= 1)
|
||||
}, toUrl : function ( a, c ) {
|
||||
var d = a.lastIndexOf( "." ), h = null;
|
||||
d !== -1 && (h = a.substring( d, a.length ), a = a.substring( 0, d ));
|
||||
return g.nameToUrl( a, h, c )
|
||||
}, nameToUrl : function ( a, h, f ) {
|
||||
var j, k, i, e, m = g.config, a = c( a, f && f.fullName );
|
||||
if ( d.jsExtRegExp.test( a ) ) {
|
||||
h = a + (h ? h : "");
|
||||
} else {
|
||||
j = m.paths;
|
||||
k = m.pkgs;
|
||||
f = a.split( "/" );
|
||||
for ( e = f.length; e > 0; e-- ) {
|
||||
if ( i = f.slice( 0, e ).join( "/" ),
|
||||
j[i] ) {
|
||||
f.splice( 0, e, j[i] );
|
||||
break
|
||||
} else if ( i = k[i] ) {
|
||||
a = a === i.name ? i.location + "/" + i.main : i.location;
|
||||
f.splice( 0, e, a );
|
||||
break
|
||||
}
|
||||
}
|
||||
h = f.join( "/" ) + (h || ".js");
|
||||
h = (h.charAt( 0 ) === "/" || h.match( /^\w+:/ ) ? "" : m.baseUrl) + h
|
||||
}
|
||||
return m.urlArgs ? h + ((h.indexOf( "?" ) === -1 ? "?" : "&") + m.urlArgs) : h
|
||||
}};
|
||||
g.jQueryCheck = S;
|
||||
g.resume = w;
|
||||
return g
|
||||
}
|
||||
|
||||
function ia() {
|
||||
var a, c, d;
|
||||
if ( n && n.readyState === "interactive" ) {
|
||||
return n;
|
||||
}
|
||||
a = document.getElementsByTagName( "script" );
|
||||
for ( c = a.length - 1; c > -1 && (d = a[c]); c-- ) {
|
||||
if ( d.readyState === "interactive" ) {
|
||||
return n = d;
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
var ja =
|
||||
/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, ka = /require\(\s*["']([^'"\s]+)["']\s*\)/g, ea = /^\.\//, aa = /\.js$/, M = Object.prototype.toString, r = Array.prototype, ga = r.slice, ha = r.splice, G = !!(typeof window !== "undefined" && navigator && document), ca = !G && typeof importScripts !== "undefined", la = G && navigator.platform === "PLAYSTATION 3" ? /^complete$/ : /^(complete|loaded)$/, da = typeof opera !== "undefined" && opera.toString() === "[object Opera]", K = {}, t = {}, U = [], n = null, X = 0, O = !1, d, r = {}, I, v, x, y, u, z, A, H, B, S, W;
|
||||
if ( typeof define === "undefined" ) {
|
||||
if ( typeof requirejs !==
|
||||
"undefined" ) {
|
||||
if ( J( requirejs ) ) {
|
||||
return;
|
||||
} else {
|
||||
r = requirejs, requirejs = void 0;
|
||||
}
|
||||
}
|
||||
typeof require !== "undefined" && !J( require ) && (r = require, require = void 0);
|
||||
d = requirejs = function ( a, c, d ) {
|
||||
var k = "_", j;
|
||||
!E( a ) && typeof a !== "string" && (j = a, E( c ) ? (a = c, c = d) : a = []);
|
||||
if ( j && j.context ) {
|
||||
k = j.context;
|
||||
}
|
||||
d = t[k] || (t[k] = fa( k ));
|
||||
j && d.configure( j );
|
||||
return d.require( a, c )
|
||||
};
|
||||
d.config = function ( a ) {
|
||||
return d( a )
|
||||
};
|
||||
require || (require = d);
|
||||
d.toUrl = function ( a ) {
|
||||
return t._.toUrl( a )
|
||||
};
|
||||
d.version = "1.0.2";
|
||||
d.jsExtRegExp = /^\/|:|\?|\.js$/;
|
||||
v = d.s = {contexts : t, skipAsync : {}};
|
||||
if ( d.isAsync =
|
||||
d.isBrowser = G ) {
|
||||
if ( x = v.head = document.getElementsByTagName( "head" )[0], y = document.getElementsByTagName( "base" )[0] ) {
|
||||
x = v.head = y.parentNode;
|
||||
}
|
||||
}
|
||||
d.onError = function ( a ) {
|
||||
throw a;
|
||||
};
|
||||
d.load = function ( a, c, h ) {
|
||||
d.resourcesReady( !1 );
|
||||
a.scriptCount += 1;
|
||||
d.attach( h, a, c );
|
||||
if ( a.jQuery && !a.jQueryIncremented ) {
|
||||
V( a.jQuery, !0 ), a.jQueryIncremented = !0
|
||||
}
|
||||
};
|
||||
define = function ( a, c, d ) {
|
||||
var k, j;
|
||||
typeof a !== "string" && (d = c, c = a, a = null);
|
||||
E( c ) || (d = c, c = []);
|
||||
!c.length && J( d ) && d.length && (d.toString().replace( ja, "" ).replace( ka, function ( a, d ) {
|
||||
c.push( d )
|
||||
} ), c = (d.length ===
|
||||
1 ? ["require"] : ["require", "exports", "module"]).concat( c ));
|
||||
if ( O && (k = I || ia()) ) {
|
||||
a || (a = k.getAttribute( "data-requiremodule" )), j = t[k.getAttribute( "data-requirecontext" )];
|
||||
}
|
||||
(j ? j.defQueue : U).push( [a, c, d] )
|
||||
};
|
||||
define.amd = {multiversion : !0, plugins : !0, jQuery : !0};
|
||||
d.exec = function ( a ) {
|
||||
return eval( a )
|
||||
};
|
||||
d.execCb = function ( a, c, d, k ) {
|
||||
return c.apply( k, d )
|
||||
};
|
||||
d.addScriptToDom = function ( a ) {
|
||||
I = a;
|
||||
y ? x.insertBefore( a, y ) : x.appendChild( a );
|
||||
I = null
|
||||
};
|
||||
d.onScriptLoad = function ( a ) {
|
||||
var c = a.currentTarget || a.srcElement, h;
|
||||
if ( a.type === "load" || c && la.test( c.readyState ) ) {
|
||||
n =
|
||||
null, a = c.getAttribute( "data-requirecontext" ), h = c.getAttribute( "data-requiremodule" ), t[a].completeLoad( h ), c.detachEvent && !da ? c.detachEvent( "onreadystatechange", d.onScriptLoad ) : c.removeEventListener( "load", d.onScriptLoad, !1 )
|
||||
}
|
||||
};
|
||||
d.attach = function ( a, c, h, k, j, n ) {
|
||||
var o;
|
||||
if ( G ) {
|
||||
return k = k || d.onScriptLoad, o = c && c.config && c.config.xhtml ? document.createElementNS( "http://www.w3.org/1999/xhtml", "html:script" ) : document.createElement( "script" ), o.type = j || "text/javascript", o.charset = "utf-8", o.async = !v.skipAsync[a], c && o.setAttribute( "data-requirecontext",
|
||||
c.contextName ), o.setAttribute( "data-requiremodule", h ), o.attachEvent && !da ? (O = !0, n ? o.onreadystatechange = function () {
|
||||
if ( o.readyState === "loaded" ) {
|
||||
o.onreadystatechange = null, o.attachEvent( "onreadystatechange", k ), n( o )
|
||||
}
|
||||
} : o.attachEvent( "onreadystatechange", k )) : o.addEventListener( "load", k, !1 ), o.src = a, n || d.addScriptToDom( o ), o;
|
||||
} else {
|
||||
ca && (importScripts( a ), c.completeLoad( h ));
|
||||
}
|
||||
return null
|
||||
};
|
||||
if ( G ) {
|
||||
u = document.getElementsByTagName( "script" );
|
||||
for ( H = u.length - 1; H > -1 && (z = u[H]); H-- ) {
|
||||
if ( !x ) {
|
||||
x = z.parentNode;
|
||||
}
|
||||
if ( A = z.getAttribute( "data-main" ) ) {
|
||||
if ( !r.baseUrl ) {
|
||||
u =
|
||||
A.split( "/" ), z = u.pop(), u = u.length ? u.join( "/" ) + "/" : "./", r.baseUrl = u, A = z.replace( aa, "" );
|
||||
}
|
||||
r.deps = r.deps ? r.deps.concat( A ) : [A];
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
d.checkReadyState = function () {
|
||||
var a = v.contexts, c;
|
||||
for ( c in a ) {
|
||||
if ( !(c in K) && a[c].waitCount ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
d.resourcesReady( !0 )
|
||||
};
|
||||
d.resourcesReady = function ( a ) {
|
||||
var c, h;
|
||||
d.resourcesDone = a;
|
||||
if ( d.resourcesDone ) {
|
||||
for ( h in a = v.contexts, a ) {
|
||||
if ( !(h in K) && (c = a[h], c.jQueryIncremented) ) {
|
||||
V( c.jQuery, !1 ), c.jQueryIncremented = !1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
d.pageLoaded = function () {
|
||||
if ( document.readyState !== "complete" ) {
|
||||
document.readyState =
|
||||
"complete"
|
||||
}
|
||||
};
|
||||
if ( G && document.addEventListener && !document.readyState ) {
|
||||
document.readyState = "loading", window.addEventListener( "load", d.pageLoaded, !1 );
|
||||
}
|
||||
d( r );
|
||||
if ( d.isAsync && typeof setTimeout !== "undefined" ) {
|
||||
B = v.contexts[r.context || "_"], B.requireWait = !0, setTimeout( function () {
|
||||
B.requireWait = !1;
|
||||
B.takeGlobalQueue();
|
||||
B.jQueryCheck();
|
||||
B.scriptCount || B.resume();
|
||||
d.checkReadyState()
|
||||
}, 0 )
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
711
example/amd/js/libs/underscore/underscore-min.js
vendored
711
example/amd/js/libs/underscore/underscore-min.js
vendored
|
|
@ -5,26 +5,691 @@
|
|||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore
|
||||
(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
|
||||
h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
|
||||
define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(b,a[e],e,a)===o)break}else for(e in a)if(m.call(a,e)&&c.call(b,a[e],e,a)===o)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.map===w)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=
|
||||
d!==void 0;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;
|
||||
D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});
|
||||
return e};var D=b.some=b.any=function(a,c,d){var c=c||b.identity,e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
|
||||
b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var c=[],b;
|
||||
j(a,function(a,f){f==0?c[0]=a:(b=Math.floor(Math.random()*(f+1)),c[f]=c[b],c[b]=a)});return c};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b<d?-1:b>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<
|
||||
f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||
|
||||
d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,
|
||||
true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(q&&a.indexOf===q)return a.indexOf(c);
|
||||
for(d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(C&&a.lastIndexOf===C)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};var E=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;
|
||||
e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));E.prototype=a.prototype;var b=new E,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return m.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
|
||||
function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=
|
||||
null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=i.call(arguments);return function(){for(var b=i.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==
|
||||
Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
|
||||
a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:
|
||||
function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};
|
||||
b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
|
||||
interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,
|
||||
"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,
|
||||
arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
|
||||
(function () {
|
||||
function r( a, c, d ) {
|
||||
if ( a === c ) {
|
||||
return a !== 0 || 1 / a == 1 / c;
|
||||
}
|
||||
if ( a == null || c == null ) {
|
||||
return a === c;
|
||||
}
|
||||
if ( a._chain ) {
|
||||
a = a._wrapped;
|
||||
}
|
||||
if ( c._chain ) {
|
||||
c = c._wrapped;
|
||||
}
|
||||
if ( b.isFunction( a.isEqual ) ) {
|
||||
return a.isEqual( c );
|
||||
}
|
||||
if ( b.isFunction( c.isEqual ) ) {
|
||||
return c.isEqual( a );
|
||||
}
|
||||
var e = l.call( a );
|
||||
if ( e != l.call( c ) ) {
|
||||
return false;
|
||||
}
|
||||
switch ( e ) {
|
||||
case "[object String]":
|
||||
return String( a ) == String( c );
|
||||
case "[object Number]":
|
||||
return a = +a, c = +c, a != a ? c != c : a == 0 ? 1 / a == 1 / c : a == c;
|
||||
case "[object Date]":
|
||||
case "[object Boolean]":
|
||||
return+a == +c;
|
||||
case "[object RegExp]":
|
||||
return a.source ==
|
||||
c.source && a.global == c.global && a.multiline == c.multiline && a.ignoreCase == c.ignoreCase
|
||||
}
|
||||
if ( typeof a != "object" || typeof c != "object" ) {
|
||||
return false;
|
||||
}
|
||||
for ( var f = d.length; f--; ) {
|
||||
if ( d[f] == a ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
d.push( a );
|
||||
var f = 0, g = true;
|
||||
if ( e == "[object Array]" ) {
|
||||
if ( f = a.length, g = f == c.length ) {
|
||||
for ( ; f--; ) {
|
||||
if ( !(g = f in a == f in c && r( a[f], c[f], d )) ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( "constructor"in a != "constructor"in c || a.constructor != c.constructor ) {
|
||||
return false;
|
||||
}
|
||||
for ( var h in a ) {
|
||||
if ( m.call( a, h ) && (f++, !(g = m.call( c, h ) && r( a[h], c[h], d ))) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( g ) {
|
||||
for ( h in c ) {
|
||||
if ( m.call( c,
|
||||
h ) && !f-- ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
g = !f
|
||||
}
|
||||
}
|
||||
d.pop();
|
||||
return g
|
||||
}
|
||||
|
||||
var s = this, F = s._, o = {}, k = Array.prototype, p = Object.prototype, i = k.slice, G = k.unshift, l = p.toString, m = p.hasOwnProperty, v = k.forEach, w = k.map, x = k.reduce, y = k.reduceRight, z = k.filter, A = k.every, B = k.some, q = k.indexOf, C = k.lastIndexOf, p = Array.isArray, H = Object.keys, t = Function.prototype.bind, b = function ( a ) {
|
||||
return new n( a )
|
||||
};
|
||||
if ( typeof exports !== "undefined" ) {
|
||||
if ( typeof module !== "undefined" && module.exports ) {
|
||||
exports = module.exports = b;
|
||||
}
|
||||
exports._ = b
|
||||
} else {
|
||||
typeof define === "function" && define.amd ?
|
||||
define( "underscore", function () {
|
||||
return b
|
||||
} ) : s._ = b;
|
||||
}
|
||||
b.VERSION = "1.2.2";
|
||||
var j = b.each = b.forEach = function ( a, c, b ) {
|
||||
if ( a != null ) {
|
||||
if ( v && a.forEach === v ) {
|
||||
a.forEach( c, b );
|
||||
} else if ( a.length === +a.length ) {
|
||||
for ( var e = 0, f = a.length; e < f; e++ ) {
|
||||
if ( e in a && c.call( b, a[e], e, a ) === o ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( e in a ) {
|
||||
if ( m.call( a, e ) && c.call( b, a[e], e, a ) === o ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
b.map = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( w && a.map === w ) {
|
||||
return a.map( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
e[e.length] = c.call( b, a, g, h )
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.reduce = b.foldl = b.inject = function ( a, c, d, e ) {
|
||||
var f =
|
||||
d !== void 0;
|
||||
a == null && (a = []);
|
||||
if ( x && a.reduce === x ) {
|
||||
return e && (c = b.bind( c, e )), f ? a.reduce( c, d ) : a.reduce( c );
|
||||
}
|
||||
j( a, function ( a, b, i ) {
|
||||
f ? d = c.call( e, d, a, b, i ) : (d = a, f = true)
|
||||
} );
|
||||
if ( !f ) {
|
||||
throw new TypeError( "Reduce of empty array with no initial value" );
|
||||
}
|
||||
return d
|
||||
};
|
||||
b.reduceRight = b.foldr = function ( a, c, d, e ) {
|
||||
a == null && (a = []);
|
||||
if ( y && a.reduceRight === y ) {
|
||||
return e && (c = b.bind( c, e )), d !== void 0 ? a.reduceRight( c, d ) : a.reduceRight( c );
|
||||
}
|
||||
a = (b.isArray( a ) ? a.slice() : b.toArray( a )).reverse();
|
||||
return b.reduce( a, c, d, e )
|
||||
};
|
||||
b.find = b.detect = function ( a, c, b ) {
|
||||
var e;
|
||||
D( a, function ( a, g, h ) {
|
||||
if ( c.call( b, a, g, h ) ) {
|
||||
return e = a, true
|
||||
}
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.filter = b.select = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( z && a.filter === z ) {
|
||||
return a.filter( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
c.call( b, a, g, h ) && (e[e.length] = a)
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.reject = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
c.call( b, a, g, h ) || (e[e.length] = a)
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.every = b.all = function ( a, c, b ) {
|
||||
var e = true;
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( A && a.every === A ) {
|
||||
return a.every( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
if ( !(e = e && c.call( b, a, g, h )) ) {
|
||||
return o
|
||||
}
|
||||
} );
|
||||
return e
|
||||
};
|
||||
var D = b.some = b.any = function ( a, c, d ) {
|
||||
var c = c || b.identity, e = false;
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( B && a.some === B ) {
|
||||
return a.some( c, d );
|
||||
}
|
||||
j( a, function ( a, b, h ) {
|
||||
if ( e || (e = c.call( d, a, b, h )) ) {
|
||||
return o
|
||||
}
|
||||
} );
|
||||
return!!e
|
||||
};
|
||||
b.include = b.contains = function ( a, c ) {
|
||||
var b = false;
|
||||
if ( a == null ) {
|
||||
return b;
|
||||
}
|
||||
return q && a.indexOf === q ? a.indexOf( c ) != -1 : b = D( a, function ( a ) {
|
||||
return a === c
|
||||
} )
|
||||
};
|
||||
b.invoke = function ( a, c ) {
|
||||
var d = i.call( arguments, 2 );
|
||||
return b.map( a, function ( a ) {
|
||||
return(c.call ? c || a : a[c]).apply( a, d )
|
||||
} )
|
||||
};
|
||||
b.pluck = function ( a, c ) {
|
||||
return b.map( a, function ( a ) {
|
||||
return a[c]
|
||||
} )
|
||||
};
|
||||
b.max = function ( a, c, d ) {
|
||||
if ( !c && b.isArray( a ) ) {
|
||||
return Math.max.apply( Math, a );
|
||||
}
|
||||
if ( !c && b.isEmpty( a ) ) {
|
||||
return-Infinity;
|
||||
}
|
||||
var e = {computed : -Infinity};
|
||||
j( a, function ( a, b, h ) {
|
||||
b = c ? c.call( d, a, b, h ) : a;
|
||||
b >= e.computed && (e = {value : a, computed : b})
|
||||
} );
|
||||
return e.value
|
||||
};
|
||||
b.min = function ( a, c, d ) {
|
||||
if ( !c && b.isArray( a ) ) {
|
||||
return Math.min.apply( Math, a );
|
||||
}
|
||||
if ( !c && b.isEmpty( a ) ) {
|
||||
return Infinity;
|
||||
}
|
||||
var e = {computed : Infinity};
|
||||
j( a, function ( a, b, h ) {
|
||||
b = c ? c.call( d, a, b, h ) : a;
|
||||
b < e.computed && (e = {value : a, computed : b})
|
||||
} );
|
||||
return e.value
|
||||
};
|
||||
b.shuffle = function ( a ) {
|
||||
var c = [], b;
|
||||
j( a, function ( a, f ) {
|
||||
f == 0 ? c[0] = a : (b = Math.floor( Math.random() * (f + 1) ), c[f] = c[b], c[b] = a)
|
||||
} );
|
||||
return c
|
||||
};
|
||||
b.sortBy = function ( a, c, d ) {
|
||||
return b.pluck( b.map( a,
|
||||
function ( a, b, g ) {
|
||||
return{value : a, criteria : c.call( d, a, b, g )}
|
||||
} ).sort( function ( a, c ) {
|
||||
var b = a.criteria, d = c.criteria;
|
||||
return b < d ? -1 : b > d ? 1 : 0
|
||||
} ), "value" )
|
||||
};
|
||||
b.groupBy = function ( a, c ) {
|
||||
var d = {}, e = b.isFunction( c ) ? c : function ( a ) {
|
||||
return a[c]
|
||||
};
|
||||
j( a, function ( a, c ) {
|
||||
var b = e( a, c );
|
||||
(d[b] || (d[b] = [])).push( a )
|
||||
} );
|
||||
return d
|
||||
};
|
||||
b.sortedIndex = function ( a, c, d ) {
|
||||
d || (d = b.identity);
|
||||
for ( var e = 0, f = a.length; e <
|
||||
f; ) {
|
||||
var g = e + f >> 1;
|
||||
d( a[g] ) < d( c ) ? e = g + 1 : f = g
|
||||
}
|
||||
return e
|
||||
};
|
||||
b.toArray = function ( a ) {
|
||||
return!a ? [] : a.toArray ? a.toArray() : b.isArray( a ) ? i.call( a ) : b.isArguments( a ) ? i.call( a ) : b.values( a )
|
||||
};
|
||||
b.size = function ( a ) {
|
||||
return b.toArray( a ).length
|
||||
};
|
||||
b.first = b.head = function ( a, b, d ) {
|
||||
return b != null && !d ? i.call( a, 0, b ) : a[0]
|
||||
};
|
||||
b.initial = function ( a, b, d ) {
|
||||
return i.call( a, 0, a.length - (b == null || d ? 1 : b) )
|
||||
};
|
||||
b.last = function ( a, b, d ) {
|
||||
return b != null && !d ? i.call( a, Math.max( a.length - b, 0 ) ) : a[a.length - 1]
|
||||
};
|
||||
b.rest = b.tail = function ( a, b, d ) {
|
||||
return i.call( a, b == null ||
|
||||
d ? 1 : b )
|
||||
};
|
||||
b.compact = function ( a ) {
|
||||
return b.filter( a, function ( a ) {
|
||||
return!!a
|
||||
} )
|
||||
};
|
||||
b.flatten = function ( a, c ) {
|
||||
return b.reduce( a, function ( a, e ) {
|
||||
if ( b.isArray( e ) ) {
|
||||
return a.concat( c ? e : b.flatten( e ) );
|
||||
}
|
||||
a[a.length] = e;
|
||||
return a
|
||||
}, [] )
|
||||
};
|
||||
b.without = function ( a ) {
|
||||
return b.difference( a, i.call( arguments, 1 ) )
|
||||
};
|
||||
b.uniq = b.unique = function ( a, c, d ) {
|
||||
var d = d ? b.map( a, d ) : a, e = [];
|
||||
b.reduce( d, function ( d, g, h ) {
|
||||
if ( 0 == h || (c === true ? b.last( d ) != g : !b.include( d, g )) ) {
|
||||
d[d.length] = g, e[e.length] = a[h];
|
||||
}
|
||||
return d
|
||||
}, [] );
|
||||
return e
|
||||
};
|
||||
b.union = function () {
|
||||
return b.uniq( b.flatten( arguments,
|
||||
true ) )
|
||||
};
|
||||
b.intersection = b.intersect = function ( a ) {
|
||||
var c = i.call( arguments, 1 );
|
||||
return b.filter( b.uniq( a ), function ( a ) {
|
||||
return b.every( c, function ( c ) {
|
||||
return b.indexOf( c, a ) >= 0
|
||||
} )
|
||||
} )
|
||||
};
|
||||
b.difference = function ( a, c ) {
|
||||
return b.filter( a, function ( a ) {
|
||||
return!b.include( c, a )
|
||||
} )
|
||||
};
|
||||
b.zip = function () {
|
||||
for ( var a = i.call( arguments ), c = b.max( b.pluck( a, "length" ) ), d = Array( c ), e = 0; e < c; e++ ) {
|
||||
d[e] = b.pluck( a, "" + e );
|
||||
}
|
||||
return d
|
||||
};
|
||||
b.indexOf = function ( a, c, d ) {
|
||||
if ( a == null ) {
|
||||
return-1;
|
||||
}
|
||||
var e;
|
||||
if ( d ) {
|
||||
return d = b.sortedIndex( a, c ), a[d] === c ? d : -1;
|
||||
}
|
||||
if ( q && a.indexOf === q ) {
|
||||
return a.indexOf( c );
|
||||
}
|
||||
for ( d = 0, e = a.length; d < e; d++ ) {
|
||||
if ( a[d] === c ) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return-1
|
||||
};
|
||||
b.lastIndexOf = function ( a, b ) {
|
||||
if ( a == null ) {
|
||||
return-1;
|
||||
}
|
||||
if ( C && a.lastIndexOf === C ) {
|
||||
return a.lastIndexOf( b );
|
||||
}
|
||||
for ( var d = a.length; d--; ) {
|
||||
if ( a[d] === b ) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return-1
|
||||
};
|
||||
b.range = function ( a, b, d ) {
|
||||
arguments.length <= 1 && (b = a || 0, a = 0);
|
||||
for ( var d = arguments[2] || 1, e = Math.max( Math.ceil( (b - a) / d ), 0 ), f = 0, g = Array( e ); f < e; ) {
|
||||
g[f++] = a, a += d;
|
||||
}
|
||||
return g
|
||||
};
|
||||
var E = function () {
|
||||
};
|
||||
b.bind = function ( a, c ) {
|
||||
var d, e;
|
||||
if ( a.bind === t && t ) {
|
||||
return t.apply( a, i.call( arguments, 1 ) );
|
||||
}
|
||||
if ( !b.isFunction( a ) ) {
|
||||
throw new TypeError;
|
||||
}
|
||||
e = i.call( arguments, 2 );
|
||||
return d = function () {
|
||||
if ( !(this instanceof d) ) {
|
||||
return a.apply( c, e.concat( i.call( arguments ) ) );
|
||||
}
|
||||
E.prototype = a.prototype;
|
||||
var b = new E, g = a.apply( b, e.concat( i.call( arguments ) ) );
|
||||
return Object( g ) === g ? g : b
|
||||
}
|
||||
};
|
||||
b.bindAll = function ( a ) {
|
||||
var c = i.call( arguments, 1 );
|
||||
c.length == 0 && (c = b.functions( a ));
|
||||
j( c, function ( c ) {
|
||||
a[c] = b.bind( a[c], a )
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.memoize = function ( a, c ) {
|
||||
var d = {};
|
||||
c || (c = b.identity);
|
||||
return function () {
|
||||
var b = c.apply( this, arguments );
|
||||
return m.call( d, b ) ? d[b] : d[b] = a.apply( this, arguments )
|
||||
}
|
||||
};
|
||||
b.delay =
|
||||
function ( a, b ) {
|
||||
var d = i.call( arguments, 2 );
|
||||
return setTimeout( function () {
|
||||
return a.apply( a, d )
|
||||
}, b )
|
||||
};
|
||||
b.defer = function ( a ) {
|
||||
return b.delay.apply( b, [a, 1].concat( i.call( arguments, 1 ) ) )
|
||||
};
|
||||
b.throttle = function ( a, c ) {
|
||||
var d, e, f, g, h, i = b.debounce( function () {
|
||||
h = g = false
|
||||
}, c );
|
||||
return function () {
|
||||
d = this;
|
||||
e = arguments;
|
||||
var b;
|
||||
f || (f = setTimeout( function () {
|
||||
f = null;
|
||||
h && a.apply( d, e );
|
||||
i()
|
||||
}, c ));
|
||||
g ? h = true : a.apply( d, e );
|
||||
i();
|
||||
g = true
|
||||
}
|
||||
};
|
||||
b.debounce = function ( a, b ) {
|
||||
var d;
|
||||
return function () {
|
||||
var e = this, f = arguments;
|
||||
clearTimeout( d );
|
||||
d = setTimeout( function () {
|
||||
d =
|
||||
null;
|
||||
a.apply( e, f )
|
||||
}, b )
|
||||
}
|
||||
};
|
||||
b.once = function ( a ) {
|
||||
var b = false, d;
|
||||
return function () {
|
||||
if ( b ) {
|
||||
return d;
|
||||
}
|
||||
b = true;
|
||||
return d = a.apply( this, arguments )
|
||||
}
|
||||
};
|
||||
b.wrap = function ( a, b ) {
|
||||
return function () {
|
||||
var d = [a].concat( i.call( arguments ) );
|
||||
return b.apply( this, d )
|
||||
}
|
||||
};
|
||||
b.compose = function () {
|
||||
var a = i.call( arguments );
|
||||
return function () {
|
||||
for ( var b = i.call( arguments ), d = a.length - 1; d >= 0; d-- ) {
|
||||
b = [a[d].apply( this, b )];
|
||||
}
|
||||
return b[0]
|
||||
}
|
||||
};
|
||||
b.after = function ( a, b ) {
|
||||
return a <= 0 ? b() : function () {
|
||||
if ( --a < 1 ) {
|
||||
return b.apply( this, arguments )
|
||||
}
|
||||
}
|
||||
};
|
||||
b.keys = H || function ( a ) {
|
||||
if ( a !==
|
||||
Object( a ) ) {
|
||||
throw new TypeError( "Invalid object" );
|
||||
}
|
||||
var b = [], d;
|
||||
for ( d in a ) {
|
||||
m.call( a, d ) && (b[b.length] = d);
|
||||
}
|
||||
return b
|
||||
};
|
||||
b.values = function ( a ) {
|
||||
return b.map( a, b.identity )
|
||||
};
|
||||
b.functions = b.methods = function ( a ) {
|
||||
var c = [], d;
|
||||
for ( d in a ) {
|
||||
b.isFunction( a[d] ) && c.push( d );
|
||||
}
|
||||
return c.sort()
|
||||
};
|
||||
b.extend = function ( a ) {
|
||||
j( i.call( arguments, 1 ), function ( b ) {
|
||||
for ( var d in b ) {
|
||||
b[d] !== void 0 && (a[d] = b[d])
|
||||
}
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.defaults = function ( a ) {
|
||||
j( i.call( arguments, 1 ), function ( b ) {
|
||||
for ( var d in b ) {
|
||||
a[d] == null && (a[d] = b[d])
|
||||
}
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.clone = function ( a ) {
|
||||
return!b.isObject( a ) ?
|
||||
a : b.isArray( a ) ? a.slice() : b.extend( {}, a )
|
||||
};
|
||||
b.tap = function ( a, b ) {
|
||||
b( a );
|
||||
return a
|
||||
};
|
||||
b.isEqual = function ( a, b ) {
|
||||
return r( a, b, [] )
|
||||
};
|
||||
b.isEmpty = function ( a ) {
|
||||
if ( b.isArray( a ) || b.isString( a ) ) {
|
||||
return a.length === 0;
|
||||
}
|
||||
for ( var c in a ) {
|
||||
if ( m.call( a, c ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
};
|
||||
b.isElement = function ( a ) {
|
||||
return!!(a && a.nodeType == 1)
|
||||
};
|
||||
b.isArray = p || function ( a ) {
|
||||
return l.call( a ) == "[object Array]"
|
||||
};
|
||||
b.isObject = function ( a ) {
|
||||
return a === Object( a )
|
||||
};
|
||||
b.isArguments = l.call( arguments ) == "[object Arguments]" ? function ( a ) {
|
||||
return l.call( a ) == "[object Arguments]"
|
||||
} :
|
||||
function ( a ) {
|
||||
return!(!a || !m.call( a, "callee" ))
|
||||
};
|
||||
b.isFunction = function ( a ) {
|
||||
return l.call( a ) == "[object Function]"
|
||||
};
|
||||
b.isString = function ( a ) {
|
||||
return l.call( a ) == "[object String]"
|
||||
};
|
||||
b.isNumber = function ( a ) {
|
||||
return l.call( a ) == "[object Number]"
|
||||
};
|
||||
b.isNaN = function ( a ) {
|
||||
return a !== a
|
||||
};
|
||||
b.isBoolean = function ( a ) {
|
||||
return a === true || a === false || l.call( a ) == "[object Boolean]"
|
||||
};
|
||||
b.isDate = function ( a ) {
|
||||
return l.call( a ) == "[object Date]"
|
||||
};
|
||||
b.isRegExp = function ( a ) {
|
||||
return l.call( a ) == "[object RegExp]"
|
||||
};
|
||||
b.isNull = function ( a ) {
|
||||
return a === null
|
||||
};
|
||||
b.isUndefined = function ( a ) {
|
||||
return a === void 0
|
||||
};
|
||||
b.noConflict = function () {
|
||||
s._ = F;
|
||||
return this
|
||||
};
|
||||
b.identity = function ( a ) {
|
||||
return a
|
||||
};
|
||||
b.times = function ( a, b, d ) {
|
||||
for ( var e = 0; e < a; e++ ) {
|
||||
b.call( d, e )
|
||||
}
|
||||
};
|
||||
b.escape = function ( a ) {
|
||||
return("" + a).replace( /&/g, "&" ).replace( /</g, "<" ).replace( />/g, ">" ).replace( /"/g, """ ).replace( /'/g, "'" ).replace( /\//g, "/" )
|
||||
};
|
||||
b.mixin = function ( a ) {
|
||||
j( b.functions( a ), function ( c ) {
|
||||
I( c, b[c] = a[c] )
|
||||
} )
|
||||
};
|
||||
var J = 0;
|
||||
b.uniqueId = function ( a ) {
|
||||
var b = J++;
|
||||
return a ? a + b : b
|
||||
};
|
||||
b.templateSettings = {evaluate : /<%([\s\S]+?)%>/g,
|
||||
interpolate : /<%=([\s\S]+?)%>/g, escape : /<%-([\s\S]+?)%>/g};
|
||||
b.template = function ( a, c ) {
|
||||
var d = b.templateSettings, d = "var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('" + a.replace( /\\/g, "\\\\" ).replace( /'/g, "\\'" ).replace( d.escape,
|
||||
function ( a, b ) {
|
||||
return"',_.escape(" + b.replace( /\\'/g, "'" ) + "),'"
|
||||
} ).replace( d.interpolate,
|
||||
function ( a, b ) {
|
||||
return"'," + b.replace( /\\'/g, "'" ) + ",'"
|
||||
} ).replace( d.evaluate || null,
|
||||
function ( a, b ) {
|
||||
return"');" + b.replace( /\\'/g, "'" ).replace( /[\r\n\t]/g, " " ) + ";__p.push('"
|
||||
} ).replace( /\r/g,
|
||||
"\\r" ).replace( /\n/g, "\\n" ).replace( /\t/g, "\\t" ) + "');}return __p.join('');", e = new Function( "obj", "_", d );
|
||||
return c ? e( c, b ) : function ( a ) {
|
||||
return e( a, b )
|
||||
}
|
||||
};
|
||||
var n = function ( a ) {
|
||||
this._wrapped = a
|
||||
};
|
||||
b.prototype = n.prototype;
|
||||
var u = function ( a, c ) {
|
||||
return c ? b( a ).chain() : a
|
||||
}, I = function ( a, c ) {
|
||||
n.prototype[a] = function () {
|
||||
var a = i.call( arguments );
|
||||
G.call( a, this._wrapped );
|
||||
return u( c.apply( b, a ), this._chain )
|
||||
}
|
||||
};
|
||||
b.mixin( b );
|
||||
j( "pop,push,reverse,shift,sort,splice,unshift".split( "," ), function ( a ) {
|
||||
var b = k[a];
|
||||
n.prototype[a] = function () {
|
||||
b.apply( this._wrapped,
|
||||
arguments );
|
||||
return u( this._wrapped, this._chain )
|
||||
}
|
||||
} );
|
||||
j( ["concat", "join", "slice"], function ( a ) {
|
||||
var b = k[a];
|
||||
n.prototype[a] = function () {
|
||||
return u( b.apply( this._wrapped, arguments ), this._chain )
|
||||
}
|
||||
} );
|
||||
n.prototype.chain = function () {
|
||||
this._chain = true;
|
||||
return this
|
||||
};
|
||||
n.prototype.value = function () {
|
||||
return this._wrapped
|
||||
}
|
||||
}).call( this );
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
require.config({
|
||||
paths: {
|
||||
underscore: 'libs/underscore/underscore-min',
|
||||
postal: 'libs/postal/postal',
|
||||
postaldiags:'libs/postal/postal.diagnostics',
|
||||
jquery: 'libs/jquery/jquery-min'
|
||||
require.config( {
|
||||
paths : {
|
||||
underscore : 'libs/underscore/underscore-min',
|
||||
postal : 'libs/postal/postal',
|
||||
postaldiags : 'libs/postal/postal.diagnostics',
|
||||
jquery : 'libs/jquery/jquery-min'
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
require( [ 'jquery' ], function( $ ){
|
||||
$(function(){
|
||||
require( [ 'jquery' ], function ( $ ) {
|
||||
$( function () {
|
||||
require( [ 'examples' ] );
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -4,7 +4,7 @@ div {
|
|||
}
|
||||
|
||||
.results {
|
||||
margin-bottom:20px;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
border-top: 1pt solid lightsteelblue;
|
||||
border-bottom: 1pt solid lightsteelblue;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Twitter Hash Tag Stats Demo</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||
<title>Twitter Hash Tag Stats Demo</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script data-main="js/main" src="js/lib/require-jquery.js"></script>
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
define([
|
||||
define( [
|
||||
'jquery',
|
||||
'backbone',
|
||||
'bus',
|
||||
|
|
@ -12,41 +12,40 @@ define([
|
|||
'views/hash-tag-count',
|
||||
'views/profanity-percentage',
|
||||
'views/search-requests'
|
||||
], function( $, Backbone, bus, Router, ViewManager, ContainerView, MenuView, TweetCountView, MentionCountView,
|
||||
MentionerCountView, HashTagCountView, ProfanityPercentage, SearchRequestView ) {
|
||||
], function ( $, Backbone, bus, Router, ViewManager, ContainerView, MenuView, TweetCountView, MentionCountView, MentionerCountView, HashTagCountView, ProfanityPercentage, SearchRequestView ) {
|
||||
var app = {
|
||||
bus: bus,
|
||||
router: new Router()
|
||||
bus : bus,
|
||||
router : new Router()
|
||||
};
|
||||
|
||||
// Set up UI concerns
|
||||
app.viewManager = new ViewManager();
|
||||
app.bus.viewManager.subscribe( "ui.show", function( data, env ) {
|
||||
app.bus.viewManager.subscribe( "ui.show", function ( data, env ) {
|
||||
app.viewManager.UI[ data.name ].activate( data.context );
|
||||
});
|
||||
} );
|
||||
|
||||
app.viewManager.registerViews([
|
||||
{ name: "container", ctor: ContainerView },
|
||||
{ name: "menu", ctor: MenuView },
|
||||
{ name: "tweetCount", ctor: TweetCountView },
|
||||
{ name: "mentionCount", ctor: MentionCountView },
|
||||
{ name: "mentionerCount", ctor: MentionerCountView },
|
||||
{ name: "hashTagCount", ctor: HashTagCountView },
|
||||
{ name: "profanityPercentage", ctor: ProfanityPercentage },
|
||||
{ name: "searchRequests", ctor: SearchRequestView }
|
||||
]);
|
||||
app.viewManager.defineUIs([
|
||||
{ name: "homeUI", dependencies: [ "container", "menu", "tweetCount", "mentionCount", "mentionerCount", "hashTagCount", "profanityPercentage" ] },
|
||||
{ name: "searchRequestUI", dependencies: [ "container", "menu", "searchRequests" ] },
|
||||
{ name: "wireTapLogUI", dependencies: [ "menu" ], options: { noHide: true } }
|
||||
]);
|
||||
app.viewManager.registerViews( [
|
||||
{ name : "container", ctor : ContainerView },
|
||||
{ name : "menu", ctor : MenuView },
|
||||
{ name : "tweetCount", ctor : TweetCountView },
|
||||
{ name : "mentionCount", ctor : MentionCountView },
|
||||
{ name : "mentionerCount", ctor : MentionerCountView },
|
||||
{ name : "hashTagCount", ctor : HashTagCountView },
|
||||
{ name : "profanityPercentage", ctor : ProfanityPercentage },
|
||||
{ name : "searchRequests", ctor : SearchRequestView }
|
||||
] );
|
||||
app.viewManager.defineUIs( [
|
||||
{ name : "homeUI", dependencies : [ "container", "menu", "tweetCount", "mentionCount", "mentionerCount", "hashTagCount", "profanityPercentage" ] },
|
||||
{ name : "searchRequestUI", dependencies : [ "container", "menu", "searchRequests" ] },
|
||||
{ name : "wireTapLogUI", dependencies : [ "menu" ], options : { noHide : true } }
|
||||
] );
|
||||
|
||||
$(function() {
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: $( "base" ).attr( "href" )
|
||||
});
|
||||
});
|
||||
$( function () {
|
||||
Backbone.history.start( {
|
||||
pushState : true,
|
||||
root : $( "base" ).attr( "href" )
|
||||
} );
|
||||
} );
|
||||
|
||||
return app;
|
||||
});
|
||||
} );
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
define([
|
||||
define( [
|
||||
'postal'
|
||||
], function ( postal ) {
|
||||
return {
|
||||
router : postal.channel( "router", "*" ),
|
||||
router : postal.channel( "router", "*" ),
|
||||
viewManager : postal.channel( "viewmanager", "*" ),
|
||||
data : postal.channel( "data", "*" ),
|
||||
app : postal.channel( "statsApp", "*", { type: "websocket" } ),
|
||||
stats : postal.channel( "stats", "*", { type: "websocket" } )
|
||||
data : postal.channel( "data", "*" ),
|
||||
app : postal.channel( "statsApp", "*", { type : "websocket" } ),
|
||||
stats : postal.channel( "stats", "*", { type : "websocket" } )
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
|
@ -1,315 +1,298 @@
|
|||
/*
|
||||
postal.socket
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
/*
|
||||
postal.socket
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
|
||||
(function( root, doc, factory ) {
|
||||
(function ( root, doc, factory ) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define( [ "underscore", "machina", "postal" ], function( _, machina, postal ) {
|
||||
define( [ "underscore", "machina", "postal" ], function ( _, machina, postal ) {
|
||||
return factory( _, machina, postal, root, doc );
|
||||
});
|
||||
} );
|
||||
} else {
|
||||
// Browser globals
|
||||
factory( root._, root.machina, root.postal, root, doc );
|
||||
}
|
||||
}(this, document, function( _, machina, postal, global, document, undefined ) {
|
||||
}( this, document, function ( _, machina, postal, global, document, undefined ) {
|
||||
|
||||
/*
|
||||
adding a socket namespace to postal
|
||||
which provides the following members:
|
||||
1.) config - provides values used to manage the socket connection
|
||||
2.) goOffline() - tells the manager to close the connection intentionally
|
||||
3.) goOnline() - tells the manager to try to connect.
|
||||
4.) manifest - an array of objects describing the subscriptions that have been
|
||||
set up on the remote end.
|
||||
5.) publish() - takes a valid postal envelope and pushes it through the socket
|
||||
to be published to the server instance of postal.
|
||||
6.) socketMgr - the FSM managing the socket connection
|
||||
7.) socketNamespace - exposed currently for debugging only
|
||||
8.) subscribe() - passes an object through the socket to the server
|
||||
which contains data necessary to set up a remote subscription. The
|
||||
options passed to the socket would look similar to this:
|
||||
{
|
||||
"channel":"SomeChannel",
|
||||
"topic":"my.topic",
|
||||
"correlationId":"2073383865318591267"
|
||||
}
|
||||
The "correlationId" is used on the remote side to apply a constraint to
|
||||
the subscription, enabling just this specific client to be targeted on
|
||||
and otherwise public channel.
|
||||
9.) unsubscribe() - passes an object through the socket to the server
|
||||
which contains data necessary to remove a remote subscription. The options
|
||||
passed would look similar to the example above in #8.
|
||||
adding a socket namespace to postal
|
||||
which provides the following members:
|
||||
1.) config - provides values used to manage the socket connection
|
||||
2.) goOffline() - tells the manager to close the connection intentionally
|
||||
3.) goOnline() - tells the manager to try to connect.
|
||||
4.) manifest - an array of objects describing the subscriptions that have been
|
||||
set up on the remote end.
|
||||
5.) publish() - takes a valid postal envelope and pushes it through the socket
|
||||
to be published to the server instance of postal.
|
||||
6.) socketMgr - the FSM managing the socket connection
|
||||
7.) socketNamespace - exposed currently for debugging only
|
||||
8.) subscribe() - passes an object through the socket to the server
|
||||
which contains data necessary to set up a remote subscription. The
|
||||
options passed to the socket would look similar to this:
|
||||
{
|
||||
"channel":"SomeChannel",
|
||||
"topic":"my.topic",
|
||||
"correlationId":"2073383865318591267"
|
||||
}
|
||||
The "correlationId" is used on the remote side to apply a constraint to
|
||||
the subscription, enabling just this specific client to be targeted on
|
||||
and otherwise public channel.
|
||||
9.) unsubscribe() - passes an object through the socket to the server
|
||||
which contains data necessary to remove a remote subscription. The options
|
||||
passed would look similar to the example above in #8.
|
||||
*/
|
||||
postal.connections = postal.connections || {};
|
||||
|
||||
var postalSocket = postal.connections.socket = (function(){
|
||||
|
||||
var postalSocket = postal.connections.socket = (function () {
|
||||
var socketNamespace,
|
||||
fsm = new machina.Fsm({
|
||||
retryFn: undefined,
|
||||
|
||||
session: undefined,
|
||||
|
||||
wireUpSocketEvents: function() {
|
||||
fsm = new machina.Fsm( {
|
||||
retryFn : undefined,
|
||||
|
||||
session : undefined,
|
||||
|
||||
wireUpSocketEvents : function () {
|
||||
var self = this;
|
||||
_.each([ "connect", "connecting", "connect_failed", "disconnect", "reconnect", "reconnect_failed",
|
||||
"reconnecting", "postal.socket.remote", "postal.socket.identified", "postal.socket.migration" ],
|
||||
function( evnt ) {
|
||||
socketNamespace.on( evnt, function( data ) {
|
||||
_.each( [ "connect", "connecting", "connect_failed", "disconnect", "reconnect", "reconnect_failed",
|
||||
"reconnecting", "postal.socket.remote", "postal.socket.identified", "postal.socket.migration" ],
|
||||
function ( evnt ) {
|
||||
socketNamespace.on( evnt, function ( data ) {
|
||||
self.handle( evnt, data );
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
},
|
||||
|
||||
states: {
|
||||
uninitialized: {
|
||||
tryConnect: function() {
|
||||
this.transition("initializing");
|
||||
|
||||
states : {
|
||||
uninitialized : {
|
||||
tryConnect : function () {
|
||||
this.transition( "initializing" );
|
||||
}
|
||||
},
|
||||
initializing: {
|
||||
_onEnter: function() {
|
||||
socketNamespace = io.connect(postalSocket.config.url, { "auto connect": false });
|
||||
initializing : {
|
||||
_onEnter : function () {
|
||||
socketNamespace = io.connect( postalSocket.config.url, { "auto connect" : false } );
|
||||
this.wireUpSocketEvents();
|
||||
this.transition("probing")
|
||||
this.transition( "probing" )
|
||||
},
|
||||
socketTransmit: function() {
|
||||
this.deferUntilTransition("online");
|
||||
socketTransmit : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
}
|
||||
},
|
||||
probing: {
|
||||
_onEnter: function() {
|
||||
clearTimeout(this.retryFn);
|
||||
if(!socketNamespace.socket.connecting && !socketNamespace.socket.reconnecting) {
|
||||
probing : {
|
||||
_onEnter : function () {
|
||||
clearTimeout( this.retryFn );
|
||||
if ( !socketNamespace.socket.connecting && !socketNamespace.socket.reconnecting ) {
|
||||
socketNamespace.socket.connect();
|
||||
}
|
||||
else {
|
||||
this.transition("settingSessionInfo");
|
||||
this.transition( "settingSessionInfo" );
|
||||
}
|
||||
},
|
||||
connect: function(){
|
||||
this.transition("settingSessionInfo");
|
||||
connect : function () {
|
||||
this.transition( "settingSessionInfo" );
|
||||
},
|
||||
connect_failed: function() {
|
||||
this.transition("disconnected");
|
||||
connect_failed : function () {
|
||||
this.transition( "disconnected" );
|
||||
},
|
||||
maxAttempts: function() {
|
||||
this.transition("offline");
|
||||
maxAttempts : function () {
|
||||
this.transition( "offline" );
|
||||
},
|
||||
"postal.socket.remote" : function() {
|
||||
this.deferUntilTransition("online");
|
||||
"postal.socket.remote" : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
},
|
||||
reconnect: function(){
|
||||
this.transition("settingSessionInfo");
|
||||
reconnect : function () {
|
||||
this.transition( "settingSessionInfo" );
|
||||
},
|
||||
reconnect_failed: function() {
|
||||
this.transition("disconnected");
|
||||
reconnect_failed : function () {
|
||||
this.transition( "disconnected" );
|
||||
},
|
||||
socketTransmit: function() {
|
||||
this.deferUntilTransition("online");
|
||||
socketTransmit : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
}
|
||||
},
|
||||
settingSessionInfo: {
|
||||
_onEnter: function() {
|
||||
settingSessionInfo : {
|
||||
_onEnter : function () {
|
||||
var self = this;
|
||||
postal.utils.getSessionId( function( session ) {
|
||||
if( !session || !session.id ) {
|
||||
self.handle("useFallbackSessionId" );
|
||||
} else {
|
||||
self.session = session;
|
||||
self.transition("identifying");
|
||||
}
|
||||
});
|
||||
},
|
||||
useFallbackSessionId : function () {
|
||||
var self = this;
|
||||
postal.utils.setSessionId( socketNamespace.socket.sessionid , function( session ) {
|
||||
postal.utils.setSessionId( socketNamespace.socket.sessionid, function ( session ) {
|
||||
self.session = session;
|
||||
self.transition("identifying");
|
||||
});
|
||||
self.transition( "identifying" );
|
||||
} );
|
||||
}
|
||||
},
|
||||
identifying: {
|
||||
_onEnter: function() {
|
||||
identifying : {
|
||||
_onEnter : function () {
|
||||
var self = this;
|
||||
self.retryFn = setTimeout(function() {
|
||||
self.retryFn = setTimeout( function () {
|
||||
self.handle( "timeout.identifying" );
|
||||
},postalSocket.config.reconnectInterval );
|
||||
}, postalSocket.config.reconnectInterval );
|
||||
self.handle( "client.identifier" );
|
||||
},
|
||||
"client.identifier" : function() {
|
||||
"client.identifier" : function () {
|
||||
clearTimeout( this.retryFn );
|
||||
socketNamespace.emit( "postal.clientId", { sessionId: this.session.id, lastSessionId: this.session.lastId } );
|
||||
socketNamespace.emit( "postal.clientId", { id : this.session.id, lastId : this.session.lastId } );
|
||||
},
|
||||
"postal.session.changed" : function() {
|
||||
socketNamespace.socket.disconnect();
|
||||
connect_failed : function () {
|
||||
this.transition( "disconnected" );
|
||||
},
|
||||
connect_failed: function() {
|
||||
this.transition("disconnected");
|
||||
disconnect : function () {
|
||||
this.transition( "probing" );
|
||||
},
|
||||
disconnect: function() {
|
||||
this.transition("probing");
|
||||
"postal.socket.identified" : function ( data ) {
|
||||
this.transition( "online" );
|
||||
},
|
||||
"postal.socket.identified" : function( data ) {
|
||||
this.transition("online");
|
||||
},
|
||||
"postal.socket.migration" : function() {
|
||||
_.each(postal.socket.manifest, function( sub ) {
|
||||
"postal.socket.migration" : function () {
|
||||
_.each( postal.connections.socket.manifest, function ( sub ) {
|
||||
fsm.handle( "socketTransmit", "postal.subscribe", sub );
|
||||
});
|
||||
} );
|
||||
socketNamespace.emit( "postal.migrationComplete", {} );
|
||||
},
|
||||
"postal.socket.remote" : function() {
|
||||
this.deferUntilTransition("online");
|
||||
"postal.socket.remote" : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
},
|
||||
reconnect_failed: function() {
|
||||
this.transition("disconnected");
|
||||
reconnect_failed : function () {
|
||||
this.transition( "disconnected" );
|
||||
},
|
||||
socketTransmit: function( evntName, envelope ) {
|
||||
if( evntName === "postal.subscribe" ){
|
||||
socketTransmit : function ( evntName, envelope ) {
|
||||
if ( evntName === "postal.subscribe" ) {
|
||||
// we risk mutating the message here, so extend
|
||||
// and add the correlationId to the extended copy
|
||||
var socketEnv = _.extend( {}, envelope );
|
||||
socketEnv.correlationId = this.session.id;
|
||||
socketNamespace.emit(evntName, socketEnv);
|
||||
socketNamespace.emit( evntName, socketEnv );
|
||||
}
|
||||
else {
|
||||
this.deferUntilTransition("online");
|
||||
this.deferUntilTransition( "online" );
|
||||
}
|
||||
},
|
||||
"timeout.identifying" : function() {
|
||||
this.transition("probing");
|
||||
"timeout.identifying" : function () {
|
||||
this.transition( "probing" );
|
||||
}
|
||||
},
|
||||
online: {
|
||||
disconnect: function() {
|
||||
this.transition("probing");
|
||||
online : {
|
||||
disconnect : function () {
|
||||
this.transition( "probing" );
|
||||
},
|
||||
"postal.session.changed" : function() {
|
||||
socketNamespace.socket.disconnect();
|
||||
goOffline : function () {
|
||||
this.transition( "offline" );
|
||||
},
|
||||
goOffline: function() {
|
||||
this.transition("offline");
|
||||
},
|
||||
"postal.socket.remote" : function( envelope ) {
|
||||
"postal.socket.remote" : function ( envelope ) {
|
||||
postal.publish( envelope );
|
||||
},
|
||||
socketTransmit: function( evntName, envelope ) {
|
||||
socketTransmit : function ( evntName, envelope ) {
|
||||
// we risk mutating the message here, so extend
|
||||
// and add the correlationId to the extended copy
|
||||
var socketEnv = _.extend( {}, envelope );
|
||||
socketEnv.correlationId = this.session.id;
|
||||
socketNamespace.emit(evntName, socketEnv);
|
||||
socketNamespace.emit( evntName, socketEnv );
|
||||
}
|
||||
},
|
||||
offline: {
|
||||
_onEnter: function() {
|
||||
offline : {
|
||||
_onEnter : function () {
|
||||
socketNamespace.socket.disconnect();
|
||||
},
|
||||
socketTransmit: function() {
|
||||
this.deferUntilTransition("online");
|
||||
socketTransmit : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
},
|
||||
"tryConnect": function() {
|
||||
this.transition("probing");
|
||||
"tryConnect" : function () {
|
||||
this.transition( "probing" );
|
||||
}
|
||||
},
|
||||
disconnected: {
|
||||
_onEnter: function() {
|
||||
disconnected : {
|
||||
_onEnter : function () {
|
||||
var self = this;
|
||||
self.retryFn = setTimeout(function() {
|
||||
self.transition("probing");
|
||||
},postalSocket.config.reconnectInterval);
|
||||
self.retryFn = setTimeout( function () {
|
||||
self.transition( "probing" );
|
||||
}, postalSocket.config.reconnectInterval );
|
||||
},
|
||||
connecting: function() {
|
||||
this.transition("probing");
|
||||
connecting : function () {
|
||||
this.transition( "probing" );
|
||||
},
|
||||
reconnecting: function() {
|
||||
this.transition("probing");
|
||||
reconnecting : function () {
|
||||
this.transition( "probing" );
|
||||
},
|
||||
socketTransmit: function() {
|
||||
this.deferUntilTransition("online");
|
||||
socketTransmit : function () {
|
||||
this.deferUntilTransition( "online" );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
postal.subscribe({
|
||||
channel: "postal",
|
||||
topic: "sessionId.changed",
|
||||
callback: function() {
|
||||
fsm.handle("postal.session.changed");
|
||||
} );
|
||||
postal.subscribe( {
|
||||
channel : "postal",
|
||||
topic : "sessionId.changed",
|
||||
callback : function () {
|
||||
fsm.handle( "postal.session.changed" );
|
||||
}
|
||||
});
|
||||
} );
|
||||
return {
|
||||
config : {
|
||||
url: window.location.origin,
|
||||
reconnectInterval: 4000
|
||||
url : window.location.origin,
|
||||
reconnectInterval : 4000
|
||||
},
|
||||
goOffline: function() {
|
||||
goOffline : function () {
|
||||
fsm.handle( "goOffline" );
|
||||
},
|
||||
goOnline: function() {
|
||||
goOnline : function () {
|
||||
fsm.handle( "tryConnect" );
|
||||
},
|
||||
manifest: [],
|
||||
publish: function( envelope ) {
|
||||
manifest : [],
|
||||
publish : function ( envelope ) {
|
||||
fsm.handle( "socketTransmit", "postal.publish", envelope );
|
||||
},
|
||||
subscribe: function( options ) {
|
||||
subscribe : function ( options ) {
|
||||
options.channel = options.channel || postal.configuration.DEFAULT_CHANNEL;
|
||||
options.topic = options.topic || "*";
|
||||
if( !_.any( this.manifest, function( item ){
|
||||
if ( !_.any( this.manifest, function ( item ) {
|
||||
return item.channel === options.channel && item.topic === options.topic;
|
||||
})) {
|
||||
} ) ) {
|
||||
this.manifest.push( options );
|
||||
fsm.handle( "socketTransmit", "postal.subscribe", options );
|
||||
}
|
||||
},
|
||||
socketMgr: fsm,
|
||||
socketNamespace: socketNamespace,
|
||||
unsubscribe: function( options ) {
|
||||
socketMgr : fsm,
|
||||
socketNamespace : socketNamespace,
|
||||
unsubscribe : function ( options ) {
|
||||
options.channel = options.channel || postal.configuration.DEFAULT_CHANNEL;
|
||||
options.topic = options.topic || "*";
|
||||
if( !postal.getSubscribersFor( options.channel, options.topic ).length ) {
|
||||
fsm.handle( "socketTransmit", "postal.unsubscribe", options);
|
||||
if ( !postal.getSubscribersFor( options.channel, options.topic ).length ) {
|
||||
fsm.handle( "socketTransmit", "postal.unsubscribe", options );
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
postal.connections.socket.goOnline();
|
||||
var SocketChannel = postal.channelTypes.websocket = function( channelName, defaultTopic ) {
|
||||
var SocketChannel = postal.channelTypes.websocket = function ( channelName, defaultTopic ) {
|
||||
var channel = postal.channel( channelName, defaultTopic ),
|
||||
localSubscribe = channel.subscribe,
|
||||
localPublish = channel.publish,
|
||||
localTopic = channel.topic;
|
||||
|
||||
channel.publish = function() {
|
||||
postalSocket.publish( localPublish.apply( channel, arguments) );
|
||||
|
||||
channel.publish = function () {
|
||||
postalSocket.publish( localPublish.apply( channel, arguments ) );
|
||||
};
|
||||
|
||||
channel.subscribe = function() {
|
||||
var sub = localSubscribe.apply( channel, arguments),
|
||||
|
||||
channel.subscribe = function () {
|
||||
var sub = localSubscribe.apply( channel, arguments ),
|
||||
origUnsubscribe;
|
||||
origUnsubscribe = sub.unsubscribe;
|
||||
sub.unsubscribe = function() {
|
||||
origUnsubscribe.call(sub);
|
||||
postalSocket.unsubscribe({ channel: sub.channel, topic: sub.topic });
|
||||
sub.unsubscribe = function () {
|
||||
origUnsubscribe.call( sub );
|
||||
postalSocket.unsubscribe( { channel : sub.channel, topic : sub.topic } );
|
||||
};
|
||||
postalSocket.subscribe({ channel: sub.channel, topic: sub.topic });
|
||||
postalSocket.subscribe( { channel : sub.channel, topic : sub.topic } );
|
||||
return sub;
|
||||
};
|
||||
|
||||
channel.topic = function( topic ) {
|
||||
if(topic === channel._topic) {
|
||||
|
||||
channel.topic = function ( topic ) {
|
||||
if ( topic === channel._topic ) {
|
||||
return this;
|
||||
}
|
||||
return new SocketChannel(this.channel, topic);
|
||||
return new SocketChannel( this.channel, topic );
|
||||
};
|
||||
|
||||
|
||||
return channel;
|
||||
};
|
||||
|
||||
}));
|
||||
} ));
|
||||
|
|
@ -1,52 +1,52 @@
|
|||
define([
|
||||
define( [
|
||||
'jquery',
|
||||
'backbone',
|
||||
'bus'
|
||||
], function( $, Backbone, bus ){
|
||||
], function ( $, Backbone, bus ) {
|
||||
|
||||
return Backbone.Router.extend({
|
||||
routes: {
|
||||
"" : "home",
|
||||
"requests" : "requests",
|
||||
"wiretap" : "wiretap",
|
||||
return Backbone.Router.extend( {
|
||||
routes : {
|
||||
"" : "home",
|
||||
"requests" : "requests",
|
||||
"wiretap" : "wiretap",
|
||||
"*anything" : "redirect"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
_.bindAll( self );
|
||||
|
||||
$( document ).delegate( "a.ps-nav", "click", function( e ){
|
||||
$( document ).delegate( "a.ps-nav", "click", function ( e ) {
|
||||
e.preventDefault();
|
||||
self.navigate( $( this ).attr( 'href' ), { trigger: true });
|
||||
});
|
||||
self.navigate( $( this ).attr( 'href' ), { trigger : true } );
|
||||
} );
|
||||
bus.router.publish( "initialized" );
|
||||
},
|
||||
|
||||
activateUI: function( uiName, context ) {
|
||||
bus.viewManager.publish({
|
||||
topic: "ui.show",
|
||||
data: {
|
||||
name: uiName,
|
||||
context: context
|
||||
activateUI : function ( uiName, context ) {
|
||||
bus.viewManager.publish( {
|
||||
topic : "ui.show",
|
||||
data : {
|
||||
name : uiName,
|
||||
context : context
|
||||
}
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
home: function() {
|
||||
home : function () {
|
||||
this.activateUI( "homeUI" );
|
||||
},
|
||||
|
||||
requests: function() {
|
||||
requests : function () {
|
||||
this.activateUI( "searchRequestUI" );
|
||||
},
|
||||
|
||||
wiretap: function() {
|
||||
wiretap : function () {
|
||||
this.activateUI( "wireTapLogUI" );
|
||||
},
|
||||
|
||||
redirect: function() {
|
||||
this.navigate( "/", { trigger: true });
|
||||
redirect : function () {
|
||||
this.navigate( "/", { trigger : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
define([
|
||||
define( [
|
||||
'underscore',
|
||||
'bus'
|
||||
], function( _, bus ){
|
||||
var ViewManager = function() {
|
||||
], function ( _, bus ) {
|
||||
var ViewManager = function () {
|
||||
this.views = {}; // holds the views that are registered with the manager
|
||||
this.UI = {}; // holds the UI configurations that are defined
|
||||
this.priorContext = undefined; // holds the name of the last UI configuration
|
||||
|
|
@ -17,16 +17,16 @@ define([
|
|||
// then the ViewManager will create a new instance of the view. If options.args
|
||||
// exists, it will be passed into the constructor function of the view.
|
||||
//----------------------------------------------------------------------------
|
||||
ViewManager.prototype.registerView = function(name, viewCtor) {
|
||||
ViewManager.prototype.registerView = function ( name, viewCtor ) {
|
||||
this.views[name] = {
|
||||
rendered: false,
|
||||
visible: false,
|
||||
getInstance: (function(){
|
||||
rendered : false,
|
||||
visible : false,
|
||||
getInstance : (function () {
|
||||
var _instance;
|
||||
return function(options){
|
||||
return function ( options ) {
|
||||
var _options = options || {};
|
||||
if(!_instance || _options.forceNew) {
|
||||
_instance = new viewCtor(_options.args || {});
|
||||
if ( !_instance || _options.forceNew ) {
|
||||
_instance = new viewCtor( _options.args || {} );
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
|
@ -34,8 +34,8 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
ViewManager.prototype.registerViews = function(views) {
|
||||
_.each( views, function( view ){
|
||||
ViewManager.prototype.registerViews = function ( views ) {
|
||||
_.each( views, function ( view ) {
|
||||
this.registerView( view.name, view.ctor );
|
||||
}, this );
|
||||
};
|
||||
|
|
@ -46,76 +46,76 @@ define([
|
|||
// name, second arg is the array of view names (in the order they need to be
|
||||
// instantiated/rendered/shown)
|
||||
//----------------------------------------------------------------------------
|
||||
ViewManager.prototype.defineUI = function( name, dependencies, options ) {
|
||||
ViewManager.prototype.defineUI = function ( name, dependencies, options ) {
|
||||
var self = this;
|
||||
self.UI[ name ] = {
|
||||
options: options || {},
|
||||
dependencies: dependencies,
|
||||
activate: function( data ) {
|
||||
options : options || {},
|
||||
dependencies : dependencies,
|
||||
activate : function ( data ) {
|
||||
data = data || {};
|
||||
data.priorContext = self.priorContext;
|
||||
data.targetContext = name;
|
||||
|
||||
if( !this.options.noHide ) {
|
||||
if ( !this.options.noHide ) {
|
||||
// hide anything visible that's not in the dependencies for this UI configuration
|
||||
var shouldHide = _.reduce( self.views, function( memo, val, key ){
|
||||
if( val.visible && !_.include( this.dependencies, key ) ){
|
||||
var shouldHide = _.reduce( self.views, function ( memo, val, key ) {
|
||||
if ( val.visible && !_.include( this.dependencies, key ) ) {
|
||||
memo.push( key );
|
||||
}
|
||||
return memo;
|
||||
}, [], this );
|
||||
|
||||
_.each( shouldHide, function( viewName ){
|
||||
_.each( shouldHide, function ( viewName ) {
|
||||
var instance = self.views[ viewName ].getInstance();
|
||||
if( instance.hide ) {
|
||||
if ( instance.hide ) {
|
||||
instance.hide();
|
||||
}
|
||||
self.views[ viewName ].visible = false;
|
||||
});
|
||||
} );
|
||||
}
|
||||
|
||||
// set up, render & show the dependencies for this UI configuration
|
||||
_.each(this.dependencies, function(viewName){
|
||||
var instance = self.views[viewName].getInstance(data);
|
||||
if(!self.views[viewName].rendered) {
|
||||
instance.render(data);
|
||||
_.each( this.dependencies, function ( viewName ) {
|
||||
var instance = self.views[viewName].getInstance( data );
|
||||
if ( !self.views[viewName].rendered ) {
|
||||
instance.render( data );
|
||||
self.views[viewName].rendered = true;
|
||||
}
|
||||
if(!self.views[viewName].visible) {
|
||||
if(instance.show) {
|
||||
instance.show(data);
|
||||
if ( !self.views[viewName].visible ) {
|
||||
if ( instance.show ) {
|
||||
instance.show( data );
|
||||
}
|
||||
self.views[viewName].visible = true;
|
||||
}
|
||||
|
||||
if(instance.update) {
|
||||
instance.update(data);
|
||||
if ( instance.update ) {
|
||||
instance.update( data );
|
||||
}
|
||||
});
|
||||
} );
|
||||
self.priorContext = name;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ViewManager.prototype.defineUIs = function( uis ) {
|
||||
_.each( uis, function( ui ){
|
||||
ViewManager.prototype.defineUIs = function ( uis ) {
|
||||
_.each( uis, function ( ui ) {
|
||||
this.defineUI( ui.name, ui.dependencies, ui.options );
|
||||
}, this );
|
||||
};
|
||||
|
||||
ViewManager.prototype.addViewToUI = function( uiName, viewName, viewCtor ) {
|
||||
ViewManager.prototype.addViewToUI = function ( uiName, viewName, viewCtor ) {
|
||||
var uis = _.isArray( uiName ) ? uiName : [ uiName ];
|
||||
|
||||
if( !this.views[ viewName ] ) {
|
||||
if ( !this.views[ viewName ] ) {
|
||||
this.registerView( viewName, viewCtor );
|
||||
}
|
||||
|
||||
_.each( uis, function( ui ) {
|
||||
if( this.UI[ ui ] ) {
|
||||
_.each( uis, function ( ui ) {
|
||||
if ( this.UI[ ui ] ) {
|
||||
this.UI[ ui ].dependencies.push( viewName );
|
||||
}
|
||||
}, this );
|
||||
};
|
||||
|
||||
return ViewManager;
|
||||
});
|
||||
} );
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -4,36 +4,707 @@
|
|||
// Backbone may be freely distributed under the MIT license.
|
||||
// For all details and documentation:
|
||||
// http://backbonejs.org
|
||||
(function(h,g){typeof exports!=="undefined"?g(h,exports,require("underscore")):typeof define==="function"&&define.amd?define(["underscore","jquery","exports"],function(f,i,p){h.Backbone=g(h,p,f,i)}):h.Backbone=g(h,{},h._,h.jQuery||h.Zepto||h.ender)})(this,function(h,g,f,i){var p=h.Backbone,y=Array.prototype.slice,z=Array.prototype.splice;g.VERSION="0.9.2";g.setDomLibrary=function(a){i=a};g.noConflict=function(){h.Backbone=p;return g};g.emulateHTTP=false;g.emulateJSON=false;var q=/\s+/,l=g.Events=
|
||||
{on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(q);for(d=this._callbacks||(this._callbacks={});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,k,g,j,h;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(q):f.keys(e);d=a.shift();)if(k=e[d],delete e[d],k&&(b||c))for(g=k.tail;(k=k.next)!==g;)if(j=k.callback,h=k.context,b&&j!==b||c&&h!==c)this.on(d,j,h);return this}},
|
||||
trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(q);for(g=y.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};l.bind=l.on;l.unbind=l.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);if(b&&b.collection)this.collection=b.collection;
|
||||
this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent={};this._pending={};this.set(a,{silent:true});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,l,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;
|
||||
if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(b==null?"":""+b)},has:function(a){return this.get(a)!=null},set:function(a,b,c){var d,e;f.isObject(a)||a==null?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;if(d instanceof o)d=d.attributes;if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return false;if(this.idAttribute in d)this.id=d[this.idAttribute];var b=c.changes={},g=this.attributes,h=this._escapedAttributes,j=this._previousAttributes||
|
||||
{};for(e in d){a=d[e];if(!f.isEqual(g[e],a)||c.unset&&f.has(g,e))delete h[e],(c.silent?this._silent:b)[e]=true;c.unset?delete g[e]:g[e]=a;!f.isEqual(j[e],a)||f.has(g,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=true)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=true;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=true;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=
|
||||
a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return false;c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||a==null?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return false;e=f.clone(this.attributes)}a=f.extend({},c,{silent:true});if(d&&!this.set(d,c.wait?a:c))return false;var k=this,h=c.success;c.success=function(a,b,e){b=k.parse(a,e);
|
||||
c.wait&&(delete c.wait,b=f.extend(d||{},b));if(!k.set(b,c))return false;h?h(k,a):k.trigger("sync",k,a,c)};c.error=g.wrapError(c.error,k,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),false;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||
|
||||
g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t();return this.isNew()?a:a+(a.charAt(a.length-1)=="/"?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return this.id==null},change:function(a){a||(a={});var b=this._changing;this._changing=true;for(var c in this._silent)this._pending[c]=true;var d=f.extend({},a.changes,this._silent);
|
||||
this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending={};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=false;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):
|
||||
false;var b,c=false,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return true;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return true;b&&b.error?
|
||||
b.error(this,c,b):this.trigger("error",this,c,b);return false}});var r=g.Collection=function(a,b){b||(b={});if(b.model)this.model=b.model;if(b.comparator)this.comparator=b.comparator;this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:true,parse:b.parse})};f.extend(r.prototype,l,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,h,j={},i={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];for(c=0,d=
|
||||
a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");g=e.cid;h=e.id;j[g]||this._byCid[g]||h!=null&&(i[h]||this._byId[h])?l.push(c):j[g]=i[h]=e}for(c=l.length;c--;)a.splice(l[c],1);for(c=0,d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,e.id!=null&&(this._byId[e.id]=e);this.length+=d;z.apply(this.models,[b.at!=null?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:true});if(b.silent)return this;
|
||||
for(c=0,d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?a.slice():[a];for(c=0,d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c])){delete this._byId[g.id];delete this._byCid[g.cid];e=this.indexOf(g);this.models.splice(e,1);this.length--;if(!b.silent)b.index=e,g.trigger("remove",g,this,b);this._removeReference(g)}return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,
|
||||
b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return a==null?void 0:this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return false;
|
||||
return true})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);this.comparator.length==1?this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,f.extend({silent:true},
|
||||
b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};if(a.parse===void 0)a.parse=true;var b=this,c=a.success;a.success=function(d,e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return false;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",
|
||||
a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){b||(b={});if(a instanceof o){if(!a.collection)a.collection=this}else{var c;b.collection=this;a=new this.model(a,b);a._validate(a.attributes,b)||(a=false)}return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,
|
||||
b,c,d){(a=="add"||a=="remove")&&c!=this||(a=="destroy"&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),function(a){r.prototype[a]=function(){return f[a].apply(f,
|
||||
[this.models].concat(f.toArray(arguments)))}});var u=g.Router=function(a){a||(a={});if(a.routes)this.routes=a.routes;this._bindRoutes();this.initialize.apply(this,arguments)},A=/:\w+/g,B=/\*\w+/g,C=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(u.prototype,l,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new m);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+
|
||||
b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(C,"\\$&").replace(A,"([^/]+)").replace(B,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var m=g.History=function(){this.handlers=
|
||||
[];f.bindAll(this,"checkUrl")},s=/^[#\/]/,D=/msie [\w.]+/;m.started=false;f.extend(m.prototype,l,{interval:50,getHash:function(a){return(a=(a?a.location:window.location).href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,b){if(a==null)if(this._hasPushState||b){var a=window.location.pathname,c=window.location.search;c&&(a+=c)}else a=this.getHash();a.indexOf(this.options.root)||(a=a.substr(this.options.root.length));return a.replace(s,"")},start:function(a){if(m.started)throw Error("Backbone.history has already been started");
|
||||
m.started=true;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=D.exec(navigator.userAgent.toLowerCase())&&(!b||b<=7))this.iframe=i('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);if(this._hasPushState)i(window).bind("popstate",
|
||||
this.checkUrl);else if(this._wantsHashChange&&"onhashchange"in window&&!b)i(window).bind("hashchange",this.checkUrl);else if(this._wantsHashChange)this._checkUrlInterval=setInterval(this.checkUrl,this.interval);this.fragment=a;a=window.location;b=a.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,true),window.location.replace(this.options.root+"#"+this.fragment),true;else if(this._wantsPushState&&this._hasPushState&&
|
||||
b&&a.hash)this.fragment=this.getHash().replace(s,""),window.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment);if(!this.options.silent)return this.loadUrl()},stop:function(){i(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);m.started=false},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));
|
||||
if(a==this.fragment)return false;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),true})},navigate:function(a,b){if(!m.started)return false;if(!b||b===true)b={trigger:b};var c=(a||"").replace(s,"");if(this.fragment!=c)this._hasPushState?(c.indexOf(this.options.root)!=0&&(c=this.options.root+c),this.fragment=c,window.history[b.replace?
|
||||
"replaceState":"pushState"]({},document.title,c)):this._wantsHashChange?(this.fragment=c,this._updateHash(window.location,c,b.replace),this.iframe&&c!=this.getFragment(this.getHash(this.iframe))&&(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,c,b.replace))):window.location.assign(this.options.root+a),b.trigger&&this.loadUrl(a)},_updateHash:function(a,b,c){c?a.replace(a.toString().replace(/(javascript:|#).*$/,"")+"#"+b):a.hash=b}});var v=g.View=function(a){this.cid=
|
||||
f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},E=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(",");f.extend(v.prototype,l,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&i(a).attr(b);c!=null&&i(a).html(c);return a},setElement:function(a,
|
||||
b){this.$el&&this.undelegateEvents();this.$el=a instanceof i?a:i(a);this.el=this.$el[0];b!==false&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents();for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(E),e=d[1],d=d[2],c=f.bind(c,this);e+=".delegateEvents"+this.cid;d===""?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+
|
||||
this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,false);else{var a=n(this,"attributes")||{};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.setElement(this.make(this.tagName,a),false)}}});o.extend=r.extend=u.extend=v.extend=function(a,b){var c=F(this,a,b);c.extend=this.extend;return c};var G={create:"POST",
|
||||
update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=G[a];c||(c={});var e={type:d,dataType:"json"};if(!c.url)e.url=n(b,"url")||t();if(!c.data&&b&&(a=="create"||a=="update"))e.contentType="application/json",e.data=JSON.stringify(b.toJSON());if(g.emulateJSON)e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{};if(g.emulateHTTP&&(d==="PUT"||d==="DELETE")){if(g.emulateJSON)e.data._method=d;e.type="POST";e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",
|
||||
d)}}if(e.type!=="GET"&&!g.emulateJSON)e.processData=false;return i.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},F=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);x.prototype=a.prototype;d.prototype=new x;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},n=function(a,b){return!a||
|
||||
!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},t=function(){throw Error('A "url" property or function must be specified');};return g});
|
||||
(function ( h, g ) {
|
||||
typeof exports !== "undefined" ? g( h, exports, require( "underscore" ) ) : typeof define === "function" && define.amd ? define( ["underscore", "jquery", "exports"], function ( f, i, p ) {
|
||||
h.Backbone = g( h, p, f, i )
|
||||
} ) : h.Backbone = g( h, {}, h._, h.jQuery || h.Zepto || h.ender )
|
||||
})( this, function ( h, g, f, i ) {
|
||||
var p = h.Backbone, y = Array.prototype.slice, z = Array.prototype.splice;
|
||||
g.VERSION = "0.9.2";
|
||||
g.setDomLibrary = function ( a ) {
|
||||
i = a
|
||||
};
|
||||
g.noConflict = function () {
|
||||
h.Backbone = p;
|
||||
return g
|
||||
};
|
||||
g.emulateHTTP = false;
|
||||
g.emulateJSON = false;
|
||||
var q = /\s+/, l = g.Events =
|
||||
{on : function ( a, b, c ) {
|
||||
var d, e, f, g, j;
|
||||
if ( !b ) {
|
||||
return this;
|
||||
}
|
||||
a = a.split( q );
|
||||
for ( d = this._callbacks || (this._callbacks = {}); e = a.shift(); ) {
|
||||
f = (j = d[e]) ? j.tail : {}, f.next = g = {}, f.context = c, f.callback = b, d[e] = {tail : g, next : j ? j.next : f};
|
||||
}
|
||||
return this
|
||||
}, off : function ( a, b, c ) {
|
||||
var d, e, k, g, j, h;
|
||||
if ( e = this._callbacks ) {
|
||||
if ( !a && !b && !c ) {
|
||||
return delete this._callbacks, this;
|
||||
}
|
||||
for ( a = a ? a.split( q ) : f.keys( e ); d = a.shift(); ) {
|
||||
if ( k = e[d], delete e[d], k && (b || c) ) {
|
||||
for ( g = k.tail; (k = k.next) !== g; ) {
|
||||
if ( j = k.callback, h = k.context, b && j !== b || c && h !== c ) {
|
||||
this.on( d, j, h );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
},
|
||||
trigger : function ( a ) {
|
||||
var b, c, d, e, f, g;
|
||||
if ( !(d = this._callbacks) ) {
|
||||
return this;
|
||||
}
|
||||
f = d.all;
|
||||
a = a.split( q );
|
||||
for ( g = y.call( arguments, 1 ); b = a.shift(); ) {
|
||||
if ( c = d[b] ) {
|
||||
for ( e = c.tail; (c = c.next) !== e; ) {
|
||||
c.callback.apply( c.context || this, g );
|
||||
}
|
||||
}
|
||||
if ( c = f ) {
|
||||
e = c.tail;
|
||||
for ( b = [b].concat( g ); (c = c.next) !== e; ) {
|
||||
c.callback.apply( c.context || this, b )
|
||||
}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}};
|
||||
l.bind = l.on;
|
||||
l.unbind = l.off;
|
||||
var o = g.Model = function ( a, b ) {
|
||||
var c;
|
||||
a || (a = {});
|
||||
b && b.parse && (a = this.parse( a ));
|
||||
if ( c = n( this, "defaults" ) ) {
|
||||
a = f.extend( {}, c, a );
|
||||
}
|
||||
if ( b && b.collection ) {
|
||||
this.collection = b.collection;
|
||||
}
|
||||
this.attributes = {};
|
||||
this._escapedAttributes = {};
|
||||
this.cid = f.uniqueId( "c" );
|
||||
this.changed = {};
|
||||
this._silent = {};
|
||||
this._pending = {};
|
||||
this.set( a, {silent : true} );
|
||||
this.changed = {};
|
||||
this._silent = {};
|
||||
this._pending = {};
|
||||
this._previousAttributes = f.clone( this.attributes );
|
||||
this.initialize.apply( this, arguments )
|
||||
};
|
||||
f.extend( o.prototype, l, {changed : null, _silent : null, _pending : null, idAttribute : "id", initialize : function () {
|
||||
}, toJSON : function () {
|
||||
return f.clone( this.attributes )
|
||||
}, get : function ( a ) {
|
||||
return this.attributes[a]
|
||||
}, escape : function ( a ) {
|
||||
var b;
|
||||
if ( b = this._escapedAttributes[a] ) {
|
||||
return b;
|
||||
}
|
||||
b = this.get( a );
|
||||
return this._escapedAttributes[a] = f.escape( b == null ? "" : "" + b )
|
||||
}, has : function ( a ) {
|
||||
return this.get( a ) != null
|
||||
}, set : function ( a, b, c ) {
|
||||
var d, e;
|
||||
f.isObject( a ) || a == null ? (d = a, c = b) : (d = {}, d[a] = b);
|
||||
c || (c = {});
|
||||
if ( !d ) {
|
||||
return this;
|
||||
}
|
||||
if ( d instanceof o ) {
|
||||
d = d.attributes;
|
||||
}
|
||||
if ( c.unset ) {
|
||||
for ( e in d ) {
|
||||
d[e] = void 0;
|
||||
}
|
||||
}
|
||||
if ( !this._validate( d, c ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( this.idAttribute in d ) {
|
||||
this.id = d[this.idAttribute];
|
||||
}
|
||||
var b = c.changes = {}, g = this.attributes, h = this._escapedAttributes, j = this._previousAttributes ||
|
||||
{};
|
||||
for ( e in d ) {
|
||||
a = d[e];
|
||||
if ( !f.isEqual( g[e], a ) || c.unset && f.has( g, e ) ) {
|
||||
delete h[e], (c.silent ? this._silent : b)[e] = true;
|
||||
}
|
||||
c.unset ? delete g[e] : g[e] = a;
|
||||
!f.isEqual( j[e], a ) || f.has( g, e ) != f.has( j, e ) ? (this.changed[e] = a, c.silent || (this._pending[e] = true)) : (delete this.changed[e], delete this._pending[e])
|
||||
}
|
||||
c.silent || this.change( c );
|
||||
return this
|
||||
}, unset : function ( a, b ) {
|
||||
(b || (b = {})).unset = true;
|
||||
return this.set( a, null, b )
|
||||
}, clear : function ( a ) {
|
||||
(a || (a = {})).unset = true;
|
||||
return this.set( f.clone( this.attributes ), a )
|
||||
}, fetch : function ( a ) {
|
||||
var a =
|
||||
a ? f.clone( a ) : {}, b = this, c = a.success;
|
||||
a.success = function ( d, e, f ) {
|
||||
if ( !b.set( b.parse( d, f ), a ) ) {
|
||||
return false;
|
||||
}
|
||||
c && c( b, d )
|
||||
};
|
||||
a.error = g.wrapError( a.error, b, a );
|
||||
return(this.sync || g.sync).call( this, "read", this, a )
|
||||
}, save : function ( a, b, c ) {
|
||||
var d, e;
|
||||
f.isObject( a ) || a == null ? (d = a, c = b) : (d = {}, d[a] = b);
|
||||
c = c ? f.clone( c ) : {};
|
||||
if ( c.wait ) {
|
||||
if ( !this._validate( d, c ) ) {
|
||||
return false;
|
||||
}
|
||||
e = f.clone( this.attributes )
|
||||
}
|
||||
a = f.extend( {}, c, {silent : true} );
|
||||
if ( d && !this.set( d, c.wait ? a : c ) ) {
|
||||
return false;
|
||||
}
|
||||
var k = this, h = c.success;
|
||||
c.success = function ( a, b, e ) {
|
||||
b = k.parse( a, e );
|
||||
c.wait && (delete c.wait, b = f.extend( d || {}, b ));
|
||||
if ( !k.set( b, c ) ) {
|
||||
return false;
|
||||
}
|
||||
h ? h( k, a ) : k.trigger( "sync", k, a, c )
|
||||
};
|
||||
c.error = g.wrapError( c.error, k, c );
|
||||
b = this.isNew() ? "create" : "update";
|
||||
b = (this.sync || g.sync).call( this, b, this, c );
|
||||
c.wait && this.set( e, a );
|
||||
return b
|
||||
}, destroy : function ( a ) {
|
||||
var a = a ? f.clone( a ) : {}, b = this, c = a.success, d = function () {
|
||||
b.trigger( "destroy", b, b.collection, a )
|
||||
};
|
||||
if ( this.isNew() ) {
|
||||
return d(), false;
|
||||
}
|
||||
a.success = function ( e ) {
|
||||
a.wait && d();
|
||||
c ? c( b, e ) : b.trigger( "sync", b, e, a )
|
||||
};
|
||||
a.error = g.wrapError( a.error, b, a );
|
||||
var e = (this.sync ||
|
||||
g.sync).call( this, "delete", this, a );
|
||||
a.wait || d();
|
||||
return e
|
||||
}, url : function () {
|
||||
var a = n( this, "urlRoot" ) || n( this.collection, "url" ) || t();
|
||||
return this.isNew() ? a : a + (a.charAt( a.length - 1 ) == "/" ? "" : "/") + encodeURIComponent( this.id )
|
||||
}, parse : function ( a ) {
|
||||
return a
|
||||
}, clone : function () {
|
||||
return new this.constructor( this.attributes )
|
||||
}, isNew : function () {
|
||||
return this.id == null
|
||||
}, change : function ( a ) {
|
||||
a || (a = {});
|
||||
var b = this._changing;
|
||||
this._changing = true;
|
||||
for ( var c in this._silent ) {
|
||||
this._pending[c] = true;
|
||||
}
|
||||
var d = f.extend( {}, a.changes, this._silent );
|
||||
this._silent = {};
|
||||
for ( c in d ) {
|
||||
this.trigger( "change:" + c, this, this.get( c ), a );
|
||||
}
|
||||
if ( b ) {
|
||||
return this;
|
||||
}
|
||||
for ( ; !f.isEmpty( this._pending ); ) {
|
||||
this._pending = {};
|
||||
this.trigger( "change", this, a );
|
||||
for ( c in this.changed ) {
|
||||
!this._pending[c] && !this._silent[c] && delete this.changed[c];
|
||||
}
|
||||
this._previousAttributes = f.clone( this.attributes )
|
||||
}
|
||||
this._changing = false;
|
||||
return this
|
||||
}, hasChanged : function ( a ) {
|
||||
return!arguments.length ? !f.isEmpty( this.changed ) : f.has( this.changed, a )
|
||||
}, changedAttributes : function ( a ) {
|
||||
if ( !a ) {
|
||||
return this.hasChanged() ? f.clone( this.changed ) :
|
||||
false;
|
||||
}
|
||||
var b, c = false, d = this._previousAttributes, e;
|
||||
for ( e in a ) {
|
||||
if ( !f.isEqual( d[e], b = a[e] ) ) {
|
||||
(c || (c = {}))[e] = b;
|
||||
}
|
||||
}
|
||||
return c
|
||||
}, previous : function ( a ) {
|
||||
return!arguments.length || !this._previousAttributes ? null : this._previousAttributes[a]
|
||||
}, previousAttributes : function () {
|
||||
return f.clone( this._previousAttributes )
|
||||
}, isValid : function () {
|
||||
return!this.validate( this.attributes )
|
||||
}, _validate : function ( a, b ) {
|
||||
if ( b.silent || !this.validate ) {
|
||||
return true;
|
||||
}
|
||||
var a = f.extend( {}, this.attributes, a ), c = this.validate( a, b );
|
||||
if ( !c ) {
|
||||
return true;
|
||||
}
|
||||
b && b.error ?
|
||||
b.error( this, c, b ) : this.trigger( "error", this, c, b );
|
||||
return false
|
||||
}} );
|
||||
var r = g.Collection = function ( a, b ) {
|
||||
b || (b = {});
|
||||
if ( b.model ) {
|
||||
this.model = b.model;
|
||||
}
|
||||
if ( b.comparator ) {
|
||||
this.comparator = b.comparator;
|
||||
}
|
||||
this._reset();
|
||||
this.initialize.apply( this, arguments );
|
||||
a && this.reset( a, {silent : true, parse : b.parse} )
|
||||
};
|
||||
f.extend( r.prototype, l, {model : o, initialize : function () {
|
||||
}, toJSON : function ( a ) {
|
||||
return this.map( function ( b ) {
|
||||
return b.toJSON( a )
|
||||
} )
|
||||
}, add : function ( a, b ) {
|
||||
var c, d, e, g, h, j = {}, i = {}, l = [];
|
||||
b || (b = {});
|
||||
a = f.isArray( a ) ? a.slice() : [a];
|
||||
for ( c = 0, d =
|
||||
a.length; c < d; c++ ) {
|
||||
if ( !(e = a[c] = this._prepareModel( a[c], b )) ) {
|
||||
throw Error( "Can't add an invalid model to a collection" );
|
||||
}
|
||||
g = e.cid;
|
||||
h = e.id;
|
||||
j[g] || this._byCid[g] || h != null && (i[h] || this._byId[h]) ? l.push( c ) : j[g] = i[h] = e
|
||||
}
|
||||
for ( c = l.length; c--; ) {
|
||||
a.splice( l[c], 1 );
|
||||
}
|
||||
for ( c = 0, d = a.length; c < d; c++ ) {
|
||||
(e = a[c]).on( "all", this._onModelEvent, this ), this._byCid[e.cid] = e, e.id != null && (this._byId[e.id] = e);
|
||||
}
|
||||
this.length += d;
|
||||
z.apply( this.models, [b.at != null ? b.at : this.models.length, 0].concat( a ) );
|
||||
this.comparator && this.sort( {silent : true} );
|
||||
if ( b.silent ) {
|
||||
return this;
|
||||
}
|
||||
for ( c = 0, d = this.models.length; c < d; c++ ) {
|
||||
if ( j[(e = this.models[c]).cid] ) {
|
||||
b.index = c, e.trigger( "add", e, this, b );
|
||||
}
|
||||
}
|
||||
return this
|
||||
}, remove : function ( a, b ) {
|
||||
var c, d, e, g;
|
||||
b || (b = {});
|
||||
a = f.isArray( a ) ? a.slice() : [a];
|
||||
for ( c = 0, d = a.length; c < d; c++ ) {
|
||||
if ( g = this.getByCid( a[c] ) || this.get( a[c] ) ) {
|
||||
delete this._byId[g.id];
|
||||
delete this._byCid[g.cid];
|
||||
e = this.indexOf( g );
|
||||
this.models.splice( e, 1 );
|
||||
this.length--;
|
||||
if ( !b.silent ) {
|
||||
b.index = e, g.trigger( "remove", g, this, b );
|
||||
}
|
||||
this._removeReference( g )
|
||||
}
|
||||
}
|
||||
return this
|
||||
}, push : function ( a, b ) {
|
||||
a = this._prepareModel( a, b );
|
||||
this.add( a,
|
||||
b );
|
||||
return a
|
||||
}, pop : function ( a ) {
|
||||
var b = this.at( this.length - 1 );
|
||||
this.remove( b, a );
|
||||
return b
|
||||
}, unshift : function ( a, b ) {
|
||||
a = this._prepareModel( a, b );
|
||||
this.add( a, f.extend( {at : 0}, b ) );
|
||||
return a
|
||||
}, shift : function ( a ) {
|
||||
var b = this.at( 0 );
|
||||
this.remove( b, a );
|
||||
return b
|
||||
}, get : function ( a ) {
|
||||
return a == null ? void 0 : this._byId[a.id != null ? a.id : a]
|
||||
}, getByCid : function ( a ) {
|
||||
return a && this._byCid[a.cid || a]
|
||||
}, at : function ( a ) {
|
||||
return this.models[a]
|
||||
}, where : function ( a ) {
|
||||
return f.isEmpty( a ) ? [] : this.filter( function ( b ) {
|
||||
for ( var c in a ) {
|
||||
if ( a[c] !== b.get( c ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
} )
|
||||
}, sort : function ( a ) {
|
||||
a || (a = {});
|
||||
if ( !this.comparator ) {
|
||||
throw Error( "Cannot sort a set without a comparator" );
|
||||
}
|
||||
var b = f.bind( this.comparator, this );
|
||||
this.comparator.length == 1 ? this.models = this.sortBy( b ) : this.models.sort( b );
|
||||
a.silent || this.trigger( "reset", this, a );
|
||||
return this
|
||||
}, pluck : function ( a ) {
|
||||
return f.map( this.models, function ( b ) {
|
||||
return b.get( a )
|
||||
} )
|
||||
}, reset : function ( a, b ) {
|
||||
a || (a = []);
|
||||
b || (b = {});
|
||||
for ( var c = 0, d = this.models.length; c < d; c++ ) {
|
||||
this._removeReference( this.models[c] );
|
||||
}
|
||||
this._reset();
|
||||
this.add( a, f.extend( {silent : true},
|
||||
b ) );
|
||||
b.silent || this.trigger( "reset", this, b );
|
||||
return this
|
||||
}, fetch : function ( a ) {
|
||||
a = a ? f.clone( a ) : {};
|
||||
if ( a.parse === void 0 ) {
|
||||
a.parse = true;
|
||||
}
|
||||
var b = this, c = a.success;
|
||||
a.success = function ( d, e, f ) {
|
||||
b[a.add ? "add" : "reset"]( b.parse( d, f ), a );
|
||||
c && c( b, d )
|
||||
};
|
||||
a.error = g.wrapError( a.error, b, a );
|
||||
return(this.sync || g.sync).call( this, "read", this, a )
|
||||
}, create : function ( a, b ) {
|
||||
var c = this, b = b ? f.clone( b ) : {}, a = this._prepareModel( a, b );
|
||||
if ( !a ) {
|
||||
return false;
|
||||
}
|
||||
b.wait || c.add( a, b );
|
||||
var d = b.success;
|
||||
b.success = function ( e, f ) {
|
||||
b.wait && c.add( e, b );
|
||||
d ? d( e, f ) : e.trigger( "sync",
|
||||
a, f, b )
|
||||
};
|
||||
a.save( null, b );
|
||||
return a
|
||||
}, parse : function ( a ) {
|
||||
return a
|
||||
}, chain : function () {
|
||||
return f( this.models ).chain()
|
||||
}, _reset : function () {
|
||||
this.length = 0;
|
||||
this.models = [];
|
||||
this._byId = {};
|
||||
this._byCid = {}
|
||||
}, _prepareModel : function ( a, b ) {
|
||||
b || (b = {});
|
||||
if ( a instanceof o ) {
|
||||
if ( !a.collection ) {
|
||||
a.collection = this
|
||||
}
|
||||
} else {
|
||||
var c;
|
||||
b.collection = this;
|
||||
a = new this.model( a, b );
|
||||
a._validate( a.attributes, b ) || (a = false)
|
||||
}
|
||||
return a
|
||||
}, _removeReference : function ( a ) {
|
||||
this == a.collection && delete a.collection;
|
||||
a.off( "all", this._onModelEvent, this )
|
||||
}, _onModelEvent : function ( a, b, c, d ) {
|
||||
(a == "add" || a == "remove") && c != this || (a == "destroy" && this.remove( b, d ), b && a === "change:" + b.idAttribute && (delete this._byId[b.previous( b.idAttribute )], this._byId[b.id] = b), this.trigger.apply( this, arguments ))
|
||||
}} );
|
||||
f.each( "forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split( "," ), function ( a ) {
|
||||
r.prototype[a] = function () {
|
||||
return f[a].apply( f,
|
||||
[this.models].concat( f.toArray( arguments ) ) )
|
||||
}
|
||||
} );
|
||||
var u = g.Router = function ( a ) {
|
||||
a || (a = {});
|
||||
if ( a.routes ) {
|
||||
this.routes = a.routes;
|
||||
}
|
||||
this._bindRoutes();
|
||||
this.initialize.apply( this, arguments )
|
||||
}, A = /:\w+/g, B = /\*\w+/g, C = /[-[\]{}()+?.,\\^$|#\s]/g;
|
||||
f.extend( u.prototype, l, {initialize : function () {
|
||||
}, route : function ( a, b, c ) {
|
||||
g.history || (g.history = new m);
|
||||
f.isRegExp( a ) || (a = this._routeToRegExp( a ));
|
||||
c || (c = this[b]);
|
||||
g.history.route( a, f.bind( function ( d ) {
|
||||
d = this._extractParameters( a, d );
|
||||
c && c.apply( this, d );
|
||||
this.trigger.apply( this, ["route:" +
|
||||
b].concat( d ) );
|
||||
g.history.trigger( "route", this, b, d )
|
||||
}, this ) );
|
||||
return this
|
||||
}, navigate : function ( a, b ) {
|
||||
g.history.navigate( a, b )
|
||||
}, _bindRoutes : function () {
|
||||
if ( this.routes ) {
|
||||
var a = [], b;
|
||||
for ( b in this.routes ) {
|
||||
a.unshift( [b, this.routes[b]] );
|
||||
}
|
||||
b = 0;
|
||||
for ( var c = a.length; b < c; b++ ) {
|
||||
this.route( a[b][0], a[b][1], this[a[b][1]] )
|
||||
}
|
||||
}
|
||||
}, _routeToRegExp : function ( a ) {
|
||||
a = a.replace( C, "\\$&" ).replace( A, "([^/]+)" ).replace( B, "(.*?)" );
|
||||
return RegExp( "^" + a + "$" )
|
||||
}, _extractParameters : function ( a, b ) {
|
||||
return a.exec( b ).slice( 1 )
|
||||
}} );
|
||||
var m = g.History = function () {
|
||||
this.handlers =
|
||||
[];
|
||||
f.bindAll( this, "checkUrl" )
|
||||
}, s = /^[#\/]/, D = /msie [\w.]+/;
|
||||
m.started = false;
|
||||
f.extend( m.prototype, l, {interval : 50, getHash : function ( a ) {
|
||||
return(a = (a ? a.location : window.location).href.match( /#(.*)$/ )) ? a[1] : ""
|
||||
}, getFragment : function ( a, b ) {
|
||||
if ( a == null ) {
|
||||
if ( this._hasPushState || b ) {
|
||||
var a = window.location.pathname, c = window.location.search;
|
||||
c && (a += c)
|
||||
} else {
|
||||
a = this.getHash();
|
||||
}
|
||||
}
|
||||
a.indexOf( this.options.root ) || (a = a.substr( this.options.root.length ));
|
||||
return a.replace( s, "" )
|
||||
}, start : function ( a ) {
|
||||
if ( m.started ) {
|
||||
throw Error( "Backbone.history has already been started" );
|
||||
}
|
||||
m.started = true;
|
||||
this.options = f.extend( {}, {root : "/"}, this.options, a );
|
||||
this._wantsHashChange = this.options.hashChange !== false;
|
||||
this._wantsPushState = !!this.options.pushState;
|
||||
this._hasPushState = !(!this.options.pushState || !window.history || !window.history.pushState);
|
||||
var a = this.getFragment(), b = document.documentMode;
|
||||
if ( b = D.exec( navigator.userAgent.toLowerCase() ) && (!b || b <= 7) ) {
|
||||
this.iframe = i( '<iframe src="javascript:0" tabindex="-1" />' ).hide().appendTo( "body" )[0].contentWindow, this.navigate( a );
|
||||
}
|
||||
if ( this._hasPushState ) {
|
||||
i( window ).bind( "popstate",
|
||||
this.checkUrl );
|
||||
} else if ( this._wantsHashChange && "onhashchange"in window && !b ) {
|
||||
i( window ).bind( "hashchange", this.checkUrl );
|
||||
} else if ( this._wantsHashChange ) {
|
||||
this._checkUrlInterval = setInterval( this.checkUrl, this.interval );
|
||||
}
|
||||
this.fragment = a;
|
||||
a = window.location;
|
||||
b = a.pathname == this.options.root;
|
||||
if ( this._wantsHashChange && this._wantsPushState && !this._hasPushState && !b ) {
|
||||
return this.fragment = this.getFragment( null, true ), window.location.replace( this.options.root + "#" + this.fragment ), true;
|
||||
} else if ( this._wantsPushState && this._hasPushState &&
|
||||
b && a.hash ) {
|
||||
this.fragment = this.getHash().replace( s, "" ), window.history.replaceState( {}, document.title, a.protocol + "//" + a.host + this.options.root + this.fragment );
|
||||
}
|
||||
if ( !this.options.silent ) {
|
||||
return this.loadUrl()
|
||||
}
|
||||
}, stop : function () {
|
||||
i( window ).unbind( "popstate", this.checkUrl ).unbind( "hashchange", this.checkUrl );
|
||||
clearInterval( this._checkUrlInterval );
|
||||
m.started = false
|
||||
}, route : function ( a, b ) {
|
||||
this.handlers.unshift( {route : a, callback : b} )
|
||||
}, checkUrl : function () {
|
||||
var a = this.getFragment();
|
||||
a == this.fragment && this.iframe && (a = this.getFragment( this.getHash( this.iframe ) ));
|
||||
if ( a == this.fragment ) {
|
||||
return false;
|
||||
}
|
||||
this.iframe && this.navigate( a );
|
||||
this.loadUrl() || this.loadUrl( this.getHash() )
|
||||
}, loadUrl : function ( a ) {
|
||||
var b = this.fragment = this.getFragment( a );
|
||||
return f.any( this.handlers, function ( a ) {
|
||||
if ( a.route.test( b ) ) {
|
||||
return a.callback( b ), true
|
||||
}
|
||||
} )
|
||||
}, navigate : function ( a, b ) {
|
||||
if ( !m.started ) {
|
||||
return false;
|
||||
}
|
||||
if ( !b || b === true ) {
|
||||
b = {trigger : b};
|
||||
}
|
||||
var c = (a || "").replace( s, "" );
|
||||
if ( this.fragment != c ) {
|
||||
this._hasPushState ? (c.indexOf( this.options.root ) != 0 && (c = this.options.root + c), this.fragment = c, window.history[b.replace ?
|
||||
"replaceState" : "pushState"]( {}, document.title, c )) : this._wantsHashChange ? (this.fragment = c, this._updateHash( window.location, c, b.replace ), this.iframe && c != this.getFragment( this.getHash( this.iframe ) ) && (b.replace || this.iframe.document.open().close(), this._updateHash( this.iframe.location, c, b.replace ))) : window.location.assign( this.options.root + a ), b.trigger && this.loadUrl( a )
|
||||
}
|
||||
}, _updateHash : function ( a, b, c ) {
|
||||
c ? a.replace( a.toString().replace( /(javascript:|#).*$/, "" ) + "#" + b ) : a.hash = b
|
||||
}} );
|
||||
var v = g.View = function ( a ) {
|
||||
this.cid =
|
||||
f.uniqueId( "view" );
|
||||
this._configure( a || {} );
|
||||
this._ensureElement();
|
||||
this.initialize.apply( this, arguments );
|
||||
this.delegateEvents()
|
||||
}, E = /^(\S+)\s*(.*)$/, w = "model,collection,el,id,attributes,className,tagName".split( "," );
|
||||
f.extend( v.prototype, l, {tagName : "div", $ : function ( a ) {
|
||||
return this.$el.find( a )
|
||||
}, initialize : function () {
|
||||
}, render : function () {
|
||||
return this
|
||||
}, remove : function () {
|
||||
this.$el.remove();
|
||||
return this
|
||||
}, make : function ( a, b, c ) {
|
||||
a = document.createElement( a );
|
||||
b && i( a ).attr( b );
|
||||
c != null && i( a ).html( c );
|
||||
return a
|
||||
}, setElement : function ( a, b ) {
|
||||
this.$el && this.undelegateEvents();
|
||||
this.$el = a instanceof i ? a : i( a );
|
||||
this.el = this.$el[0];
|
||||
b !== false && this.delegateEvents();
|
||||
return this
|
||||
}, delegateEvents : function ( a ) {
|
||||
if ( a || (a = n( this, "events" )) ) {
|
||||
this.undelegateEvents();
|
||||
for ( var b in a ) {
|
||||
var c = a[b];
|
||||
f.isFunction( c ) || (c = this[a[b]]);
|
||||
if ( !c ) {
|
||||
throw Error( 'Method "' + a[b] + '" does not exist' );
|
||||
}
|
||||
var d = b.match( E ), e = d[1], d = d[2], c = f.bind( c, this );
|
||||
e += ".delegateEvents" + this.cid;
|
||||
d === "" ? this.$el.bind( e, c ) : this.$el.delegate( d, e, c )
|
||||
}
|
||||
}
|
||||
}, undelegateEvents : function () {
|
||||
this.$el.unbind( ".delegateEvents" +
|
||||
this.cid )
|
||||
}, _configure : function ( a ) {
|
||||
this.options && (a = f.extend( {}, this.options, a ));
|
||||
for ( var b = 0, c = w.length; b < c; b++ ) {
|
||||
var d = w[b];
|
||||
a[d] && (this[d] = a[d])
|
||||
}
|
||||
this.options = a
|
||||
}, _ensureElement : function () {
|
||||
if ( this.el ) {
|
||||
this.setElement( this.el, false );
|
||||
} else {
|
||||
var a = n( this, "attributes" ) || {};
|
||||
if ( this.id ) {
|
||||
a.id = this.id;
|
||||
}
|
||||
if ( this.className ) {
|
||||
a["class"] = this.className;
|
||||
}
|
||||
this.setElement( this.make( this.tagName, a ), false )
|
||||
}
|
||||
}} );
|
||||
o.extend = r.extend = u.extend = v.extend = function ( a, b ) {
|
||||
var c = F( this, a, b );
|
||||
c.extend = this.extend;
|
||||
return c
|
||||
};
|
||||
var G = {create : "POST",
|
||||
update : "PUT", "delete" : "DELETE", read : "GET"};
|
||||
g.sync = function ( a, b, c ) {
|
||||
var d = G[a];
|
||||
c || (c = {});
|
||||
var e = {type : d, dataType : "json"};
|
||||
if ( !c.url ) {
|
||||
e.url = n( b, "url" ) || t();
|
||||
}
|
||||
if ( !c.data && b && (a == "create" || a == "update") ) {
|
||||
e.contentType = "application/json", e.data = JSON.stringify( b.toJSON() );
|
||||
}
|
||||
if ( g.emulateJSON ) {
|
||||
e.contentType = "application/x-www-form-urlencoded", e.data = e.data ? {model : e.data} : {};
|
||||
}
|
||||
if ( g.emulateHTTP && (d === "PUT" || d === "DELETE") ) {
|
||||
if ( g.emulateJSON ) {
|
||||
e.data._method = d;
|
||||
}
|
||||
e.type = "POST";
|
||||
e.beforeSend = function ( a ) {
|
||||
a.setRequestHeader( "X-HTTP-Method-Override",
|
||||
d )
|
||||
}
|
||||
}
|
||||
if ( e.type !== "GET" && !g.emulateJSON ) {
|
||||
e.processData = false;
|
||||
}
|
||||
return i.ajax( f.extend( e, c ) )
|
||||
};
|
||||
g.wrapError = function ( a, b, c ) {
|
||||
return function ( d, e ) {
|
||||
e = d === b ? e : d;
|
||||
a ? a( b, e, c ) : b.trigger( "error", b, e, c )
|
||||
}
|
||||
};
|
||||
var x = function () {
|
||||
}, F = function ( a, b, c ) {
|
||||
var d;
|
||||
d = b && b.hasOwnProperty( "constructor" ) ? b.constructor : function () {
|
||||
a.apply( this, arguments )
|
||||
};
|
||||
f.extend( d, a );
|
||||
x.prototype = a.prototype;
|
||||
d.prototype = new x;
|
||||
b && f.extend( d.prototype, b );
|
||||
c && f.extend( d, c );
|
||||
d.prototype.constructor = d;
|
||||
d.__super__ = a.prototype;
|
||||
return d
|
||||
}, n = function ( a, b ) {
|
||||
return!a ||
|
||||
!a[b] ? null : f.isFunction( a[b] ) ? a[b]() : a[b]
|
||||
}, t = function () {
|
||||
throw Error( 'A "url" property or function must be specified' );
|
||||
};
|
||||
return g
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -1,212 +1,212 @@
|
|||
/*
|
||||
machina.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
/*
|
||||
machina.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
|
||||
(function(root, doc, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
(function ( root, doc, factory ) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["underscore"], function(_) {
|
||||
return factory(_, root, doc);
|
||||
});
|
||||
define( ["underscore"], function ( _ ) {
|
||||
return factory( _, root, doc );
|
||||
} );
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(root._, root, doc);
|
||||
factory( root._, root, doc );
|
||||
}
|
||||
}(this, document, function(_, global, document, undefined) {
|
||||
}( this, document, function ( _, global, document, undefined ) {
|
||||
|
||||
var slice = [].slice,
|
||||
NEXT_TRANSITION = "transition",
|
||||
NEXT_HANDLER = "handler",
|
||||
transformEventListToObject = function(eventList){
|
||||
var obj = {};
|
||||
_.each(eventList, function(evntName) {
|
||||
obj[evntName] = [];
|
||||
});
|
||||
return obj;
|
||||
},
|
||||
parseEventListeners = function(evnts) {
|
||||
var obj = evnts;
|
||||
if(_.isArray(evnts)) {
|
||||
obj = transformEventListToObject(evnts);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
NEXT_TRANSITION = "transition",
|
||||
NEXT_HANDLER = "handler",
|
||||
transformEventListToObject = function ( eventList ) {
|
||||
var obj = {};
|
||||
_.each( eventList, function ( evntName ) {
|
||||
obj[evntName] = [];
|
||||
} );
|
||||
return obj;
|
||||
},
|
||||
parseEventListeners = function ( evnts ) {
|
||||
var obj = evnts;
|
||||
if ( _.isArray( evnts ) ) {
|
||||
obj = transformEventListToObject( evnts );
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
var utils = {
|
||||
makeFsmNamespace: (function(){
|
||||
var machinaCount = 0;
|
||||
return function() {
|
||||
return "fsm." + machinaCount++;
|
||||
};
|
||||
})(),
|
||||
getDefaultOptions: function() {
|
||||
return {
|
||||
initialState: "uninitialized",
|
||||
eventListeners: {
|
||||
"*" : []
|
||||
},
|
||||
states: {},
|
||||
eventQueue: [],
|
||||
namespace: utils.makeFsmNamespace()
|
||||
};
|
||||
}
|
||||
};
|
||||
var Fsm = function(options) {
|
||||
var opt, initialState, defaults = utils.getDefaultOptions();
|
||||
if(options) {
|
||||
if(options.eventListeners) {
|
||||
options.eventListeners = parseEventListeners(options.eventListeners);
|
||||
makeFsmNamespace : (function () {
|
||||
var machinaCount = 0;
|
||||
return function () {
|
||||
return "fsm." + machinaCount++;
|
||||
};
|
||||
})(),
|
||||
getDefaultOptions : function () {
|
||||
return {
|
||||
initialState : "uninitialized",
|
||||
eventListeners : {
|
||||
"*" : []
|
||||
},
|
||||
states : {},
|
||||
eventQueue : [],
|
||||
namespace : utils.makeFsmNamespace()
|
||||
};
|
||||
}
|
||||
if(options.messaging) {
|
||||
options.messaging = _.extend({}, defaults.messaging, options.messaging);
|
||||
}
|
||||
}
|
||||
opt = _.extend(defaults , options || {});
|
||||
initialState = opt.initialState;
|
||||
delete opt.initialState;
|
||||
_.extend(this,opt);
|
||||
|
||||
this.state = undefined;
|
||||
this._priorAction = "";
|
||||
this._currentAction = "";
|
||||
if(initialState) {
|
||||
this.transition(initialState);
|
||||
}
|
||||
machina.fireEvent("newFsm", this);
|
||||
};
|
||||
|
||||
Fsm.prototype.fireEvent = function(eventName) {
|
||||
var args = arguments;
|
||||
_.each(this.eventListeners["*"], function(callback) {
|
||||
try {
|
||||
callback.apply(this,slice.call(args, 0));
|
||||
} catch(exception) {
|
||||
if(console && typeof console.log !== "undefined") {
|
||||
console.log(exception.toString());
|
||||
};
|
||||
var Fsm = function ( options ) {
|
||||
var opt, initialState, defaults = utils.getDefaultOptions();
|
||||
if ( options ) {
|
||||
if ( options.eventListeners ) {
|
||||
options.eventListeners = parseEventListeners( options.eventListeners );
|
||||
}
|
||||
if ( options.messaging ) {
|
||||
options.messaging = _.extend( {}, defaults.messaging, options.messaging );
|
||||
}
|
||||
}
|
||||
});
|
||||
if(this.eventListeners[eventName]) {
|
||||
_.each(this.eventListeners[eventName], function(callback) {
|
||||
try {
|
||||
callback.apply(this,slice.call(args, 1));
|
||||
} catch(exception) {
|
||||
if(console && typeof console.log !== "undefined") {
|
||||
console.log(exception.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
opt = _.extend( defaults, options || {} );
|
||||
initialState = opt.initialState;
|
||||
delete opt.initialState;
|
||||
_.extend( this, opt );
|
||||
|
||||
Fsm.prototype.handle = function(msgType) {
|
||||
// vars to avoid a "this." fest
|
||||
var states = this.states, current = this.state, args = slice.call(arguments,0), handlerName;
|
||||
this.currentActionArgs = args;
|
||||
if(states[current] && (states[current][msgType] || states[current]["*"])) {
|
||||
handlerName = states[current][msgType] ? msgType : "*";
|
||||
this._currentAction = current + "." + handlerName;
|
||||
this.fireEvent.apply(this, ["Handling"].concat(args));
|
||||
states[current][handlerName].apply(this, args.slice(1));
|
||||
this.fireEvent.apply(this, ["Handled"].concat(args));
|
||||
this._priorAction = this._currentAction;
|
||||
this._currentAction = "";
|
||||
this.processQueue(NEXT_HANDLER);
|
||||
}
|
||||
else {
|
||||
this.fireEvent.apply(this, ["NoHandler"].concat(args));
|
||||
}
|
||||
this.currentActionArgs = undefined;
|
||||
};
|
||||
this.state = undefined;
|
||||
this._priorAction = "";
|
||||
this._currentAction = "";
|
||||
if ( initialState ) {
|
||||
this.transition( initialState );
|
||||
}
|
||||
machina.fireEvent( "newFsm", this );
|
||||
};
|
||||
|
||||
Fsm.prototype.transition = function(newState) {
|
||||
if(this.states[newState]){
|
||||
var oldState = this.state;
|
||||
this.state = newState;
|
||||
if(this.states[newState]._onEnter) {
|
||||
this.states[newState]._onEnter.call( this );
|
||||
}
|
||||
this.fireEvent.apply(this, ["Transitioned", oldState, this.state ]);
|
||||
this.processQueue(NEXT_TRANSITION);
|
||||
return;
|
||||
}
|
||||
this.fireEvent.apply(this, ["InvalidState", this.state, newState ]);
|
||||
};
|
||||
Fsm.prototype.fireEvent = function ( eventName ) {
|
||||
var args = arguments;
|
||||
_.each( this.eventListeners["*"], function ( callback ) {
|
||||
try {
|
||||
callback.apply( this, slice.call( args, 0 ) );
|
||||
} catch ( exception ) {
|
||||
if ( console && typeof console.log !== "undefined" ) {
|
||||
console.log( exception.toString() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
_.each( this.eventListeners[eventName], function ( callback ) {
|
||||
try {
|
||||
callback.apply( this, slice.call( args, 1 ) );
|
||||
} catch ( exception ) {
|
||||
if ( console && typeof console.log !== "undefined" ) {
|
||||
console.log( exception.toString() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.processQueue = function(type) {
|
||||
var filterFn = type === NEXT_TRANSITION ?
|
||||
function(item){
|
||||
return item.type === NEXT_TRANSITION && ((!item.untilState) || (item.untilState === this.state));
|
||||
} :
|
||||
function(item) {
|
||||
return item.type === NEXT_HANDLER;
|
||||
},
|
||||
toProcess = _.filter(this.eventQueue, filterFn, this);
|
||||
this.eventQueue = _.difference(this.eventQueue, toProcess);
|
||||
_.each(toProcess, function(item, index){
|
||||
this.handle.apply(this, item.args);
|
||||
}, this);
|
||||
};
|
||||
Fsm.prototype.handle = function ( msgType ) {
|
||||
// vars to avoid a "this." fest
|
||||
var states = this.states, current = this.state, args = slice.call( arguments, 0 ), handlerName;
|
||||
this.currentActionArgs = args;
|
||||
if ( states[current] && (states[current][msgType] || states[current]["*"]) ) {
|
||||
handlerName = states[current][msgType] ? msgType : "*";
|
||||
this._currentAction = current + "." + handlerName;
|
||||
this.fireEvent.apply( this, ["Handling"].concat( args ) );
|
||||
states[current][handlerName].apply( this, args.slice( 1 ) );
|
||||
this.fireEvent.apply( this, ["Handled"].concat( args ) );
|
||||
this._priorAction = this._currentAction;
|
||||
this._currentAction = "";
|
||||
this.processQueue( NEXT_HANDLER );
|
||||
}
|
||||
else {
|
||||
this.fireEvent.apply( this, ["NoHandler"].concat( args ) );
|
||||
}
|
||||
this.currentActionArgs = undefined;
|
||||
};
|
||||
|
||||
Fsm.prototype.deferUntilTransition = function(stateName) {
|
||||
if(this.currentActionArgs) {
|
||||
var queued = { type: NEXT_TRANSITION, untilState: stateName, args: this.currentActionArgs };
|
||||
this.eventQueue.push(queued);
|
||||
this.fireEvent.apply(this, [ "Deferred", this.state, queued ]);
|
||||
}
|
||||
};
|
||||
Fsm.prototype.transition = function ( newState ) {
|
||||
if ( this.states[newState] ) {
|
||||
var oldState = this.state;
|
||||
this.state = newState;
|
||||
if ( this.states[newState]._onEnter ) {
|
||||
this.states[newState]._onEnter.call( this );
|
||||
}
|
||||
this.fireEvent.apply( this, ["Transitioned", oldState, this.state ] );
|
||||
this.processQueue( NEXT_TRANSITION );
|
||||
return;
|
||||
}
|
||||
this.fireEvent.apply( this, ["InvalidState", this.state, newState ] );
|
||||
};
|
||||
|
||||
Fsm.prototype.deferUntilNextHandler = function() {
|
||||
if(this.currentActionArgs) {
|
||||
var queued = { type: NEXT_TRANSITION, args: this.currentActionArgs };
|
||||
this.eventQueue.push(queued);
|
||||
this.fireEvent.apply(this, [ "Deferred", this.state, queued ]);
|
||||
}
|
||||
};
|
||||
Fsm.prototype.processQueue = function ( type ) {
|
||||
var filterFn = type === NEXT_TRANSITION ?
|
||||
function ( item ) {
|
||||
return item.type === NEXT_TRANSITION && ((!item.untilState) || (item.untilState === this.state));
|
||||
} :
|
||||
function ( item ) {
|
||||
return item.type === NEXT_HANDLER;
|
||||
},
|
||||
toProcess = _.filter( this.eventQueue, filterFn, this );
|
||||
this.eventQueue = _.difference( this.eventQueue, toProcess );
|
||||
_.each( toProcess, function ( item, index ) {
|
||||
this.handle.apply( this, item.args );
|
||||
}, this );
|
||||
};
|
||||
|
||||
Fsm.prototype.on = function(eventName, callback) {
|
||||
if(!this.eventListeners[eventName]) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push(callback);
|
||||
};
|
||||
Fsm.prototype.deferUntilTransition = function ( stateName ) {
|
||||
if ( this.currentActionArgs ) {
|
||||
var queued = { type : NEXT_TRANSITION, untilState : stateName, args : this.currentActionArgs };
|
||||
this.eventQueue.push( queued );
|
||||
this.fireEvent.apply( this, [ "Deferred", this.state, queued ] );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.off = function(eventName, callback) {
|
||||
if(this.eventListeners[eventName]){
|
||||
this.eventListeners[eventName] = _.without(this.eventListeners[eventName], callback);
|
||||
}
|
||||
};
|
||||
Fsm.prototype.deferUntilNextHandler = function () {
|
||||
if ( this.currentActionArgs ) {
|
||||
var queued = { type : NEXT_TRANSITION, args : this.currentActionArgs };
|
||||
this.eventQueue.push( queued );
|
||||
this.fireEvent.apply( this, [ "Deferred", this.state, queued ] );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.on = function ( eventName, callback ) {
|
||||
if ( !this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push( callback );
|
||||
};
|
||||
|
||||
Fsm.prototype.off = function ( eventName, callback ) {
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = _.without( this.eventListeners[eventName], callback );
|
||||
}
|
||||
};
|
||||
|
||||
var machina = {
|
||||
Fsm: Fsm,
|
||||
bus: undefined,
|
||||
utils: utils,
|
||||
on: function(eventName, callback) {
|
||||
if(!this.eventListeners[eventName]) {
|
||||
Fsm : Fsm,
|
||||
bus : undefined,
|
||||
utils : utils,
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push(callback);
|
||||
this.eventListeners[eventName].push( callback );
|
||||
},
|
||||
off: function(eventName, callback) {
|
||||
if(this.eventListeners[eventName]){
|
||||
this.eventListeners[eventName] = _.without(this.eventListeners[eventName], callback);
|
||||
off : function ( eventName, callback ) {
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = _.without( this.eventListeners[eventName], callback );
|
||||
}
|
||||
},
|
||||
fireEvent: function(eventName) {
|
||||
fireEvent : function ( eventName ) {
|
||||
var i = 0, len, args = arguments, listeners = this.eventListeners[eventName];
|
||||
if(listeners && listeners.length) {
|
||||
_.each(listeners, function(callback) {
|
||||
callback.apply(null,slice.call(args, 1));
|
||||
});
|
||||
if ( listeners && listeners.length ) {
|
||||
_.each( listeners, function ( callback ) {
|
||||
callback.apply( null, slice.call( args, 1 ) );
|
||||
} );
|
||||
}
|
||||
},
|
||||
eventListeners: {
|
||||
eventListeners : {
|
||||
newFsm : []
|
||||
}
|
||||
};
|
||||
|
||||
global.machina = machina;
|
||||
return machina;
|
||||
}));
|
||||
} ));
|
||||
|
|
@ -47,7 +47,9 @@ define( [ "postal", "underscore" ], function ( postal, _, undefined ) {
|
|||
}
|
||||
} );
|
||||
|
||||
postal.diagnostics = {
|
||||
postal.diagnostics = postal.diagnostics || {};
|
||||
|
||||
postal.diagnostics.console = {
|
||||
clearFilters : function () {
|
||||
filters = [];
|
||||
},
|
||||
|
|
@ -60,13 +62,13 @@ define( [ "postal", "underscore" ], function ( postal, _, undefined ) {
|
|||
if ( !_.isArray( constraint ) ) {
|
||||
constraint = [ constraint ];
|
||||
}
|
||||
_.each( constraint, function( item ){
|
||||
_.each( constraint, function ( item ) {
|
||||
if ( filters.length === 0 || !_.any( filters, function ( filter ) {
|
||||
return _.isEqual( filter, item );
|
||||
} ) ) {
|
||||
filters.push( item );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
},
|
||||
getCurrentFilters : function () {
|
||||
|
|
|
|||
|
|
@ -1,225 +1,228 @@
|
|||
/*
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
*/
|
||||
|
||||
// This is the amd-module version of postal.js
|
||||
// If you need the standard lib style version, go to http://github.com/ifandelse/postal.js
|
||||
define(["underscore"], function(_, undefined) {
|
||||
define( ["underscore"], function ( _, undefined ) {
|
||||
|
||||
var DEFAULT_CHANNEL = "/",
|
||||
DEFAULT_PRIORITY = 50,
|
||||
DEFAULT_DISPOSEAFTER = 0,
|
||||
SYSTEM_CHANNEL = "postal",
|
||||
NO_OP = function() { };
|
||||
NO_OP = function () {
|
||||
};
|
||||
|
||||
var DistinctPredicate = function() {
|
||||
var DistinctPredicate = function () {
|
||||
var previous;
|
||||
return function(data) {
|
||||
return function ( data ) {
|
||||
var eq = false;
|
||||
if(_.isString(data)) {
|
||||
if ( _.isString( data ) ) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
eq = _.isEqual( data, previous );
|
||||
previous = _.clone( data );
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var ChannelDefinition = function(channelName, defaultTopic) {
|
||||
var ChannelDefinition = function ( channelName, defaultTopic ) {
|
||||
this.channel = channelName || DEFAULT_CHANNEL;
|
||||
this._topic = defaultTopic || "";
|
||||
};
|
||||
|
||||
ChannelDefinition.prototype = {
|
||||
subscribe: function() {
|
||||
subscribe : function () {
|
||||
var len = arguments.length;
|
||||
if(len === 1) {
|
||||
return new SubscriptionDefinition(this.channel, this._topic, arguments[0]);
|
||||
if ( len === 1 ) {
|
||||
return new SubscriptionDefinition( this.channel, this._topic, arguments[0] );
|
||||
}
|
||||
else if (len === 2) {
|
||||
return new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
|
||||
else if ( len === 2 ) {
|
||||
return new SubscriptionDefinition( this.channel, arguments[0], arguments[1] );
|
||||
}
|
||||
},
|
||||
|
||||
publish: function(obj) {
|
||||
publish : function ( obj ) {
|
||||
var envelope = {
|
||||
channel: this.channel,
|
||||
topic: this._topic,
|
||||
data: obj || {}
|
||||
channel : this.channel,
|
||||
topic : this._topic,
|
||||
data : obj || {}
|
||||
};
|
||||
// If this is an envelope....
|
||||
if( obj.topic && obj.data ) {
|
||||
if ( obj.topic && obj.data ) {
|
||||
envelope = obj;
|
||||
envelope.channel = envelope.channel || this.channel;
|
||||
}
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
|
||||
topic: function(topic) {
|
||||
if(topic === this._topic) {
|
||||
topic : function ( topic ) {
|
||||
if ( topic === this._topic ) {
|
||||
return this;
|
||||
}
|
||||
return new ChannelDefinition(this.channel, topic);
|
||||
return new ChannelDefinition( this.channel, topic );
|
||||
}
|
||||
};
|
||||
|
||||
var SubscriptionDefinition = function(channel, topic, callback) {
|
||||
var SubscriptionDefinition = function ( channel, topic, callback ) {
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.callback = callback;
|
||||
this.priority = DEFAULT_PRIORITY;
|
||||
this.constraints = new Array(0);
|
||||
this.constraints = new Array( 0 );
|
||||
this.maxCalls = DEFAULT_DISPOSEAFTER;
|
||||
this.onHandled = NO_OP;
|
||||
this.context = null;
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.created",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.created",
|
||||
channel: channel,
|
||||
topic: topic
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.created",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.created",
|
||||
channel : channel,
|
||||
topic : topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
postal.configuration.bus.subscribe(this);
|
||||
postal.configuration.bus.subscribe( this );
|
||||
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function() {
|
||||
postal.configuration.bus.unsubscribe(this);
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.removed",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.removed",
|
||||
channel: this.channel,
|
||||
topic: this.topic
|
||||
unsubscribe : function () {
|
||||
postal.configuration.bus.unsubscribe( this );
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.removed",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.removed",
|
||||
channel : this.channel,
|
||||
topic : this.topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
defer: function() {
|
||||
defer : function () {
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(fn,0,data);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( fn, 0, data );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
disposeAfter: function(maxCalls) {
|
||||
if(_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
disposeAfter : function ( maxCalls ) {
|
||||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
|
||||
var fn = this.onHandled;
|
||||
var dispose = _.after(maxCalls, _.bind(function() {
|
||||
this.unsubscribe(this);
|
||||
}, this));
|
||||
var dispose = _.after( maxCalls, _.bind( function () {
|
||||
this.unsubscribe( this );
|
||||
}, this ) );
|
||||
|
||||
this.onHandled = function() {
|
||||
fn.apply(this.context, arguments);
|
||||
this.onHandled = function () {
|
||||
fn.apply( this.context, arguments );
|
||||
dispose();
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
ignoreDuplicates: function() {
|
||||
this.withConstraint(new DistinctPredicate());
|
||||
ignoreDuplicates : function () {
|
||||
this.withConstraint( new DistinctPredicate() );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraint: function(predicate) {
|
||||
if(! _.isFunction(predicate)) {
|
||||
withConstraint : function ( predicate ) {
|
||||
if ( !_.isFunction( predicate ) ) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
this.constraints.push(predicate);
|
||||
this.constraints.push( predicate );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraints: function(predicates) {
|
||||
withConstraints : function ( predicates ) {
|
||||
var self = this;
|
||||
if(_.isArray(predicates)) {
|
||||
_.each(predicates, function(predicate) { self.withConstraint(predicate); } );
|
||||
if ( _.isArray( predicates ) ) {
|
||||
_.each( predicates, function ( predicate ) {
|
||||
self.withConstraint( predicate );
|
||||
} );
|
||||
}
|
||||
return self;
|
||||
},
|
||||
|
||||
withContext: function(context) {
|
||||
withContext : function ( context ) {
|
||||
this.context = context;
|
||||
return this;
|
||||
},
|
||||
|
||||
withDebounce: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDebounce : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.debounce(fn, milliseconds);
|
||||
this.callback = _.debounce( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
withDelay: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDelay : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(function(){
|
||||
fn(data);
|
||||
}, milliseconds);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( function () {
|
||||
fn( data );
|
||||
}, milliseconds );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
withPriority: function(priority) {
|
||||
if(_.isNaN(priority)) {
|
||||
withPriority : function ( priority ) {
|
||||
if ( _.isNaN( priority ) ) {
|
||||
throw "Priority must be a number";
|
||||
}
|
||||
this.priority = priority;
|
||||
return this;
|
||||
},
|
||||
|
||||
withThrottle: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withThrottle : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.throttle(fn, milliseconds);
|
||||
this.callback = _.throttle( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
subscribe: function(callback) {
|
||||
subscribe : function ( callback ) {
|
||||
this.callback = callback;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
var bindingsResolver = {
|
||||
cache: { },
|
||||
cache : { },
|
||||
|
||||
compare: function(binding, topic) {
|
||||
if(this.cache[topic] && this.cache[topic][binding]) {
|
||||
compare : function ( binding, topic ) {
|
||||
if ( this.cache[topic] && this.cache[topic][binding] ) {
|
||||
return true;
|
||||
}
|
||||
// binding.replace(/\./g,"\\.") // escape actual periods
|
||||
// .replace(/\*/g, ".*") // asterisks match any value
|
||||
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
|
||||
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
|
||||
result = rgx.test(topic);
|
||||
if(result) {
|
||||
if(!this.cache[topic]) {
|
||||
var rgx = new RegExp( "^" + binding.replace( /\./g, "\\." ).replace( /\*/g, ".*" ).replace( /#/g, "[A-Z,a-z,0-9]*" ) + "$" ),
|
||||
result = rgx.test( topic );
|
||||
if ( result ) {
|
||||
if ( !this.cache[topic] ) {
|
||||
this.cache[topic] = {};
|
||||
}
|
||||
this.cache[topic][binding] = true;
|
||||
|
|
@ -227,91 +230,93 @@ var bindingsResolver = {
|
|||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
this.cache = {};
|
||||
}
|
||||
};
|
||||
|
||||
var localBus = {
|
||||
|
||||
addWireTap: function(callback) {
|
||||
addWireTap : function ( callback ) {
|
||||
var self = this;
|
||||
self.wireTaps.push(callback);
|
||||
return function() {
|
||||
var idx = self.wireTaps.indexOf(callback);
|
||||
if(idx !== -1) {
|
||||
self.wireTaps.splice(idx,1);
|
||||
self.wireTaps.push( callback );
|
||||
return function () {
|
||||
var idx = self.wireTaps.indexOf( callback );
|
||||
if ( idx !== -1 ) {
|
||||
self.wireTaps.splice( idx, 1 );
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
publish: function(envelope) {
|
||||
_.each(this.wireTaps,function(tap) {
|
||||
tap(envelope.data, envelope);
|
||||
});
|
||||
publish : function ( envelope ) {
|
||||
_.each( this.wireTaps, function ( tap ) {
|
||||
tap( envelope.data, envelope );
|
||||
} );
|
||||
|
||||
_.each(this.subscriptions[envelope.channel], function(topic) {
|
||||
_.each(topic, function(subDef){
|
||||
if(postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
||||
if(_.all(subDef.constraints, function(constraint) { return constraint(envelope.data,envelope); })) {
|
||||
if(typeof subDef.callback === 'function') {
|
||||
subDef.callback.apply(subDef.context, [envelope.data, envelope]);
|
||||
_.each( this.subscriptions[envelope.channel], function ( topic ) {
|
||||
_.each( topic, function ( subDef ) {
|
||||
if ( postal.configuration.resolver.compare( subDef.topic, envelope.topic ) ) {
|
||||
if ( _.all( subDef.constraints, function ( constraint ) {
|
||||
return constraint( envelope.data, envelope );
|
||||
} ) ) {
|
||||
if ( typeof subDef.callback === 'function' ) {
|
||||
subDef.callback.apply( subDef.context, [envelope.data, envelope] );
|
||||
subDef.onHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if( this.subscriptions ) {
|
||||
_.each( this.subscriptions , function( channel ){
|
||||
_.each( channel, function( topic ){
|
||||
while( topic.length ) {
|
||||
reset : function () {
|
||||
if ( this.subscriptions ) {
|
||||
_.each( this.subscriptions, function ( channel ) {
|
||||
_.each( channel, function ( topic ) {
|
||||
while ( topic.length ) {
|
||||
topic.pop().unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
this.subscriptions = {};
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(subDef) {
|
||||
subscribe : function ( subDef ) {
|
||||
var idx, found, fn, channel = this.subscriptions[subDef.channel], subs;
|
||||
|
||||
if(!channel) {
|
||||
if ( !channel ) {
|
||||
channel = this.subscriptions[subDef.channel] = {};
|
||||
}
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
||||
if(!subs) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array(0);
|
||||
if ( !subs ) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array( 0 );
|
||||
}
|
||||
|
||||
idx = subs.length - 1;
|
||||
for(; idx >= 0; idx--) {
|
||||
if(subs[idx].priority <= subDef.priority) {
|
||||
subs.splice(idx + 1, 0, subDef);
|
||||
for ( ; idx >= 0; idx-- ) {
|
||||
if ( subs[idx].priority <= subDef.priority ) {
|
||||
subs.splice( idx + 1, 0, subDef );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
subs.unshift(subDef);
|
||||
if ( !found ) {
|
||||
subs.unshift( subDef );
|
||||
}
|
||||
return subDef;
|
||||
},
|
||||
|
||||
subscriptions: {},
|
||||
subscriptions : {},
|
||||
|
||||
wireTaps: new Array(0),
|
||||
wireTaps : new Array( 0 ),
|
||||
|
||||
unsubscribe: function(config) {
|
||||
if(this.subscriptions[config.channel][config.topic]) {
|
||||
unsubscribe : function ( config ) {
|
||||
if ( this.subscriptions[config.channel][config.topic] ) {
|
||||
var len = this.subscriptions[config.channel][config.topic].length,
|
||||
idx = 0;
|
||||
for ( ; idx < len; idx++ ) {
|
||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
||||
if ( this.subscriptions[config.channel][config.topic][idx] === config ) {
|
||||
this.subscriptions[config.channel][config.topic].splice( idx, 1 );
|
||||
break;
|
||||
}
|
||||
|
|
@ -321,50 +326,50 @@ var localBus = {
|
|||
};
|
||||
|
||||
var publishPicker = {
|
||||
"1" : function(envelope) {
|
||||
if(!envelope) {
|
||||
throw new Error("publishing from the 'global' postal.publish call requires a valid envelope.");
|
||||
"1" : function ( envelope ) {
|
||||
if ( !envelope ) {
|
||||
throw new Error( "publishing from the 'global' postal.publish call requires a valid envelope." );
|
||||
}
|
||||
envelope.channel = envelope.channel || DEFAULT_CHANNEL;
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
return envelope;
|
||||
},
|
||||
"2" : function(topic, data) {
|
||||
var envelope = { channel: DEFAULT_CHANNEL, topic: topic, timeStamp: new Date(), data: data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function(channel, topic, data) {
|
||||
var envelope = { channel: channel, topic: topic, timeStamp: new Date(), data: data };
|
||||
"2" : function ( topic, data ) {
|
||||
var envelope = { channel : DEFAULT_CHANNEL, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function ( channel, topic, data ) {
|
||||
var envelope = { channel : channel, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
}
|
||||
},
|
||||
channelPicker = {
|
||||
"1" : function( chn ) {
|
||||
"1" : function ( chn ) {
|
||||
var channel = chn, topic, options = {};
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
}
|
||||
else {
|
||||
channel = chn.channel || DEFAULT_CHANNEL;
|
||||
topic = chn.topic;
|
||||
topic = chn.topic;
|
||||
options = chn.options || options;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"2" : function( chn, tpc ) {
|
||||
"2" : function ( chn, tpc ) {
|
||||
var channel = chn, topic = tpc, options = {};
|
||||
if( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
if ( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
options = tpc;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"3" : function( channel, topic, options ) {
|
||||
"3" : function ( channel, topic, options ) {
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
}
|
||||
},
|
||||
|
|
@ -374,110 +379,110 @@ var publishPicker = {
|
|||
localBus.subscriptions[SYSTEM_CHANNEL] = {};
|
||||
|
||||
var postal = {
|
||||
configuration: {
|
||||
bus: localBus,
|
||||
resolver: bindingsResolver,
|
||||
getSessionIdAction: function( callback ) {
|
||||
configuration : {
|
||||
bus : localBus,
|
||||
resolver : bindingsResolver,
|
||||
getSessionIdAction : function ( callback ) {
|
||||
callback( sessionInfo );
|
||||
},
|
||||
setSessionIdAction: function( info, callback ) {
|
||||
setSessionIdAction : function ( info, callback ) {
|
||||
sessionInfo = info;
|
||||
callback( sessionInfo );
|
||||
},
|
||||
DEFAULT_CHANNEL: DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY: DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER: DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL: SYSTEM_CHANNEL
|
||||
DEFAULT_CHANNEL : DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY : DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER : DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL : SYSTEM_CHANNEL
|
||||
},
|
||||
|
||||
channelTypes: {
|
||||
local: ChannelDefinition
|
||||
channelTypes : {
|
||||
local : ChannelDefinition
|
||||
},
|
||||
|
||||
channel: function() {
|
||||
channel : function () {
|
||||
var len = arguments.length;
|
||||
if(channelPicker[len]) {
|
||||
return channelPicker[len].apply(this, arguments);
|
||||
if ( channelPicker[len] ) {
|
||||
return channelPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(options) {
|
||||
subscribe : function ( options ) {
|
||||
var callback = options.callback,
|
||||
topic = options.topic,
|
||||
channel = options.channel || DEFAULT_CHANNEL;
|
||||
return new SubscriptionDefinition(channel, topic, callback);
|
||||
return new SubscriptionDefinition( channel, topic, callback );
|
||||
},
|
||||
|
||||
publish: function() {
|
||||
publish : function () {
|
||||
var len = arguments.length;
|
||||
if(publishPicker[len]) {
|
||||
return publishPicker[len].apply(this, arguments);
|
||||
if ( publishPicker[len] ) {
|
||||
return publishPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
addWireTap: function(callback) {
|
||||
return this.configuration.bus.addWireTap(callback);
|
||||
addWireTap : function ( callback ) {
|
||||
return this.configuration.bus.addWireTap( callback );
|
||||
},
|
||||
|
||||
linkChannels: function(sources, destinations) {
|
||||
linkChannels : function ( sources, destinations ) {
|
||||
var result = [];
|
||||
if(!_.isArray(sources)) {
|
||||
if ( !_.isArray( sources ) ) {
|
||||
sources = [sources];
|
||||
}
|
||||
if(!_.isArray(destinations)) {
|
||||
if ( !_.isArray( destinations ) ) {
|
||||
destinations = [destinations];
|
||||
}
|
||||
_.each(sources, function(source){
|
||||
_.each( sources, function ( source ) {
|
||||
var sourceTopic = source.topic || "*";
|
||||
_.each(destinations, function(destination) {
|
||||
_.each( destinations, function ( destination ) {
|
||||
var destChannel = destination.channel || DEFAULT_CHANNEL;
|
||||
result.push(
|
||||
postal.subscribe({
|
||||
channel: source.channel || DEFAULT_CHANNEL,
|
||||
topic: source.topic || "*",
|
||||
callback : function(data, env) {
|
||||
postal.subscribe( {
|
||||
channel : source.channel || DEFAULT_CHANNEL,
|
||||
topic : source.topic || "*",
|
||||
callback : function ( data, env ) {
|
||||
var newEnv = env;
|
||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
||||
newEnv.topic = _.isFunction( destination.topic ) ? destination.topic( env.topic ) : destination.topic || env.topic;
|
||||
newEnv.channel = destChannel;
|
||||
newEnv.data = data;
|
||||
postal.publish(newEnv);
|
||||
postal.publish( newEnv );
|
||||
}
|
||||
})
|
||||
} )
|
||||
);
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
return result;
|
||||
},
|
||||
|
||||
utils: {
|
||||
getSessionId: function( callback ) {
|
||||
utils : {
|
||||
getSessionId : function ( callback ) {
|
||||
postal.configuration.getSessionIdAction.call( this, callback );
|
||||
},
|
||||
|
||||
setSessionId: function( value, callback ) {
|
||||
postal.utils.getSessionId( function( info ) {
|
||||
setSessionId : function ( value, callback ) {
|
||||
postal.utils.getSessionId( function ( info ) {
|
||||
// get the session info to move id to last id
|
||||
info.lastId = info.id;
|
||||
info.id = value;
|
||||
// invoke the callback the user provided to handle storing session
|
||||
postal.configuration.setSessionIdAction( info, function( session ) {
|
||||
postal.configuration.setSessionIdAction( info, function ( session ) {
|
||||
callback( session );
|
||||
// publish postal event msg about the change
|
||||
postal.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "sessionId.changed",
|
||||
data: session
|
||||
});
|
||||
postal.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "sessionId.changed",
|
||||
data : session
|
||||
} );
|
||||
} );
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
getSubscribersFor: function() {
|
||||
getSubscribersFor : function () {
|
||||
var channel = arguments[ 0 ],
|
||||
tpc = arguments[ 1 ],
|
||||
result = [];
|
||||
if( arguments.length === 1 ) {
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( arguments.length === 1 ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = postal.configuration.DEFAULT_CHANNEL;
|
||||
tpc = arguments[ 0 ];
|
||||
}
|
||||
|
|
@ -486,14 +491,14 @@ var postal = {
|
|||
tpc = arguments[ 0 ].topic;
|
||||
}
|
||||
}
|
||||
if( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc )) {
|
||||
if ( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc ) ) {
|
||||
result = postal.configuration.bus.subscriptions[ channel ][ tpc ];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
postal.configuration.bus.reset();
|
||||
postal.configuration.resolver.reset();
|
||||
}
|
||||
|
|
@ -501,4 +506,4 @@ var postal = {
|
|||
};
|
||||
|
||||
return postal;
|
||||
});
|
||||
} );
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,10 +2,116 @@
|
|||
RequireJS text 1.0.2 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
|
||||
Available via the MIT or new BSD license.
|
||||
see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
(function(){var k=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],n=/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,o=/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,i=typeof location!=="undefined"&&location.href,p=i&&location.protocol&&location.protocol.replace(/\:/,""),q=i&&location.hostname,r=i&&(location.port||void 0),j=[];define(function(){var g,h,l;typeof window!=="undefined"&&window.navigator&&window.document?h=function(a,c){var b=g.createXhr();b.open("GET",a,!0);b.onreadystatechange=
|
||||
function(){b.readyState===4&&c(b.responseText)};b.send(null)}:typeof process!=="undefined"&&process.versions&&process.versions.node?(l=require.nodeRequire("fs"),h=function(a,c){c(l.readFileSync(a,"utf8"))}):typeof Packages!=="undefined"&&(h=function(a,c){var b=new java.io.File(a),e=java.lang.System.getProperty("line.separator"),b=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(b),"utf-8")),d,f,g="";try{d=new java.lang.StringBuffer;(f=b.readLine())&&f.length()&&
|
||||
f.charAt(0)===65279&&(f=f.substring(1));for(d.append(f);(f=b.readLine())!==null;)d.append(e),d.append(f);g=String(d.toString())}finally{b.close()}c(g)});return g={version:"1.0.2",strip:function(a){if(a){var a=a.replace(n,""),c=a.match(o);c&&(a=c[1])}else a="";return a},jsEscape:function(a){return a.replace(/(['\\])/g,"\\$1").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r")},createXhr:function(){var a,c,b;if(typeof XMLHttpRequest!==
|
||||
"undefined")return new XMLHttpRequest;else for(c=0;c<3;c++){b=k[c];try{a=new ActiveXObject(b)}catch(e){}if(a){k=[b];break}}if(!a)throw Error("createXhr(): XMLHttpRequest not available");return a},get:h,parseName:function(a){var c=!1,b=a.indexOf("."),e=a.substring(0,b),a=a.substring(b+1,a.length),b=a.indexOf("!");b!==-1&&(c=a.substring(b+1,a.length),c=c==="strip",a=a.substring(0,b));return{moduleName:e,ext:a,strip:c}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,useXhr:function(a,c,b,e){var d=g.xdRegExp.exec(a),
|
||||
f;if(!d)return!0;a=d[2];d=d[3];d=d.split(":");f=d[1];d=d[0];return(!a||a===c)&&(!d||d===b)&&(!f&&!d||f===e)},finishLoad:function(a,c,b,e,d){b=c?g.strip(b):b;d.isBuild&&(j[a]=b);e(b)},load:function(a,c,b,e){if(e.isBuild&&!e.inlineText)b();else{var d=g.parseName(a),f=d.moduleName+"."+d.ext,m=c.toUrl(f),h=e&&e.text&&e.text.useXhr||g.useXhr;!i||h(m,p,q,r)?g.get(m,function(c){g.finishLoad(a,d.strip,c,b,e)}):c([f],function(a){g.finishLoad(d.moduleName+"."+d.ext,d.strip,a,b,e)})}},write:function(a,c,b){if(c in
|
||||
j){var e=g.jsEscape(j[c]);b.asModule(a+"!"+c,"define(function () { return '"+e+"';});\n")}},writeFile:function(a,c,b,e,d){var c=g.parseName(c),f=c.moduleName+"."+c.ext,h=b.toUrl(c.moduleName+"."+c.ext)+".js";g.load(f,b,function(){var b=function(a){return e(h,a)};b.asModule=function(a,b){return e.asModule(a,h,b)};g.write(a,f,b,d)},d)}}})})();
|
||||
*/
|
||||
(function () {
|
||||
var k = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP", "Msxml2.XMLHTTP.4.0"], n = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, o = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im, i = typeof location !== "undefined" && location.href, p = i && location.protocol && location.protocol.replace( /\:/, "" ), q = i && location.hostname, r = i && (location.port || void 0), j = [];
|
||||
define( function () {
|
||||
var g, h, l;
|
||||
typeof window !== "undefined" && window.navigator && window.document ? h = function ( a, c ) {
|
||||
var b = g.createXhr();
|
||||
b.open( "GET", a, !0 );
|
||||
b.onreadystatechange =
|
||||
function () {
|
||||
b.readyState === 4 && c( b.responseText )
|
||||
};
|
||||
b.send( null )
|
||||
} : typeof process !== "undefined" && process.versions && process.versions.node ? (l = require.nodeRequire( "fs" ), h = function ( a, c ) {
|
||||
c( l.readFileSync( a, "utf8" ) )
|
||||
}) : typeof Packages !== "undefined" && (h = function ( a, c ) {
|
||||
var b = new java.io.File( a ), e = java.lang.System.getProperty( "line.separator" ), b = new java.io.BufferedReader( new java.io.InputStreamReader( new java.io.FileInputStream( b ), "utf-8" ) ), d, f, g = "";
|
||||
try {
|
||||
d = new java.lang.StringBuffer;
|
||||
(f = b.readLine()) && f.length() &&
|
||||
f.charAt( 0 ) === 65279 && (f = f.substring( 1 ));
|
||||
for ( d.append( f ); (f = b.readLine()) !== null; ) {
|
||||
d.append( e ), d.append( f );
|
||||
}
|
||||
g = String( d.toString() )
|
||||
} finally {
|
||||
b.close()
|
||||
}
|
||||
c( g )
|
||||
});
|
||||
return g = {version : "1.0.2", strip : function ( a ) {
|
||||
if ( a ) {
|
||||
var a = a.replace( n, "" ), c = a.match( o );
|
||||
c && (a = c[1])
|
||||
} else {
|
||||
a = "";
|
||||
}
|
||||
return a
|
||||
}, jsEscape : function ( a ) {
|
||||
return a.replace( /(['\\])/g, "\\$1" ).replace( /[\f]/g, "\\f" ).replace( /[\b]/g, "\\b" ).replace( /[\n]/g, "\\n" ).replace( /[\t]/g, "\\t" ).replace( /[\r]/g, "\\r" )
|
||||
}, createXhr : function () {
|
||||
var a, c, b;
|
||||
if ( typeof XMLHttpRequest !==
|
||||
"undefined" ) {
|
||||
return new XMLHttpRequest;
|
||||
} else {
|
||||
for ( c = 0; c < 3; c++ ) {
|
||||
b = k[c];
|
||||
try {
|
||||
a = new ActiveXObject( b )
|
||||
} catch ( e ) {
|
||||
}
|
||||
if ( a ) {
|
||||
k = [b];
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !a ) {
|
||||
throw Error( "createXhr(): XMLHttpRequest not available" );
|
||||
}
|
||||
return a
|
||||
}, get : h, parseName : function ( a ) {
|
||||
var c = !1, b = a.indexOf( "." ), e = a.substring( 0, b ), a = a.substring( b + 1, a.length ), b = a.indexOf( "!" );
|
||||
b !== -1 && (c = a.substring( b + 1, a.length ), c = c === "strip", a = a.substring( 0, b ));
|
||||
return{moduleName : e, ext : a, strip : c}
|
||||
}, xdRegExp : /^((\w+)\:)?\/\/([^\/\\]+)/, useXhr : function ( a, c, b, e ) {
|
||||
var d = g.xdRegExp.exec( a ),
|
||||
f;
|
||||
if ( !d ) {
|
||||
return!0;
|
||||
}
|
||||
a = d[2];
|
||||
d = d[3];
|
||||
d = d.split( ":" );
|
||||
f = d[1];
|
||||
d = d[0];
|
||||
return(!a || a === c) && (!d || d === b) && (!f && !d || f === e)
|
||||
}, finishLoad : function ( a, c, b, e, d ) {
|
||||
b = c ? g.strip( b ) : b;
|
||||
d.isBuild && (j[a] = b);
|
||||
e( b )
|
||||
}, load : function ( a, c, b, e ) {
|
||||
if ( e.isBuild && !e.inlineText ) {
|
||||
b();
|
||||
} else {
|
||||
var d = g.parseName( a ), f = d.moduleName + "." + d.ext, m = c.toUrl( f ), h = e && e.text && e.text.useXhr || g.useXhr;
|
||||
!i || h( m, p, q, r ) ? g.get( m, function ( c ) {
|
||||
g.finishLoad( a, d.strip, c, b, e )
|
||||
} ) : c( [f], function ( a ) {
|
||||
g.finishLoad( d.moduleName + "." + d.ext, d.strip, a, b, e )
|
||||
} )
|
||||
}
|
||||
}, write : function ( a, c, b ) {
|
||||
if ( c in
|
||||
j ) {
|
||||
var e = g.jsEscape( j[c] );
|
||||
b.asModule( a + "!" + c, "define(function () { return '" + e + "';});\n" )
|
||||
}
|
||||
}, writeFile : function ( a, c, b, e, d ) {
|
||||
var c = g.parseName( c ), f = c.moduleName + "." + c.ext, h = b.toUrl( c.moduleName + "." + c.ext ) + ".js";
|
||||
g.load( f, b, function () {
|
||||
var b = function ( a ) {
|
||||
return e( h, a )
|
||||
};
|
||||
b.asModule = function ( a, b ) {
|
||||
return e.asModule( a, h, b )
|
||||
};
|
||||
g.write( a, f, b, d )
|
||||
}, d )
|
||||
}}
|
||||
} )
|
||||
})();
|
||||
|
|
@ -5,27 +5,713 @@
|
|||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore
|
||||
(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
|
||||
h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
|
||||
b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
|
||||
null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
|
||||
function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
|
||||
e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
|
||||
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
|
||||
return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
|
||||
c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
|
||||
b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
|
||||
return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
|
||||
d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
|
||||
var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
|
||||
c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
|
||||
a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
|
||||
b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
|
||||
1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
|
||||
b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
|
||||
b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
|
||||
function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
|
||||
u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
|
||||
function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
|
||||
true;return this};m.prototype.value=function(){return this._wrapped};typeof define==="function"&&define.amd&&define("underscore",function(){return b})}).call(this);
|
||||
(function () {
|
||||
function q( a, c, d ) {
|
||||
if ( a === c ) {
|
||||
return a !== 0 || 1 / a == 1 / c;
|
||||
}
|
||||
if ( a == null || c == null ) {
|
||||
return a === c;
|
||||
}
|
||||
if ( a._chain ) {
|
||||
a = a._wrapped;
|
||||
}
|
||||
if ( c._chain ) {
|
||||
c = c._wrapped;
|
||||
}
|
||||
if ( a.isEqual && b.isFunction( a.isEqual ) ) {
|
||||
return a.isEqual( c );
|
||||
}
|
||||
if ( c.isEqual && b.isFunction( c.isEqual ) ) {
|
||||
return c.isEqual( a );
|
||||
}
|
||||
var e = l.call( a );
|
||||
if ( e != l.call( c ) ) {
|
||||
return false;
|
||||
}
|
||||
switch ( e ) {
|
||||
case "[object String]":
|
||||
return a == String( c );
|
||||
case "[object Number]":
|
||||
return a != +a ? c != +c : a == 0 ? 1 / a == 1 / c : a == +c;
|
||||
case "[object Date]":
|
||||
case "[object Boolean]":
|
||||
return+a == +c;
|
||||
case "[object RegExp]":
|
||||
return a.source ==
|
||||
c.source && a.global == c.global && a.multiline == c.multiline && a.ignoreCase == c.ignoreCase
|
||||
}
|
||||
if ( typeof a != "object" || typeof c != "object" ) {
|
||||
return false;
|
||||
}
|
||||
for ( var f = d.length; f--; ) {
|
||||
if ( d[f] == a ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
d.push( a );
|
||||
var f = 0, g = true;
|
||||
if ( e == "[object Array]" ) {
|
||||
if ( f = a.length, g = f == c.length ) {
|
||||
for ( ; f--; ) {
|
||||
if ( !(g = f in a == f in c && q( a[f], c[f], d )) ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( "constructor"in a != "constructor"in c || a.constructor != c.constructor ) {
|
||||
return false;
|
||||
}
|
||||
for ( var h in a ) {
|
||||
if ( b.has( a, h ) && (f++, !(g = b.has( c, h ) && q( a[h], c[h], d ))) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( g ) {
|
||||
for ( h in c ) {
|
||||
if ( b.has( c,
|
||||
h ) && !f-- ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
g = !f
|
||||
}
|
||||
}
|
||||
d.pop();
|
||||
return g
|
||||
}
|
||||
|
||||
var r = this, G = r._, n = {}, k = Array.prototype, o = Object.prototype, i = k.slice, H = k.unshift, l = o.toString, I = o.hasOwnProperty, w = k.forEach, x = k.map, y = k.reduce, z = k.reduceRight, A = k.filter, B = k.every, C = k.some, p = k.indexOf, D = k.lastIndexOf, o = Array.isArray, J = Object.keys, s = Function.prototype.bind, b = function ( a ) {
|
||||
return new m( a )
|
||||
};
|
||||
if ( typeof exports !== "undefined" ) {
|
||||
if ( typeof module !== "undefined" && module.exports ) {
|
||||
exports = module.exports = b;
|
||||
}
|
||||
exports._ = b
|
||||
} else {
|
||||
r._ = b;
|
||||
}
|
||||
b.VERSION = "1.3.1";
|
||||
var j = b.each =
|
||||
b.forEach = function ( a, c, d ) {
|
||||
if ( a != null ) {
|
||||
if ( w && a.forEach === w ) {
|
||||
a.forEach( c, d );
|
||||
} else if ( a.length === +a.length ) {
|
||||
for ( var e = 0, f = a.length; e < f; e++ ) {
|
||||
if ( e in a && c.call( d, a[e], e, a ) === n ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( e in a ) {
|
||||
if ( b.has( a, e ) && c.call( d, a[e], e, a ) === n ) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
b.map = b.collect = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( x && a.map === x ) {
|
||||
return a.map( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
e[e.length] = c.call( b, a, g, h )
|
||||
} );
|
||||
if ( a.length === +a.length ) {
|
||||
e.length = a.length;
|
||||
}
|
||||
return e
|
||||
};
|
||||
b.reduce = b.foldl = b.inject = function ( a, c, d, e ) {
|
||||
var f = arguments.length > 2;
|
||||
a ==
|
||||
null && (a = []);
|
||||
if ( y && a.reduce === y ) {
|
||||
return e && (c = b.bind( c, e )), f ? a.reduce( c, d ) : a.reduce( c );
|
||||
}
|
||||
j( a, function ( a, b, i ) {
|
||||
f ? d = c.call( e, d, a, b, i ) : (d = a, f = true)
|
||||
} );
|
||||
if ( !f ) {
|
||||
throw new TypeError( "Reduce of empty array with no initial value" );
|
||||
}
|
||||
return d
|
||||
};
|
||||
b.reduceRight = b.foldr = function ( a, c, d, e ) {
|
||||
var f = arguments.length > 2;
|
||||
a == null && (a = []);
|
||||
if ( z && a.reduceRight === z ) {
|
||||
return e && (c = b.bind( c, e )), f ? a.reduceRight( c, d ) : a.reduceRight( c );
|
||||
}
|
||||
var g = b.toArray( a ).reverse();
|
||||
e && !f && (c = b.bind( c, e ));
|
||||
return f ? b.reduce( g, c, d, e ) : b.reduce( g, c )
|
||||
};
|
||||
b.find = b.detect =
|
||||
function ( a, c, b ) {
|
||||
var e;
|
||||
E( a, function ( a, g, h ) {
|
||||
if ( c.call( b, a, g, h ) ) {
|
||||
return e = a, true
|
||||
}
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.filter = b.select = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( A && a.filter === A ) {
|
||||
return a.filter( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
c.call( b, a, g, h ) && (e[e.length] = a)
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.reject = function ( a, c, b ) {
|
||||
var e = [];
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
c.call( b, a, g, h ) || (e[e.length] = a)
|
||||
} );
|
||||
return e
|
||||
};
|
||||
b.every = b.all = function ( a, c, b ) {
|
||||
var e = true;
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( B && a.every === B ) {
|
||||
return a.every( c, b );
|
||||
}
|
||||
j( a, function ( a, g, h ) {
|
||||
if ( !(e =
|
||||
e && c.call( b, a, g, h )) ) {
|
||||
return n
|
||||
}
|
||||
} );
|
||||
return e
|
||||
};
|
||||
var E = b.some = b.any = function ( a, c, d ) {
|
||||
c || (c = b.identity);
|
||||
var e = false;
|
||||
if ( a == null ) {
|
||||
return e;
|
||||
}
|
||||
if ( C && a.some === C ) {
|
||||
return a.some( c, d );
|
||||
}
|
||||
j( a, function ( a, b, h ) {
|
||||
if ( e || (e = c.call( d, a, b, h )) ) {
|
||||
return n
|
||||
}
|
||||
} );
|
||||
return!!e
|
||||
};
|
||||
b.include = b.contains = function ( a, c ) {
|
||||
var b = false;
|
||||
if ( a == null ) {
|
||||
return b;
|
||||
}
|
||||
return p && a.indexOf === p ? a.indexOf( c ) != -1 : b = E( a, function ( a ) {
|
||||
return a === c
|
||||
} )
|
||||
};
|
||||
b.invoke = function ( a, c ) {
|
||||
var d = i.call( arguments, 2 );
|
||||
return b.map( a, function ( a ) {
|
||||
return(b.isFunction( c ) ? c || a : a[c]).apply( a, d )
|
||||
} )
|
||||
};
|
||||
b.pluck =
|
||||
function ( a, c ) {
|
||||
return b.map( a, function ( a ) {
|
||||
return a[c]
|
||||
} )
|
||||
};
|
||||
b.max = function ( a, c, d ) {
|
||||
if ( !c && b.isArray( a ) ) {
|
||||
return Math.max.apply( Math, a );
|
||||
}
|
||||
if ( !c && b.isEmpty( a ) ) {
|
||||
return-Infinity;
|
||||
}
|
||||
var e = {computed : -Infinity};
|
||||
j( a, function ( a, b, h ) {
|
||||
b = c ? c.call( d, a, b, h ) : a;
|
||||
b >= e.computed && (e = {value : a, computed : b})
|
||||
} );
|
||||
return e.value
|
||||
};
|
||||
b.min = function ( a, c, d ) {
|
||||
if ( !c && b.isArray( a ) ) {
|
||||
return Math.min.apply( Math, a );
|
||||
}
|
||||
if ( !c && b.isEmpty( a ) ) {
|
||||
return Infinity;
|
||||
}
|
||||
var e = {computed : Infinity};
|
||||
j( a, function ( a, b, h ) {
|
||||
b = c ? c.call( d, a, b, h ) : a;
|
||||
b < e.computed && (e = {value : a, computed : b})
|
||||
} );
|
||||
return e.value
|
||||
};
|
||||
b.shuffle = function ( a ) {
|
||||
var b = [], d;
|
||||
j( a, function ( a, f ) {
|
||||
f == 0 ? b[0] = a : (d = Math.floor( Math.random() * (f + 1) ), b[f] = b[d], b[d] = a)
|
||||
} );
|
||||
return b
|
||||
};
|
||||
b.sortBy = function ( a, c, d ) {
|
||||
return b.pluck( b.map( a,
|
||||
function ( a, b, g ) {
|
||||
return{value : a, criteria : c.call( d, a, b, g )}
|
||||
} ).sort( function ( a, b ) {
|
||||
var c = a.criteria, d = b.criteria;
|
||||
return c < d ? -1 : c > d ? 1 : 0
|
||||
} ), "value" )
|
||||
};
|
||||
b.groupBy = function ( a, c ) {
|
||||
var d = {}, e = b.isFunction( c ) ? c : function ( a ) {
|
||||
return a[c]
|
||||
};
|
||||
j( a, function ( a, b ) {
|
||||
var c = e( a, b );
|
||||
(d[c] || (d[c] = [])).push( a )
|
||||
} );
|
||||
return d
|
||||
};
|
||||
b.sortedIndex = function ( a, c, d ) {
|
||||
d || (d = b.identity);
|
||||
for ( var e = 0, f = a.length; e < f; ) {
|
||||
var g = e + f >> 1;
|
||||
d( a[g] ) < d( c ) ? e = g + 1 : f = g
|
||||
}
|
||||
return e
|
||||
};
|
||||
b.toArray = function ( a ) {
|
||||
return!a ? [] : a.toArray ? a.toArray() : b.isArray( a ) ? i.call( a ) : b.isArguments( a ) ? i.call( a ) : b.values( a )
|
||||
};
|
||||
b.size = function ( a ) {
|
||||
return b.toArray( a ).length
|
||||
};
|
||||
b.first = b.head = function ( a, b, d ) {
|
||||
return b != null && !d ? i.call( a, 0, b ) : a[0]
|
||||
};
|
||||
b.initial = function ( a, b, d ) {
|
||||
return i.call( a, 0, a.length - (b == null || d ? 1 : b) )
|
||||
};
|
||||
b.last = function ( a, b, d ) {
|
||||
return b != null && !d ? i.call( a, Math.max( a.length - b, 0 ) ) : a[a.length - 1]
|
||||
};
|
||||
b.rest =
|
||||
b.tail = function ( a, b, d ) {
|
||||
return i.call( a, b == null || d ? 1 : b )
|
||||
};
|
||||
b.compact = function ( a ) {
|
||||
return b.filter( a, function ( a ) {
|
||||
return!!a
|
||||
} )
|
||||
};
|
||||
b.flatten = function ( a, c ) {
|
||||
return b.reduce( a, function ( a, e ) {
|
||||
if ( b.isArray( e ) ) {
|
||||
return a.concat( c ? e : b.flatten( e ) );
|
||||
}
|
||||
a[a.length] = e;
|
||||
return a
|
||||
}, [] )
|
||||
};
|
||||
b.without = function ( a ) {
|
||||
return b.difference( a, i.call( arguments, 1 ) )
|
||||
};
|
||||
b.uniq = b.unique = function ( a, c, d ) {
|
||||
var d = d ? b.map( a, d ) : a, e = [];
|
||||
b.reduce( d, function ( d, g, h ) {
|
||||
if ( 0 == h || (c === true ? b.last( d ) != g : !b.include( d, g )) ) {
|
||||
d[d.length] = g, e[e.length] = a[h];
|
||||
}
|
||||
return d
|
||||
}, [] );
|
||||
return e
|
||||
};
|
||||
b.union = function () {
|
||||
return b.uniq( b.flatten( arguments, true ) )
|
||||
};
|
||||
b.intersection = b.intersect = function ( a ) {
|
||||
var c = i.call( arguments, 1 );
|
||||
return b.filter( b.uniq( a ), function ( a ) {
|
||||
return b.every( c, function ( c ) {
|
||||
return b.indexOf( c, a ) >= 0
|
||||
} )
|
||||
} )
|
||||
};
|
||||
b.difference = function ( a ) {
|
||||
var c = b.flatten( i.call( arguments, 1 ) );
|
||||
return b.filter( a, function ( a ) {
|
||||
return!b.include( c, a )
|
||||
} )
|
||||
};
|
||||
b.zip = function () {
|
||||
for ( var a = i.call( arguments ), c = b.max( b.pluck( a, "length" ) ), d = Array( c ), e = 0; e < c; e++ ) {
|
||||
d[e] = b.pluck( a, "" + e );
|
||||
}
|
||||
return d
|
||||
};
|
||||
b.indexOf = function ( a, c, d ) {
|
||||
if ( a == null ) {
|
||||
return-1;
|
||||
}
|
||||
var e;
|
||||
if ( d ) {
|
||||
return d = b.sortedIndex( a, c ), a[d] === c ? d : -1;
|
||||
}
|
||||
if ( p && a.indexOf === p ) {
|
||||
return a.indexOf( c );
|
||||
}
|
||||
for ( d = 0, e = a.length; d < e; d++ ) {
|
||||
if ( d in a && a[d] === c ) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return-1
|
||||
};
|
||||
b.lastIndexOf = function ( a, b ) {
|
||||
if ( a == null ) {
|
||||
return-1;
|
||||
}
|
||||
if ( D && a.lastIndexOf === D ) {
|
||||
return a.lastIndexOf( b );
|
||||
}
|
||||
for ( var d = a.length; d--; ) {
|
||||
if ( d in a && a[d] === b ) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return-1
|
||||
};
|
||||
b.range = function ( a, b, d ) {
|
||||
arguments.length <= 1 && (b = a || 0, a = 0);
|
||||
for ( var d = arguments[2] || 1, e = Math.max( Math.ceil( (b - a) / d ), 0 ), f = 0, g = Array( e ); f < e; ) {
|
||||
g[f++] = a, a += d;
|
||||
}
|
||||
return g
|
||||
};
|
||||
var F = function () {
|
||||
};
|
||||
b.bind = function ( a, c ) {
|
||||
var d, e;
|
||||
if ( a.bind === s && s ) {
|
||||
return s.apply( a, i.call( arguments, 1 ) );
|
||||
}
|
||||
if ( !b.isFunction( a ) ) {
|
||||
throw new TypeError;
|
||||
}
|
||||
e = i.call( arguments, 2 );
|
||||
return d = function () {
|
||||
if ( !(this instanceof d) ) {
|
||||
return a.apply( c, e.concat( i.call( arguments ) ) );
|
||||
}
|
||||
F.prototype = a.prototype;
|
||||
var b = new F, g = a.apply( b, e.concat( i.call( arguments ) ) );
|
||||
return Object( g ) === g ? g : b
|
||||
}
|
||||
};
|
||||
b.bindAll = function ( a ) {
|
||||
var c = i.call( arguments, 1 );
|
||||
c.length == 0 && (c = b.functions( a ));
|
||||
j( c, function ( c ) {
|
||||
a[c] = b.bind( a[c], a )
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.memoize = function ( a, c ) {
|
||||
var d = {};
|
||||
c || (c = b.identity);
|
||||
return function () {
|
||||
var e = c.apply( this, arguments );
|
||||
return b.has( d, e ) ? d[e] : d[e] = a.apply( this, arguments )
|
||||
}
|
||||
};
|
||||
b.delay = function ( a, b ) {
|
||||
var d = i.call( arguments, 2 );
|
||||
return setTimeout( function () {
|
||||
return a.apply( a, d )
|
||||
}, b )
|
||||
};
|
||||
b.defer = function ( a ) {
|
||||
return b.delay.apply( b, [a, 1].concat( i.call( arguments, 1 ) ) )
|
||||
};
|
||||
b.throttle = function ( a, c ) {
|
||||
var d, e, f, g, h, i = b.debounce( function () {
|
||||
h = g = false
|
||||
}, c );
|
||||
return function () {
|
||||
d = this;
|
||||
e = arguments;
|
||||
var b;
|
||||
f || (f = setTimeout( function () {
|
||||
f = null;
|
||||
h && a.apply( d, e );
|
||||
i()
|
||||
}, c ));
|
||||
g ? h = true :
|
||||
a.apply( d, e );
|
||||
i();
|
||||
g = true
|
||||
}
|
||||
};
|
||||
b.debounce = function ( a, b ) {
|
||||
var d;
|
||||
return function () {
|
||||
var e = this, f = arguments;
|
||||
clearTimeout( d );
|
||||
d = setTimeout( function () {
|
||||
d = null;
|
||||
a.apply( e, f )
|
||||
}, b )
|
||||
}
|
||||
};
|
||||
b.once = function ( a ) {
|
||||
var b = false, d;
|
||||
return function () {
|
||||
if ( b ) {
|
||||
return d;
|
||||
}
|
||||
b = true;
|
||||
return d = a.apply( this, arguments )
|
||||
}
|
||||
};
|
||||
b.wrap = function ( a, b ) {
|
||||
return function () {
|
||||
var d = [a].concat( i.call( arguments, 0 ) );
|
||||
return b.apply( this, d )
|
||||
}
|
||||
};
|
||||
b.compose = function () {
|
||||
var a = arguments;
|
||||
return function () {
|
||||
for ( var b = arguments, d = a.length - 1; d >= 0; d-- ) {
|
||||
b = [a[d].apply( this, b )];
|
||||
}
|
||||
return b[0]
|
||||
}
|
||||
};
|
||||
b.after = function ( a, b ) {
|
||||
return a <= 0 ? b() : function () {
|
||||
if ( --a < 1 ) {
|
||||
return b.apply( this, arguments )
|
||||
}
|
||||
}
|
||||
};
|
||||
b.keys = J || function ( a ) {
|
||||
if ( a !== Object( a ) ) {
|
||||
throw new TypeError( "Invalid object" );
|
||||
}
|
||||
var c = [], d;
|
||||
for ( d in a ) {
|
||||
b.has( a, d ) && (c[c.length] = d);
|
||||
}
|
||||
return c
|
||||
};
|
||||
b.values = function ( a ) {
|
||||
return b.map( a, b.identity )
|
||||
};
|
||||
b.functions = b.methods = function ( a ) {
|
||||
var c = [], d;
|
||||
for ( d in a ) {
|
||||
b.isFunction( a[d] ) && c.push( d );
|
||||
}
|
||||
return c.sort()
|
||||
};
|
||||
b.extend = function ( a ) {
|
||||
j( i.call( arguments, 1 ), function ( b ) {
|
||||
for ( var d in b ) {
|
||||
a[d] = b[d]
|
||||
}
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.defaults = function ( a ) {
|
||||
j( i.call( arguments,
|
||||
1 ), function ( b ) {
|
||||
for ( var d in b ) {
|
||||
a[d] == null && (a[d] = b[d])
|
||||
}
|
||||
} );
|
||||
return a
|
||||
};
|
||||
b.clone = function ( a ) {
|
||||
return!b.isObject( a ) ? a : b.isArray( a ) ? a.slice() : b.extend( {}, a )
|
||||
};
|
||||
b.tap = function ( a, b ) {
|
||||
b( a );
|
||||
return a
|
||||
};
|
||||
b.isEqual = function ( a, b ) {
|
||||
return q( a, b, [] )
|
||||
};
|
||||
b.isEmpty = function ( a ) {
|
||||
if ( b.isArray( a ) || b.isString( a ) ) {
|
||||
return a.length === 0;
|
||||
}
|
||||
for ( var c in a ) {
|
||||
if ( b.has( a, c ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
};
|
||||
b.isElement = function ( a ) {
|
||||
return!!(a && a.nodeType == 1)
|
||||
};
|
||||
b.isArray = o || function ( a ) {
|
||||
return l.call( a ) == "[object Array]"
|
||||
};
|
||||
b.isObject = function ( a ) {
|
||||
return a === Object( a )
|
||||
};
|
||||
b.isArguments = function ( a ) {
|
||||
return l.call( a ) == "[object Arguments]"
|
||||
};
|
||||
if ( !b.isArguments( arguments ) ) {
|
||||
b.isArguments = function ( a ) {
|
||||
return!(!a || !b.has( a, "callee" ))
|
||||
};
|
||||
}
|
||||
b.isFunction = function ( a ) {
|
||||
return l.call( a ) == "[object Function]"
|
||||
};
|
||||
b.isString = function ( a ) {
|
||||
return l.call( a ) == "[object String]"
|
||||
};
|
||||
b.isNumber = function ( a ) {
|
||||
return l.call( a ) == "[object Number]"
|
||||
};
|
||||
b.isNaN = function ( a ) {
|
||||
return a !== a
|
||||
};
|
||||
b.isBoolean = function ( a ) {
|
||||
return a === true || a === false || l.call( a ) == "[object Boolean]"
|
||||
};
|
||||
b.isDate = function ( a ) {
|
||||
return l.call( a ) == "[object Date]"
|
||||
};
|
||||
b.isRegExp = function ( a ) {
|
||||
return l.call( a ) == "[object RegExp]"
|
||||
};
|
||||
b.isNull = function ( a ) {
|
||||
return a === null
|
||||
};
|
||||
b.isUndefined = function ( a ) {
|
||||
return a === void 0
|
||||
};
|
||||
b.has = function ( a, b ) {
|
||||
return I.call( a, b )
|
||||
};
|
||||
b.noConflict = function () {
|
||||
r._ = G;
|
||||
return this
|
||||
};
|
||||
b.identity = function ( a ) {
|
||||
return a
|
||||
};
|
||||
b.times = function ( a, b, d ) {
|
||||
for ( var e = 0; e < a; e++ ) {
|
||||
b.call( d, e )
|
||||
}
|
||||
};
|
||||
b.escape = function ( a ) {
|
||||
return("" + a).replace( /&/g, "&" ).replace( /</g, "<" ).replace( />/g, ">" ).replace( /"/g, """ ).replace( /'/g, "'" ).replace( /\//g, "/" )
|
||||
};
|
||||
b.mixin = function ( a ) {
|
||||
j( b.functions( a ),
|
||||
function ( c ) {
|
||||
K( c, b[c] = a[c] )
|
||||
} )
|
||||
};
|
||||
var L = 0;
|
||||
b.uniqueId = function ( a ) {
|
||||
var b = L++;
|
||||
return a ? a + b : b
|
||||
};
|
||||
b.templateSettings = {evaluate : /<%([\s\S]+?)%>/g, interpolate : /<%=([\s\S]+?)%>/g, escape : /<%-([\s\S]+?)%>/g};
|
||||
var t = /.^/, u = function ( a ) {
|
||||
return a.replace( /\\\\/g, "\\" ).replace( /\\'/g, "'" )
|
||||
};
|
||||
b.template = function ( a, c ) {
|
||||
var d = b.templateSettings, d = "var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('" + a.replace( /\\/g, "\\\\" ).replace( /'/g, "\\'" ).replace( d.escape || t,
|
||||
function ( a, b ) {
|
||||
return"',_.escape(" +
|
||||
u( b ) + "),'"
|
||||
} ).replace( d.interpolate || t,
|
||||
function ( a, b ) {
|
||||
return"'," + u( b ) + ",'"
|
||||
} ).replace( d.evaluate || t,
|
||||
function ( a, b ) {
|
||||
return"');" + u( b ).replace( /[\r\n\t]/g, " " ) + ";__p.push('"
|
||||
} ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /\t/g, "\\t" ) + "');}return __p.join('');", e = new Function( "obj", "_", d );
|
||||
return c ? e( c, b ) : function ( a ) {
|
||||
return e.call( this, a, b )
|
||||
}
|
||||
};
|
||||
b.chain = function ( a ) {
|
||||
return b( a ).chain()
|
||||
};
|
||||
var m = function ( a ) {
|
||||
this._wrapped = a
|
||||
};
|
||||
b.prototype = m.prototype;
|
||||
var v = function ( a, c ) {
|
||||
return c ? b( a ).chain() : a
|
||||
}, K = function ( a, c ) {
|
||||
m.prototype[a] =
|
||||
function () {
|
||||
var a = i.call( arguments );
|
||||
H.call( a, this._wrapped );
|
||||
return v( c.apply( b, a ), this._chain )
|
||||
}
|
||||
};
|
||||
b.mixin( b );
|
||||
j( "pop,push,reverse,shift,sort,splice,unshift".split( "," ), function ( a ) {
|
||||
var b = k[a];
|
||||
m.prototype[a] = function () {
|
||||
var d = this._wrapped;
|
||||
b.apply( d, arguments );
|
||||
var e = d.length;
|
||||
(a == "shift" || a == "splice") && e === 0 && delete d[0];
|
||||
return v( d, this._chain )
|
||||
}
|
||||
} );
|
||||
j( ["concat", "join", "slice"], function ( a ) {
|
||||
var b = k[a];
|
||||
m.prototype[a] = function () {
|
||||
return v( b.apply( this._wrapped, arguments ), this._chain )
|
||||
}
|
||||
} );
|
||||
m.prototype.chain = function () {
|
||||
this._chain =
|
||||
true;
|
||||
return this
|
||||
};
|
||||
m.prototype.value = function () {
|
||||
return this._wrapped
|
||||
};
|
||||
typeof define === "function" && define.amd && define( "underscore", function () {
|
||||
return b
|
||||
} )
|
||||
}).call( this );
|
||||
|
|
|
|||
|
|
@ -1,42 +1,35 @@
|
|||
var socket;
|
||||
|
||||
require.config( {
|
||||
paths : {
|
||||
'text' : 'lib/requirejs-text-1.0.2',
|
||||
'backbone' : 'lib/backbone',
|
||||
'underscore': 'lib/underscore',
|
||||
'machina' : 'lib/machina',
|
||||
'postal' : 'lib/postal',
|
||||
'amplify' : 'lib/amplify',
|
||||
'bus' : 'infrastructure/bus'
|
||||
paths : {
|
||||
'text' : 'lib/requirejs-text-1.0.2',
|
||||
'backbone' : 'lib/backbone',
|
||||
'underscore' : 'lib/underscore',
|
||||
'machina' : 'lib/machina',
|
||||
'postal' : 'lib/postal',
|
||||
'amplify' : 'lib/amplify',
|
||||
'bus' : 'infrastructure/bus'
|
||||
},
|
||||
baseUrl: 'js'
|
||||
baseUrl : 'js'
|
||||
} );
|
||||
|
||||
require( [ 'backbone', 'jquery', 'underscore', 'machina', 'postal', 'lib/postal.diagnostics', 'infrastructure/postal.socket-client' ],
|
||||
function( Backbone, $, _, machina, postal ){
|
||||
require( [ 'backbone', 'jquery', 'underscore', 'amplify', 'machina', 'postal', 'lib/postal.diagnostics', 'infrastructure/postal.socket-client' ],
|
||||
function ( Backbone, $, _, amplify, machina, postal ) {
|
||||
|
||||
// for debugging purposes ONLY for now:
|
||||
window.postal = postal;
|
||||
|
||||
/*postal.addWireTap( function( d, e ){
|
||||
if( /search/.test(e.topic) ) {
|
||||
console.log( JSON.stringify( e ) );
|
||||
}
|
||||
});
|
||||
*/
|
||||
postal.connections.socket.socketMgr.on( "*", function( evnt, data ){
|
||||
var args = [].slice.call( arguments,1 );
|
||||
if( args[0] === "postal.remote" ) {
|
||||
//console.log( "FSM Event: " + evnt + " - " + JSON.stringify( args[0] ) );
|
||||
}
|
||||
else {
|
||||
//console.log( "FSM Event: " + evnt + " - " + JSON.stringify( args ) );
|
||||
}
|
||||
});
|
||||
postal.configuration.getSessionIdAction = function ( callback ) {
|
||||
callback( amplify.store( "postal.session" ) || {} );
|
||||
};
|
||||
|
||||
require([ 'infrastructure/app' ], function( app ) {
|
||||
postal.configuration.setSessionIdAction = function ( info, callback ) {
|
||||
amplify.store( "postal.session", info );
|
||||
callback( amplify.store( "postal.session", info ) );
|
||||
};
|
||||
|
||||
require( [ 'infrastructure/app' ], function ( app ) {
|
||||
window.app = app;
|
||||
});
|
||||
} );
|
||||
|
||||
});
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -2,30 +2,35 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
hashTags: []
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
hashTags : []
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
this.subscriptions = [
|
||||
bus.stats.subscribe( "hash-tag-count", function( data, env ){
|
||||
if( data.hashTags && data.hashTags.length ) {
|
||||
self.set( "hashTags", _.sortBy( data.hashTags, function( item ) { return item.count * -1; } ) );
|
||||
bus.stats.subscribe( "hash-tag-count", function ( data, env ) {
|
||||
if ( data.hashTags && data.hashTags.length ) {
|
||||
self.set( "hashTags", _.sortBy( data.hashTags, function ( item ) {
|
||||
return item.count * -1;
|
||||
} ) );
|
||||
}
|
||||
})
|
||||
} ),
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
self.set( "hashTags", [] );
|
||||
} )
|
||||
];
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,30 +2,35 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
mentions: []
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
mentions : []
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
this.subscriptions = [
|
||||
bus.stats.subscribe( "mention-count", function( data, env ){
|
||||
if( data.mentions && data.mentions.length ) {
|
||||
self.set( "mentions", _.sortBy( data.mentions, function( item ) { return item.count * -1; } ) );
|
||||
bus.stats.subscribe( "mention-count", function ( data, env ) {
|
||||
if ( data.mentions && data.mentions.length ) {
|
||||
self.set( "mentions", _.sortBy( data.mentions, function ( item ) {
|
||||
return item.count * -1;
|
||||
} ) );
|
||||
}
|
||||
})
|
||||
} ),
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
self.set( "mentions", [] );
|
||||
} )
|
||||
];
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,30 +2,35 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
mentioners: []
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
mentioners : []
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
this.subscriptions = [
|
||||
bus.stats.subscribe( "mentioner-count", function( data, env ){
|
||||
if( data.mentioners && data.mentioners.length ) {
|
||||
self.set( "mentioners", _.sortBy( data.mentioners, function( item ) { return item.count * -1; } ) );
|
||||
bus.stats.subscribe( "mentioner-count", function ( data, env ) {
|
||||
if ( data.mentioners && data.mentioners.length ) {
|
||||
self.set( "mentioners", _.sortBy( data.mentioners, function ( item ) {
|
||||
return item.count * -1;
|
||||
} ) );
|
||||
}
|
||||
})
|
||||
} ),
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
self.set( "mentioners", [] );
|
||||
} )
|
||||
];
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,43 +2,43 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
sessionId: "",
|
||||
searchOwnership: "",
|
||||
searchTerm: "",
|
||||
requests: false
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
sessionId : "",
|
||||
searchOwnership : "",
|
||||
searchTerm : "",
|
||||
requests : false
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.subscriptions = [
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch ).defer(),
|
||||
bus.app.subscribe( "search.new.ask", this.updateReqCount).defer(),
|
||||
bus.app.subscribe( "search.new.ask", this.updateReqCount ).defer(),
|
||||
bus.app.subscribe( "search.requests", this.updateReqCount ).defer()
|
||||
];
|
||||
bus.app.publish({
|
||||
topic: "get.search.info",
|
||||
data: {}
|
||||
});
|
||||
bus.app.publish( {
|
||||
topic : "get.search.info",
|
||||
data : {}
|
||||
} );
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
},
|
||||
|
||||
setCurrentSearch: function( data, env ) {
|
||||
setCurrentSearch : function ( data, env ) {
|
||||
var self = this;
|
||||
self.set( "searchTerm", data.searchTerm );
|
||||
postal.utils.getSessionId(
|
||||
function( session ) {
|
||||
self.set( "sessionId", session.id, { silent: true } );
|
||||
function ( session ) {
|
||||
self.set( "sessionId", session.id, { silent : true } );
|
||||
self.set( "searchOwnership",
|
||||
(session.id === data.id)
|
||||
? "You own the search."
|
||||
|
|
@ -48,14 +48,14 @@ define( [
|
|||
);
|
||||
},
|
||||
|
||||
updateReqCount: function( data, env ) {
|
||||
if((_.isArray(data) && data.length) || data.searchTerm) {
|
||||
this.set("requests", true);
|
||||
updateReqCount : function ( data, env ) {
|
||||
if ( (_.isArray( data ) && data.length) || data.searchTerm ) {
|
||||
this.set( "requests", true );
|
||||
}
|
||||
else {
|
||||
this.set("requests", false);
|
||||
this.set( "requests", false );
|
||||
}
|
||||
this.change("requests");
|
||||
this.change( "requests" );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,35 +2,43 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
percentage: "",
|
||||
clean: "",
|
||||
explicit: "",
|
||||
total: ""
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
percentage : "",
|
||||
clean : "",
|
||||
explicit : "",
|
||||
total : ""
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
this.subscriptions = [
|
||||
bus.stats.subscribe( "profanity-percentage", function( data, env ){
|
||||
self.set("percentage", data.percentage, { silent: true });
|
||||
self.set("clean", data.clean, { silent: true });
|
||||
self.set("explicit", data.explicit, { silent: true });
|
||||
self.set("total", data.clean + data.explicit, { silent: true });
|
||||
bus.stats.subscribe( "profanity-percentage", function ( data, env ) {
|
||||
self.set( "percentage", data.percentage, { silent : true } );
|
||||
self.set( "clean", data.clean, { silent : true } );
|
||||
self.set( "explicit", data.explicit, { silent : true } );
|
||||
self.set( "total", data.clean + data.explicit, { silent : true } );
|
||||
self.change();
|
||||
})
|
||||
} ),
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
console.log( "PROF PERF - SEARCH INIT!" );
|
||||
self.set( "percentage", "", { silent : true } );
|
||||
self.set( "clean", "", { silent : true } );
|
||||
self.set( "explicit", "", { silent : true } );
|
||||
self.set( "total", "", { silent : true } );
|
||||
self.change();
|
||||
} )
|
||||
];
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,66 +2,85 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
requests: [],
|
||||
ownerId: undefined,
|
||||
sessionId: undefined
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
requests : [],
|
||||
ownerId : undefined,
|
||||
sessionId : undefined
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.setSessionId();
|
||||
this.subscriptions = [
|
||||
bus.app.subscribe( "search.info", this.setOwner ),
|
||||
bus.app.subscribe( "search.requests", this.updateRequests ),
|
||||
bus.app.subscribe( "search.new.ask", this.addRequest )
|
||||
bus.app.subscribe( "search.new.ask", this.addRequest ),
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
self.set( "requests", [] );
|
||||
} )
|
||||
];
|
||||
bus.app.publish({
|
||||
topic: "get.search.requests",
|
||||
data: {}
|
||||
});
|
||||
this.askForUpdate();
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
askForUpdate : function () {
|
||||
bus.app.publish( {
|
||||
topic : "get.search.requests",
|
||||
data : {}
|
||||
} );
|
||||
bus.app.publish( {
|
||||
topic : "get.search.info",
|
||||
data : {}
|
||||
} );
|
||||
},
|
||||
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
},
|
||||
|
||||
setOwner: function( data, env ) {
|
||||
this.set("ownerId", data.id);
|
||||
setOwner : function ( data, env ) {
|
||||
this.set( "ownerId", data.id );
|
||||
this.change();
|
||||
this.setSessionId();
|
||||
},
|
||||
|
||||
setSessionId: function() {
|
||||
setSessionId : function () {
|
||||
var self = this;
|
||||
postal.utils.getSessionId(
|
||||
function( session ) {
|
||||
self.set( "sessionId", session.id, { silent: true } );
|
||||
function ( session ) {
|
||||
self.set( "sessionId", session.id );
|
||||
self.change();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
updateRequests: function( data, env ) {
|
||||
this.set( "requests", _.sortBy( data, function( item ) { return item.searchTerm; } ) );
|
||||
updateRequests : function ( data, env ) {
|
||||
console.log( "Got an update" );
|
||||
this.set( "requests", _.sortBy( data, function ( item ) {
|
||||
return item.searchTerm;
|
||||
} ) );
|
||||
this.change();
|
||||
},
|
||||
|
||||
addRequest: function( data, env ) {
|
||||
var reqs = this.get("requests");
|
||||
if( _.any( reqs, function( item ){
|
||||
addRequest : function ( data, env ) {
|
||||
var reqs = this.get( "requests" );
|
||||
if ( _.any( reqs, function ( item ) {
|
||||
return item.searchTerm === data.searchTerm &&
|
||||
item.correlationId === data.correlationId
|
||||
})) {
|
||||
item.correlationId === data.correlationId
|
||||
} ) ) {
|
||||
return;
|
||||
}
|
||||
reqs.push( data );
|
||||
this.set( "requests", _.sortBy( reqs, function( item ) { return item.searchTerm; } ), { silent: true } );
|
||||
this.change("change:requests");
|
||||
this.set( "requests", _.sortBy( reqs, function ( item ) {
|
||||
return item.searchTerm;
|
||||
} ) );
|
||||
this.change();
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -2,30 +2,35 @@ define( [
|
|||
'backbone',
|
||||
'bus'
|
||||
],
|
||||
function( Backbone, bus ) {
|
||||
function ( Backbone, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.Model.extend({
|
||||
defaults: {
|
||||
tweeters: []
|
||||
return Backbone.Model.extend( {
|
||||
defaults : {
|
||||
tweeters : []
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
var self = this;
|
||||
this.subscriptions = [
|
||||
bus.stats.subscribe( "tweet-count", function( data, env ){
|
||||
if( data.tweeters && data.tweeters.length ) {
|
||||
self.set( "tweeters", _.sortBy( data.tweeters, function( item ) { return item.count * -1; } ) );
|
||||
bus.stats.subscribe( "tweet-count", function ( data, env ) {
|
||||
if ( data.tweeters && data.tweeters.length ) {
|
||||
self.set( "tweeters", _.sortBy( data.tweeters, function ( item ) {
|
||||
return item.count * -1;
|
||||
} ) );
|
||||
}
|
||||
})
|
||||
} ) ,
|
||||
bus.app.subscribe( "search.init", function () {
|
||||
self.set( "tweeters", [] );
|
||||
} )
|
||||
];
|
||||
},
|
||||
|
||||
dispose: function(){
|
||||
_.each( this.subscriptions, function( subscription ){
|
||||
dispose : function () {
|
||||
_.each( this.subscriptions, function ( subscription ) {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
this.clear( { silent: true } );
|
||||
} );
|
||||
this.clear( { silent : true } );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
|
@ -3,27 +3,27 @@ define( [
|
|||
'backbone',
|
||||
'text!views/templates/container.html'
|
||||
],
|
||||
function( $, Backbone, template ) {
|
||||
function ( $, Backbone, template ) {
|
||||
// Using ECMAScript 5 strict mode during development. By default r.js will ignore that.
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
el: "body",
|
||||
el : "body",
|
||||
|
||||
initialize: function() {
|
||||
_.bindAll(this, "render");
|
||||
initialize : function () {
|
||||
_.bindAll( this, "render" );
|
||||
this.template = template;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template);
|
||||
render : function () {
|
||||
this.$el.html( this.template );
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
update: function( data ) {
|
||||
update : function ( data ) {
|
||||
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -5,36 +5,36 @@ define( [
|
|||
'models/hash-tag-count-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, HashTagCountModel, bus ) {
|
||||
function ( $, Backbone, template, HashTagCountModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
tagName: "div",
|
||||
tagName : "div",
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new HashTagCountModel();
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch );
|
||||
this.model.bind( "change", this.render );
|
||||
this.inDom = false;
|
||||
bus.stats.publish({ topic: "hash-tag-count.getLatest", data: {} });
|
||||
bus.stats.publish( { topic : "hash-tag-count.getLatest", data : {} } );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
// TODO: Capture scroll position and restore after render...
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
if( !this.inDom ) {
|
||||
if ( !this.inDom ) {
|
||||
this.$el.appendTo( "#stats" );
|
||||
this.inDom = true;
|
||||
}
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -5,36 +5,36 @@ define( [
|
|||
'models/mention-count-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, MentionCountModel, bus ) {
|
||||
function ( $, Backbone, template, MentionCountModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
tagName: "div",
|
||||
tagName : "div",
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new MentionCountModel();
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch );
|
||||
this.model.bind( "change", this.render );
|
||||
this.inDom = false;
|
||||
bus.stats.publish({ topic: "mention-count.getLatest", data: {} });
|
||||
bus.stats.publish( { topic : "mention-count.getLatest", data : {} } );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
// TODO: Capture scroll position and restore after render...
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
if( !this.inDom ) {
|
||||
if ( !this.inDom ) {
|
||||
this.$el.appendTo( "#stats" );
|
||||
this.inDom = true;
|
||||
}
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -5,36 +5,36 @@ define( [
|
|||
'models/mentioner-count-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, MentionerCountModel, bus ) {
|
||||
function ( $, Backbone, template, MentionerCountModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
tagName: "div",
|
||||
tagName : "div",
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new MentionerCountModel();
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch );
|
||||
this.model.bind( "change", this.render );
|
||||
this.inDom = false;
|
||||
bus.stats.publish({ topic: "mentioner-count.getLatest", data: {} });
|
||||
bus.stats.publish( { topic : "mentioner-count.getLatest", data : {} } );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
// TODO: Capture scroll position and restore after render...
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
if( !this.inDom ) {
|
||||
if ( !this.inDom ) {
|
||||
this.$el.appendTo( "#stats" );
|
||||
this.inDom = true;
|
||||
}
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -5,47 +5,47 @@ define( [
|
|||
'bus',
|
||||
'models/menu-model'
|
||||
],
|
||||
function( $, Backbone, template, bus, MenuModel ) {
|
||||
function ( $, Backbone, template, bus, MenuModel ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
el: "#menu",
|
||||
el : "#menu",
|
||||
|
||||
events: {
|
||||
events : {
|
||||
"click #btnSearch" : "updateSearch"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new MenuModel();
|
||||
this.model.bind( "change", this.updateView );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
updateSearch: function() {
|
||||
var searchTerm = this.$el.find('#searchTerm').val();
|
||||
if( searchTerm ) {
|
||||
bus.app.publish({
|
||||
topic: "search.new.request",
|
||||
data: {
|
||||
searchTerm: searchTerm
|
||||
updateSearch : function () {
|
||||
var searchTerm = this.$el.find( '#searchTerm' ).val();
|
||||
if ( searchTerm ) {
|
||||
bus.app.publish( {
|
||||
topic : "search.new.request",
|
||||
data : {
|
||||
searchTerm : searchTerm
|
||||
}
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
updateView: function() {
|
||||
this.$el.find( "#currentSearch" ).text( this.model.get("searchTerm") );
|
||||
this.$el.find( "#search-ownership").text( this.model.get("searchOwnership" ));
|
||||
this.$el.find( "#request-indicator").text( this.model.get("requests") ? " *" : "" );
|
||||
updateView : function () {
|
||||
this.$el.find( "#currentSearch" ).text( this.model.get( "searchTerm" ) );
|
||||
this.$el.find( "#search-ownership" ).text( this.model.get( "searchOwnership" ) );
|
||||
this.$el.find( "#request-indicator" ).text( this.model.get( "requests" ) ? " *" : "" );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
|
@ -5,36 +5,36 @@ define( [
|
|||
'models/profanity-percentage-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, ProfanityPercentageModel, bus ) {
|
||||
function ( $, Backbone, template, ProfanityPercentageModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
tagName: "div",
|
||||
tagName : "div",
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new ProfanityPercentageModel();
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch );
|
||||
this.model.bind( "change", this.render );
|
||||
this.inDom = false;
|
||||
bus.stats.publish({ topic: "profanity-percentage.getLatest", data: {} });
|
||||
bus.stats.publish( { topic : "profanity-percentage.getLatest", data : {} } );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
// TODO: Capture scroll position and restore after render...
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
if( !this.inDom ) {
|
||||
if ( !this.inDom ) {
|
||||
this.$el.appendTo( "#stats" );
|
||||
this.inDom = true;
|
||||
}
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -5,43 +5,44 @@ define( [
|
|||
'models/search-requests-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, SearchRequestsModel, bus ) {
|
||||
function ( $, Backbone, template, SearchRequestsModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
el: "#requests",
|
||||
el : "#requests",
|
||||
|
||||
events: {
|
||||
"click a.req-allow": "allowSearch"
|
||||
events : {
|
||||
"click a.req-allow" : "allowSearch"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new SearchRequestsModel();
|
||||
this.model.bind( "change", this.render );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
this.model.askForUpdate();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
},
|
||||
|
||||
allowSearch: function ( e ) {
|
||||
var idx = $( e.currentTarget).attr('href'),
|
||||
search = this.model.get("requests")[idx];
|
||||
if( search ) {
|
||||
bus.app.publish({
|
||||
topic: "search.new.confirm",
|
||||
data: search
|
||||
})
|
||||
allowSearch : function ( e ) {
|
||||
var idx = $( e.currentTarget ).attr( 'href' ),
|
||||
search = this.model.get( "requests" )[idx];
|
||||
if ( search ) {
|
||||
bus.app.publish( {
|
||||
topic : "search.new.confirm",
|
||||
data : search
|
||||
} )
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<fieldset>
|
||||
<legend><div class="title">Associated Hash Tags:</div></legend>
|
||||
<legend>
|
||||
<div class="title">Associated Hash Tags:</div>
|
||||
</legend>
|
||||
<div class="scrollableDiv">
|
||||
<table class="hashTagTable" cellspacing="0">
|
||||
<% _.each( hashTags, function( item ) { %>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<table cellspacing="0">
|
||||
<% _.each( mentions, function( mention ) { %>
|
||||
<tr>
|
||||
<td><img class="images" src="<%= mention.image %>" /></td>
|
||||
<td><img class="images" src="<%= mention.image %>"/></td>
|
||||
<td><span><%= mention.user %></span></td>
|
||||
<td><span><%= mention.count %></span></td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<table cellspacing="0">
|
||||
<% _.each( mentioners, function( mentioner ) { %>
|
||||
<tr>
|
||||
<td><img class="images" src="<%= mentioner.image %>" /></td>
|
||||
<td><img class="images" src="<%= mentioner.image %>"/></td>
|
||||
<td><span><%= mentioner.user %></span></td>
|
||||
<td><span><%= mentioner.count %></span></td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
<div>
|
||||
<% if( requests.length > 0 ) { %>
|
||||
<div>
|
||||
<h4>Search Requests <% if( sessionId === ownerId ) { %>(click one to give control to the requester)<% } %></h4>
|
||||
</div>
|
||||
<% _.each( requests, function ( request, idx ) { %>
|
||||
<div>(Client ID: <%= request.correlationId %>) -
|
||||
<% if( sessionId === ownerId ) { %>
|
||||
<a class="req-allow" href="<%= idx %>"><%= request.searchTerm %></a>
|
||||
<% } else { %>
|
||||
<%= request.searchTerm %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% }) %>
|
||||
<div>
|
||||
<h4>Search Requests <% if( sessionId === ownerId ) { %>(click one to give control to the requester)<% } %></h4>
|
||||
</div>
|
||||
<% _.each( requests, function ( request, idx ) { %>
|
||||
<div>(Client ID: <%= request.correlationId %>) -
|
||||
<% if( sessionId === ownerId ) { %>
|
||||
<a class="req-allow" href="<%= idx %>"><%= request.searchTerm %></a>
|
||||
<% } else { %>
|
||||
<%= request.searchTerm %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% }) %>
|
||||
<% } else { %>
|
||||
<div><em>No other searches have been requested at this time.</em></div>
|
||||
<div><em>No other searches have been requested at this time.</em></div>
|
||||
<% } %>
|
||||
</div>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<table cellspacing="0">
|
||||
<% _.each( tweeters, function( tweeter ) { %>
|
||||
<tr>
|
||||
<td><img class="images" src="<%= tweeter.image %>" /></td>
|
||||
<td><img class="images" src="<%= tweeter.image %>"/></td>
|
||||
<td><span><%= tweeter.user %></span></td>
|
||||
<td><span><%= tweeter.count %></span></td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -5,36 +5,36 @@ define( [
|
|||
'models/tweet-count-model',
|
||||
'bus'
|
||||
],
|
||||
function( $, Backbone, template, TweetCountModel, bus ) {
|
||||
function ( $, Backbone, template, TweetCountModel, bus ) {
|
||||
"use strict";
|
||||
|
||||
return Backbone.View.extend( {
|
||||
tagName: "div",
|
||||
tagName : "div",
|
||||
|
||||
initialize: function() {
|
||||
initialize : function () {
|
||||
_.bindAll( this );
|
||||
this.template = _.template( template );
|
||||
this.model = new TweetCountModel();
|
||||
bus.app.subscribe( "search.info", this.setCurrentSearch );
|
||||
this.model.bind( "change", this.render );
|
||||
this.inDom = false;
|
||||
bus.stats.publish({ topic: "tweet-count.getLatest", data: {} });
|
||||
bus.stats.publish( { topic : "tweet-count.getLatest", data : {} } );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
render : function () {
|
||||
// TODO: Capture scroll position and restore after render...
|
||||
this.$el.html( this.template( this.model.toJSON() ) );
|
||||
if( !this.inDom ) {
|
||||
if ( !this.inDom ) {
|
||||
this.$el.appendTo( "#stats" );
|
||||
this.inDom = true;
|
||||
}
|
||||
},
|
||||
|
||||
show: function( data ) {
|
||||
show : function ( data ) {
|
||||
this.$el.show();
|
||||
},
|
||||
|
||||
hide: function( data ) {
|
||||
hide : function ( data ) {
|
||||
this.$el.hide();
|
||||
}
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -1,62 +1,62 @@
|
|||
var _ = require('underscore'),
|
||||
_scanner = function(regExp, text, callback) {
|
||||
var _ = require( 'underscore' ),
|
||||
_scanner = function ( regExp, text, callback ) {
|
||||
var match;
|
||||
while(text.search(regExp) !== -1) {
|
||||
match = regExp.exec(text);
|
||||
if(match && match[1]) {
|
||||
callback(match[1].toLowerCase());
|
||||
while ( text.search( regExp ) !== -1 ) {
|
||||
match = regExp.exec( text );
|
||||
if ( match && match[1] ) {
|
||||
callback( match[1].toLowerCase() );
|
||||
}
|
||||
text = text.replace(regExp, "");
|
||||
text = text.replace( regExp, "" );
|
||||
}
|
||||
},
|
||||
HashTagCount = function(namespace) {
|
||||
HashTagCount = function ( namespace ) {
|
||||
this.namespace = namespace;
|
||||
|
||||
this.events = {};
|
||||
|
||||
this.hashTags = { list: [], registry: {} };
|
||||
this.hashTags = { list : [], registry : {} };
|
||||
|
||||
this.lastStats = undefined;
|
||||
this.lastStats = undefined;
|
||||
|
||||
};
|
||||
|
||||
HashTagCount.prototype = {
|
||||
init: function() {
|
||||
this.hashTags = { list: [], registry: {} };
|
||||
init : function () {
|
||||
this.hashTags = { list : [], registry : {} };
|
||||
this.lastStats = undefined;
|
||||
},
|
||||
on: function( eventName, callback ) {
|
||||
if( !this.events[ eventName ] ) {
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.events[ eventName ] ) {
|
||||
this.events[ eventName ] = [];
|
||||
}
|
||||
this.events[ eventName ].push( callback );
|
||||
return function() {
|
||||
return function () {
|
||||
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
||||
}.bind( this );
|
||||
},
|
||||
raiseEvent: function( eventName, data ) {
|
||||
if( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function( callback ){
|
||||
raiseEvent : function ( eventName, data ) {
|
||||
if ( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function ( callback ) {
|
||||
callback( data );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
processNewTweets: function( tweets ) {
|
||||
tweets.forEach( function( tweet ){
|
||||
processNewTweets : function ( tweets ) {
|
||||
tweets.forEach( function ( tweet ) {
|
||||
this.processOtherHashTags( tweet.text );
|
||||
}, this );
|
||||
this.lastStats = { type: "HashTagCount", hashTags: this.hashTags.list };
|
||||
this.lastStats = { type : "HashTagCount", hashTags : this.hashTags.list };
|
||||
this.raiseEvent( this.namespace, this.lastStats );
|
||||
},
|
||||
processOtherHashTags: function( text ) {
|
||||
_scanner( /#(\w*)/i, text, function( hash ){
|
||||
if( !this.hashTags.registry[ hash ] ) {
|
||||
var obj = { hashTag: hash, count: 0 };
|
||||
processOtherHashTags : function ( text ) {
|
||||
_scanner( /#(\w*)/i, text, function ( hash ) {
|
||||
if ( !this.hashTags.registry[ hash ] ) {
|
||||
var obj = { hashTag : hash, count : 0 };
|
||||
this.hashTags.registry[ hash ] = obj;
|
||||
this.hashTags.list.push( obj );
|
||||
}
|
||||
this.hashTags.registry[ hash ].count++;
|
||||
}.bind( this ));
|
||||
}.bind( this ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,72 +1,72 @@
|
|||
var _ = require('underscore'),
|
||||
_scanner = function(regExp, text, callback) {
|
||||
var _ = require( 'underscore' ),
|
||||
_scanner = function ( regExp, text, callback ) {
|
||||
var match;
|
||||
while(text.search(regExp) !== -1) {
|
||||
match = regExp.exec(text);
|
||||
if(match && match[1]) {
|
||||
callback(match[1].toLowerCase());
|
||||
while ( text.search( regExp ) !== -1 ) {
|
||||
match = regExp.exec( text );
|
||||
if ( match && match[1] ) {
|
||||
callback( match[1].toLowerCase() );
|
||||
}
|
||||
text = text.replace(regExp, "");
|
||||
text = text.replace( regExp, "" );
|
||||
}
|
||||
},
|
||||
MentionCount = function(namespace) {
|
||||
MentionCount = function ( namespace ) {
|
||||
this.namespace = namespace;
|
||||
|
||||
this.events = {};
|
||||
|
||||
this.mentions = { list: [], registry: {} };
|
||||
this.mentions = { list : [], registry : {} };
|
||||
|
||||
this.userImageMap = {};
|
||||
|
||||
this.lastStats = undefined;
|
||||
this.lastStats = undefined;
|
||||
};
|
||||
|
||||
MentionCount.prototype = {
|
||||
init: function() {
|
||||
this.mentions = { list: [], registry: {} };
|
||||
init : function () {
|
||||
this.mentions = { list : [], registry : {} };
|
||||
this.lastStats = undefined;
|
||||
},
|
||||
on: function( eventName, callback ) {
|
||||
if( !this.events[ eventName ] ) {
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.events[ eventName ] ) {
|
||||
this.events[ eventName ] = [];
|
||||
}
|
||||
this.events[ eventName ].push( callback );
|
||||
return function() {
|
||||
return function () {
|
||||
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
||||
}.bind( this );
|
||||
},
|
||||
raiseEvent: function( eventName, data ) {
|
||||
if( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function( callback ){
|
||||
raiseEvent : function ( eventName, data ) {
|
||||
if ( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function ( callback ) {
|
||||
callback( data );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
processNewTweets: function(tweets) {
|
||||
tweets.forEach(function(tweet){
|
||||
processNewTweets : function ( tweets ) {
|
||||
tweets.forEach( function ( tweet ) {
|
||||
this.userImageMap[ tweet.from_user ] = tweet.profile_image_url;
|
||||
this.processMentions(tweet);
|
||||
}, this);
|
||||
this.processMentions( tweet );
|
||||
}, this );
|
||||
this.tryToMatchProfileImages();
|
||||
this.lastStats = { type: "MentionCount", mentions: this.mentions.list };
|
||||
this.lastStats = { type : "MentionCount", mentions : this.mentions.list };
|
||||
this.raiseEvent( this.namespace, this.lastStats );
|
||||
},
|
||||
tryToMatchProfileImages: function() {
|
||||
_.each( this.mentions.registry, function( v, k ){
|
||||
if( this.userImageMap[ k ] ) {
|
||||
tryToMatchProfileImages : function () {
|
||||
_.each( this.mentions.registry, function ( v, k ) {
|
||||
if ( this.userImageMap[ k ] ) {
|
||||
v.image = this.userImageMap[ k ];
|
||||
}
|
||||
}, this );
|
||||
},
|
||||
processMentions: function(tweet) {
|
||||
_scanner(/@(\w*)/i, tweet.text, function(mentioned) {
|
||||
if(!this.mentions.registry[mentioned]) {
|
||||
var obj = { user: mentioned, count: 0, image: "images/default_profile_1_normal.png" };
|
||||
processMentions : function ( tweet ) {
|
||||
_scanner( /@(\w*)/i, tweet.text, function ( mentioned ) {
|
||||
if ( !this.mentions.registry[mentioned] ) {
|
||||
var obj = { user : mentioned, count : 0, image : "images/default_profile_1_normal.png" };
|
||||
this.mentions.registry[mentioned] = obj;
|
||||
this.mentions.list.push(obj);
|
||||
this.mentions.list.push( obj );
|
||||
}
|
||||
this.mentions.registry[mentioned].count++;
|
||||
}.bind(this));
|
||||
}.bind( this ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,61 +1,61 @@
|
|||
var _ = require('underscore'),
|
||||
_scanner = function(regExp, text, callback) {
|
||||
var match;
|
||||
while(text.search(regExp) !== -1) {
|
||||
match = regExp.exec(text);
|
||||
if(match && match[1]) {
|
||||
callback(match[1].toLowerCase());
|
||||
var _ = require( 'underscore' ),
|
||||
_scanner = function ( regExp, text, callback ) {
|
||||
var match;
|
||||
while ( text.search( regExp ) !== -1 ) {
|
||||
match = regExp.exec( text );
|
||||
if ( match && match[1] ) {
|
||||
callback( match[1].toLowerCase() );
|
||||
}
|
||||
text = text.replace(regExp, "");
|
||||
text = text.replace( regExp, "" );
|
||||
}
|
||||
},
|
||||
MentionerCount = function(namespace) {
|
||||
MentionerCount = function ( namespace ) {
|
||||
this.namespace = namespace;
|
||||
|
||||
this.events = {};
|
||||
|
||||
this.mentioners = { list: [], registry: {} };
|
||||
this.mentioners = { list : [], registry : {} };
|
||||
|
||||
this.lastStats = undefined;
|
||||
this.lastStats = undefined;
|
||||
};
|
||||
|
||||
MentionerCount.prototype = {
|
||||
init: function() {
|
||||
this.mentioners = { list: [], registry: {} };
|
||||
init : function () {
|
||||
this.mentioners = { list : [], registry : {} };
|
||||
this.lastStats = undefined;
|
||||
},
|
||||
on: function( eventName, callback ) {
|
||||
if( !this.events[ eventName ] ) {
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.events[ eventName ] ) {
|
||||
this.events[ eventName ] = [];
|
||||
}
|
||||
this.events[ eventName ].push( callback );
|
||||
return function() {
|
||||
return function () {
|
||||
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
||||
}.bind( this );
|
||||
},
|
||||
raiseEvent: function( eventName, data ) {
|
||||
if( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function( callback ){
|
||||
raiseEvent : function ( eventName, data ) {
|
||||
if ( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function ( callback ) {
|
||||
callback( data );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
processNewTweets: function(tweets) {
|
||||
tweets.forEach(function(tweet){
|
||||
this.processMentioners(tweet);
|
||||
}, this);
|
||||
this.lastStats = { type: "MentionerCount", mentioners: this.mentioners.list };
|
||||
processNewTweets : function ( tweets ) {
|
||||
tweets.forEach( function ( tweet ) {
|
||||
this.processMentioners( tweet );
|
||||
}, this );
|
||||
this.lastStats = { type : "MentionerCount", mentioners : this.mentioners.list };
|
||||
this.raiseEvent( this.namespace, this.lastStats );
|
||||
},
|
||||
processMentioners: function(tweet) {
|
||||
_scanner(/@(\w*)/i, tweet.text, function(mentioned) {
|
||||
if(!this.mentioners.registry[tweet.from_user]) {
|
||||
var obj = { user: tweet.from_user, count: 0, image: tweet.profile_image_url };
|
||||
processMentioners : function ( tweet ) {
|
||||
_scanner( /@(\w*)/i, tweet.text, function ( mentioned ) {
|
||||
if ( !this.mentioners.registry[tweet.from_user] ) {
|
||||
var obj = { user : tweet.from_user, count : 0, image : tweet.profile_image_url };
|
||||
this.mentioners.registry[tweet.from_user] = obj;
|
||||
this.mentioners.list.push(obj);
|
||||
this.mentioners.list.push( obj );
|
||||
}
|
||||
this.mentioners.registry[tweet.from_user].count++;
|
||||
}.bind(this));
|
||||
}.bind( this ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -34,70 +34,69 @@ var _badWords = [
|
|||
/\bpiss\b/,
|
||||
/\bpissing\b/
|
||||
],
|
||||
_ = require('underscore'),
|
||||
ProfanityPercentage = function(namespace) {
|
||||
_ = require( 'underscore' ),
|
||||
ProfanityPercentage = function ( namespace ) {
|
||||
this.namespace = namespace;
|
||||
|
||||
this.events = {};
|
||||
|
||||
this.profanityStats = { clean: 0, explicit: 0 };
|
||||
this.profanityStats = { clean : 0, explicit : 0 };
|
||||
|
||||
this.lastStats = undefined;
|
||||
this.lastStats = undefined;
|
||||
};
|
||||
|
||||
ProfanityPercentage.prototype = {
|
||||
init: function() {
|
||||
this.profanityStats = { clean: 0, explicit: 0 };
|
||||
init : function () {
|
||||
this.profanityStats = { clean : 0, explicit : 0 };
|
||||
this.lastStats = undefined;
|
||||
},
|
||||
on: function( eventName, callback ) {
|
||||
if( !this.events[ eventName ] ) {
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.events[ eventName ] ) {
|
||||
this.events[ eventName ] = [];
|
||||
}
|
||||
this.events[ eventName ].push( callback );
|
||||
return function() {
|
||||
return function () {
|
||||
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
||||
}.bind( this );
|
||||
},
|
||||
raiseEvent: function( eventName, data ) {
|
||||
if( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function( callback ){
|
||||
raiseEvent : function ( eventName, data ) {
|
||||
if ( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function ( callback ) {
|
||||
callback( data );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
hasProfanity: function(text) {
|
||||
for(var i = 0; i < _badWords.length; i++) {
|
||||
if(text.search(_badWords[i]) !== -1)
|
||||
{
|
||||
hasProfanity : function ( text ) {
|
||||
for ( var i = 0; i < _badWords.length; i++ ) {
|
||||
if ( text.search( _badWords[i] ) !== -1 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getPercentage: function() {
|
||||
getPercentage : function () {
|
||||
var total = (this.profanityStats.clean + this.profanityStats.explicit);
|
||||
if(total === 0) {
|
||||
if ( total === 0 ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return ((this.profanityStats.explicit / total) * 100).toFixed(2);
|
||||
return ((this.profanityStats.explicit / total) * 100).toFixed( 2 );
|
||||
}
|
||||
},
|
||||
processNewTweets: function(tweets) {
|
||||
tweets.forEach(function(tweet){
|
||||
this.profanitize(tweet);
|
||||
}, this);
|
||||
processNewTweets : function ( tweets ) {
|
||||
tweets.forEach( function ( tweet ) {
|
||||
this.profanitize( tweet );
|
||||
}, this );
|
||||
this.lastStats = {
|
||||
type: "ProfanityPercentage",
|
||||
percentage: this.getPercentage(),
|
||||
clean: this.profanityStats.clean,
|
||||
explicit: this.profanityStats.explicit
|
||||
type : "ProfanityPercentage",
|
||||
percentage : this.getPercentage(),
|
||||
clean : this.profanityStats.clean,
|
||||
explicit : this.profanityStats.explicit
|
||||
};
|
||||
this.raiseEvent( this.namespace, this.lastStats );
|
||||
},
|
||||
profanitize: function(tweet) {
|
||||
if(this.hasProfanity(tweet.text)) {
|
||||
profanitize : function ( tweet ) {
|
||||
if ( this.hasProfanity( tweet.text ) ) {
|
||||
this.profanityStats.explicit++;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1,48 +1,48 @@
|
|||
var _ = require('underscore'),
|
||||
TweetCount = function(namespace) {
|
||||
var _ = require( 'underscore' ),
|
||||
TweetCount = function ( namespace ) {
|
||||
this.namespace = namespace;
|
||||
|
||||
this.events = {};
|
||||
|
||||
this.tweeters = { list: [], registry: {} };
|
||||
this.tweeters = { list : [], registry : {} };
|
||||
|
||||
this.lastStats = undefined;
|
||||
this.lastStats = undefined;
|
||||
};
|
||||
|
||||
TweetCount.prototype = {
|
||||
init: function() {
|
||||
this.tweeters = { list: [], registry: {} };
|
||||
init : function () {
|
||||
this.tweeters = { list : [], registry : {} };
|
||||
this.lastStats = undefined;
|
||||
},
|
||||
on: function( eventName, callback ) {
|
||||
if( !this.events[ eventName ] ) {
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.events[ eventName ] ) {
|
||||
this.events[ eventName ] = [];
|
||||
}
|
||||
this.events[ eventName ].push( callback );
|
||||
return function() {
|
||||
return function () {
|
||||
this.events[ eventName ] = _.without( this.events[ eventName ], callback );
|
||||
}.bind( this );
|
||||
},
|
||||
raiseEvent: function( eventName, data ) {
|
||||
if( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function( callback ){
|
||||
raiseEvent : function ( eventName, data ) {
|
||||
if ( this.events[ eventName ] ) {
|
||||
this.events[ eventName ].forEach( function ( callback ) {
|
||||
callback.call( this, data );
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
processNewTweets: function(tweets) {
|
||||
tweets.forEach(function(tweet){
|
||||
this.processTweetCount(tweet);
|
||||
}, this);
|
||||
this.lastStats = { type: "TweetCount", tweeters: this.tweeters.list };
|
||||
processNewTweets : function ( tweets ) {
|
||||
tweets.forEach( function ( tweet ) {
|
||||
this.processTweetCount( tweet );
|
||||
}, this );
|
||||
this.lastStats = { type : "TweetCount", tweeters : this.tweeters.list };
|
||||
this.raiseEvent( this.namespace, this.lastStats );
|
||||
},
|
||||
processTweetCount : function(tweet) {
|
||||
if(tweet.from_user) {
|
||||
if(!this.tweeters.registry[tweet.from_user]) {
|
||||
var obj = {user: tweet.from_user, count: 0, image: tweet.profile_image_url};
|
||||
processTweetCount : function ( tweet ) {
|
||||
if ( tweet.from_user ) {
|
||||
if ( !this.tweeters.registry[tweet.from_user] ) {
|
||||
var obj = {user : tweet.from_user, count : 0, image : tweet.profile_image_url};
|
||||
this.tweeters.registry[tweet.from_user] = obj;
|
||||
this.tweeters.list.push(obj);
|
||||
this.tweeters.list.push( obj );
|
||||
}
|
||||
this.tweeters.registry[tweet.from_user].count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
var _ = require("underscore"),
|
||||
var _ = require( "underscore" ),
|
||||
express = require( 'express' ),
|
||||
app = express.createServer(),
|
||||
postal = require( "./messaging/postal.js" ),
|
||||
|
|
@ -9,21 +9,21 @@ var _ = require("underscore"),
|
|||
BusAdapter = require( './messaging/bus-adapter.js' ),
|
||||
machina = require( './machina.js' );
|
||||
|
||||
postal.addWireTap( function( data, envelope ){
|
||||
if( envelope.channel === "stats" /*|| envelope.channel === "twittersearch"*/ ) {
|
||||
postal.addWireTap( function ( data, envelope ) {
|
||||
if ( envelope.channel === "stats" /*|| envelope.channel === "twittersearch"*/ ) {
|
||||
var env = _.extend( {}, envelope );
|
||||
delete env.data;
|
||||
console.log( JSON.stringify( env ) );
|
||||
}
|
||||
else if (_.include(["postal.socket", "postal", "app", "app.events"], envelope.channel) ) {
|
||||
else if ( _.include( ["postal.socket", "postal", "app", "app.events"], envelope.channel ) ) {
|
||||
console.log( JSON.stringify( envelope ) );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
// wire machina FSMs into postal automagically
|
||||
require( './messaging/machina.postal.js' )( postal, machina );
|
||||
|
||||
var TwitterSocketStats = function( port, refreshinterval ) {
|
||||
var TwitterSocketStats = function ( port, refreshinterval ) {
|
||||
// Stand up our express app
|
||||
app.use( "/", express.static( __dirname + '/client' ) );
|
||||
app.listen( port );
|
||||
|
|
@ -31,162 +31,164 @@ var TwitterSocketStats = function( port, refreshinterval ) {
|
|||
statsChannel = postal.channel( "stats", "*" ),
|
||||
appChannel = postal.channel( "statsApp", "*" );
|
||||
|
||||
postal.linkChannels( { channel: "postal.socket", topic: "client.migrated"}, { channel: "statsApp", topic: "client.migrated" } );
|
||||
postal.linkChannels( { channel : "postal.socket", topic : "client.migrated"}, { channel : "statsApp", topic : "client.migrated" } );
|
||||
|
||||
return new machina.Fsm({
|
||||
return new machina.Fsm( {
|
||||
|
||||
namespace: "statsApp",
|
||||
namespace : "statsApp",
|
||||
|
||||
currentSearch: {
|
||||
id: null,
|
||||
searchTerm: "{ Search Not Active }"
|
||||
currentSearch : {
|
||||
id : null,
|
||||
searchTerm : "{ Search Not Active }"
|
||||
},
|
||||
|
||||
searchRequests: {},
|
||||
searchRequests : {},
|
||||
|
||||
express: app,
|
||||
express : app,
|
||||
|
||||
appChannel: appChannel,
|
||||
appChannel : appChannel,
|
||||
|
||||
searchChannel: searchChannel,
|
||||
searchChannel : searchChannel,
|
||||
|
||||
statsChannel: statsChannel,
|
||||
statsChannel : statsChannel,
|
||||
|
||||
searchAgent: new BusAdapter(new TwitterSearch( refreshinterval), searchChannel, searchChannel ),
|
||||
searchAgent : new BusAdapter( new TwitterSearch( refreshinterval ), searchChannel, searchChannel ),
|
||||
|
||||
requestedSearches: [],
|
||||
requestedSearches : [],
|
||||
|
||||
stats: collectors.load( searchChannel, statsChannel ),
|
||||
stats : collectors.load( searchChannel, statsChannel ),
|
||||
|
||||
postal: postal,
|
||||
postal : postal,
|
||||
|
||||
bridge: new PostalSocketHost( postal, sockets.getSocketProvider( postal, app ) ),
|
||||
bridge : new PostalSocketHost( postal, sockets.getSocketProvider( postal, app ) ),
|
||||
|
||||
getAvailableStats: function( clientId ) {
|
||||
this.appChannel.publish({
|
||||
topic: "available.topics",
|
||||
correlationId: clientId,
|
||||
data: {
|
||||
topics:_.toArray(this.stats).map(function(stat) { return { channel: "stats", topic: stat.namespace }; })
|
||||
getAvailableStats : function ( clientId ) {
|
||||
this.appChannel.publish( {
|
||||
topic : "available.topics",
|
||||
correlationId : clientId,
|
||||
data : {
|
||||
topics : _.toArray( this.stats ).map( function ( stat ) {
|
||||
return { channel : "stats", topic : stat.namespace };
|
||||
} )
|
||||
}
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
setSearch: function( correlationId, searchTerm ) {
|
||||
setSearch : function ( correlationId, searchTerm ) {
|
||||
this.currentSearch = {
|
||||
id: correlationId,
|
||||
searchTerm: searchTerm
|
||||
id : correlationId,
|
||||
searchTerm : searchTerm
|
||||
};
|
||||
this.searchAgent.search( searchTerm );
|
||||
this.removeSearchRequest( correlationId, searchTerm );
|
||||
this.appChannel.publish({
|
||||
topic: "search.info",
|
||||
data: this.currentSearch
|
||||
});
|
||||
this.appChannel.publish( {
|
||||
topic : "search.info",
|
||||
data : this.currentSearch
|
||||
} );
|
||||
},
|
||||
|
||||
getSearchInfo: function( env ) {
|
||||
this.appChannel.publish({
|
||||
topic: "search.info",
|
||||
correlationId: env.correlationId,
|
||||
data: this.currentSearch
|
||||
});
|
||||
getSearchInfo : function ( env ) {
|
||||
this.appChannel.publish( {
|
||||
topic : "search.info",
|
||||
correlationId : env.correlationId,
|
||||
data : this.currentSearch
|
||||
} );
|
||||
},
|
||||
|
||||
getSearchRequests: function ( env ) {
|
||||
getSearchRequests : function ( env ) {
|
||||
env || (env = {});
|
||||
this.appChannel.publish({
|
||||
topic: "search.requests",
|
||||
correlationId: env.correlationId,
|
||||
data: this.requestedSearches
|
||||
});
|
||||
this.appChannel.publish( {
|
||||
topic : "search.requests",
|
||||
correlationId : env.correlationId,
|
||||
data : this.requestedSearches
|
||||
} );
|
||||
},
|
||||
|
||||
addSearchRequest: function( correlationId, searchTerm ) {
|
||||
if( !_.any( this.searchRequests, function( item ) {
|
||||
addSearchRequest : function ( correlationId, searchTerm ) {
|
||||
if ( !_.any( this.searchRequests, function ( item ) {
|
||||
return item.correlationId === request.correlationId &&
|
||||
item.searchTerm === request.searchTerm;
|
||||
})) {
|
||||
this.requestedSearches.push( { correlationId: correlationId, searchTerm: searchTerm } );
|
||||
item.searchTerm === request.searchTerm;
|
||||
} ) ) {
|
||||
this.requestedSearches.push( { correlationId : correlationId, searchTerm : searchTerm } );
|
||||
}
|
||||
},
|
||||
|
||||
removeSearchRequest: function ( correlationId, searchTerm ) {
|
||||
if(_.any( this.requestedSearches, function ( item ) {
|
||||
removeSearchRequest : function ( correlationId, searchTerm ) {
|
||||
if ( _.any( this.requestedSearches, function ( item ) {
|
||||
return item.correlationId = correlationId && item.searchTerm === searchTerm;
|
||||
})) {
|
||||
this.requestedSearches = _.filter( this.requestedSearches, function ( item ){
|
||||
} ) ) {
|
||||
this.requestedSearches = _.filter( this.requestedSearches, function ( item ) {
|
||||
return item.correlationId !== correlationId && item.searchTerm !== searchTerm;
|
||||
});
|
||||
} );
|
||||
this.getSearchRequests();
|
||||
}
|
||||
},
|
||||
|
||||
states: {
|
||||
uninitialized: {
|
||||
start: function() {
|
||||
this.transition("notSearching");
|
||||
states : {
|
||||
uninitialized : {
|
||||
start : function () {
|
||||
this.transition( "notSearching" );
|
||||
},
|
||||
"*" : function() {
|
||||
"*" : function () {
|
||||
this.deferUntilTransition();
|
||||
}
|
||||
},
|
||||
notSearching: {
|
||||
"search.new.request" : function( data, envelope ) {
|
||||
notSearching : {
|
||||
"search.new.request" : function ( data, envelope ) {
|
||||
this.setSearch( envelope.correlationId, data.searchTerm );
|
||||
this.transition("searching");
|
||||
this.transition( "searching" );
|
||||
},
|
||||
"get.search.info": function( data, env ) {
|
||||
"get.search.info" : function ( data, env ) {
|
||||
this.getSearchInfo( env );
|
||||
},
|
||||
"get.available" : function( data, envelope ) {
|
||||
"get.available" : function ( data, envelope ) {
|
||||
this.getAvailableStats( envelope.correlationId );
|
||||
}
|
||||
},
|
||||
searching: {
|
||||
"search.new.request" : function( data, envelope ) {
|
||||
if( envelope.correlationId === this.currentSearch.id ) {
|
||||
searching : {
|
||||
"search.new.request" : function ( data, envelope ) {
|
||||
if ( envelope.correlationId === this.currentSearch.id ) {
|
||||
this.setSearch( envelope.correlationId, data.searchTerm );
|
||||
}
|
||||
else {
|
||||
this.addSearchRequest( envelope.correlationId, data.searchTerm );
|
||||
this.appChannel.publish({
|
||||
topic: "search.new.ask",
|
||||
data: {
|
||||
correlationId: envelope.correlationId,
|
||||
searchTerm: data.searchTerm
|
||||
this.appChannel.publish( {
|
||||
topic : "search.new.ask",
|
||||
data : {
|
||||
correlationId : envelope.correlationId,
|
||||
searchTerm : data.searchTerm
|
||||
}
|
||||
});
|
||||
} );
|
||||
}
|
||||
},
|
||||
"search.new.confirm" : function( data, envelope ) {
|
||||
if( envelope.correlationId === this.currentSearch.id ) {
|
||||
"search.new.confirm" : function ( data, envelope ) {
|
||||
if ( envelope.correlationId === this.currentSearch.id ) {
|
||||
this.setSearch( data.correlationId, data.searchTerm );
|
||||
}
|
||||
},
|
||||
"get.search.info": function( data, env ) {
|
||||
"get.search.info" : function ( data, env ) {
|
||||
this.getSearchInfo( env );
|
||||
},
|
||||
"get.search.requests": function( data, env ) {
|
||||
"get.search.requests" : function ( data, env ) {
|
||||
this.getSearchRequests( env );
|
||||
},
|
||||
"get.available" : function( data, envelope ) {
|
||||
"get.available" : function ( data, envelope ) {
|
||||
this.getAvailableStats( envelope.correlationId );
|
||||
},
|
||||
"client.migrated" : function( data, envelope ) {
|
||||
if( data.lastSessionId === this.currentSearch.id ) {
|
||||
"client.migrated" : function ( data, envelope ) {
|
||||
if ( data.lastSessionId === this.currentSearch.id ) {
|
||||
this.currentSearch.id = data.sessionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} );
|
||||
};
|
||||
|
||||
var x = module.exports = new TwitterSocketStats( 8002, 7000 );
|
||||
|
||||
x.on("*", function(evnt, data){
|
||||
console.log("FSM Event: " + evnt + " - " + JSON.stringify([].slice.call(arguments,1)));
|
||||
});
|
||||
x.on( "*", function ( evnt, data ) {
|
||||
console.log( "FSM Event: " + evnt + " - " + JSON.stringify( [].slice.call( arguments, 1 ) ) );
|
||||
} );
|
||||
|
||||
x.handle("start");
|
||||
x.handle( "start" );
|
||||
|
|
|
|||
|
|
@ -1,197 +1,197 @@
|
|||
var _ = require('underscore');
|
||||
var _ = require( 'underscore' );
|
||||
/*
|
||||
machina.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
machina.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
|
||||
var slice = [].slice,
|
||||
NEXT_TRANSITION = "transition",
|
||||
NEXT_HANDLER = "handler",
|
||||
transformEventListToObject = function(eventList){
|
||||
transformEventListToObject = function ( eventList ) {
|
||||
var obj = {};
|
||||
_.each(eventList, function(evntName) {
|
||||
_.each( eventList, function ( evntName ) {
|
||||
obj[evntName] = [];
|
||||
});
|
||||
} );
|
||||
return obj;
|
||||
},
|
||||
parseEventListeners = function(evnts) {
|
||||
parseEventListeners = function ( evnts ) {
|
||||
var obj = evnts;
|
||||
if(_.isArray(evnts)) {
|
||||
obj = transformEventListToObject(evnts);
|
||||
if ( _.isArray( evnts ) ) {
|
||||
obj = transformEventListToObject( evnts );
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
utils = {
|
||||
makeFsmNamespace: (function(){
|
||||
makeFsmNamespace : (function () {
|
||||
var machinaCount = 0;
|
||||
return function() {
|
||||
return function () {
|
||||
return "fsm." + machinaCount++;
|
||||
};
|
||||
})(),
|
||||
getDefaultOptions: function() {
|
||||
getDefaultOptions : function () {
|
||||
return {
|
||||
initialState: "uninitialized",
|
||||
eventListeners: {
|
||||
initialState : "uninitialized",
|
||||
eventListeners : {
|
||||
"*" : []
|
||||
},
|
||||
states: {},
|
||||
eventQueue: [],
|
||||
namespace: utils.makeFsmNamespace()
|
||||
states : {},
|
||||
eventQueue : [],
|
||||
namespace : utils.makeFsmNamespace()
|
||||
};
|
||||
}
|
||||
},
|
||||
Fsm = function(options) {
|
||||
var opt, initialState, defaults = utils.getDefaultOptions();
|
||||
if(options) {
|
||||
if(options.eventListeners) {
|
||||
options.eventListeners = parseEventListeners(options.eventListeners);
|
||||
Fsm = function ( options ) {
|
||||
var opt, initialState, defaults = utils.getDefaultOptions();
|
||||
if ( options ) {
|
||||
if ( options.eventListeners ) {
|
||||
options.eventListeners = parseEventListeners( options.eventListeners );
|
||||
}
|
||||
if(options.messaging) {
|
||||
options.messaging = _.extend({}, defaults.messaging, options.messaging);
|
||||
if ( options.messaging ) {
|
||||
options.messaging = _.extend( {}, defaults.messaging, options.messaging );
|
||||
}
|
||||
}
|
||||
opt = _.extend(defaults , options || {});
|
||||
opt = _.extend( defaults, options || {} );
|
||||
initialState = opt.initialState;
|
||||
delete opt.initialState;
|
||||
_.extend(this,opt);
|
||||
_.extend( this, opt );
|
||||
|
||||
this.state = undefined;
|
||||
this._priorAction = "";
|
||||
this._currentAction = "";
|
||||
if(initialState) {
|
||||
this.transition(initialState);
|
||||
if ( initialState ) {
|
||||
this.transition( initialState );
|
||||
}
|
||||
machina.fireEvent("newFsm", this);
|
||||
machina.fireEvent( "newFsm", this );
|
||||
};
|
||||
|
||||
Fsm.prototype.fireEvent = function(eventName) {
|
||||
var args = arguments;
|
||||
_.each(this.eventListeners["*"], function(callback) {
|
||||
Fsm.prototype.fireEvent = function ( eventName ) {
|
||||
var args = arguments;
|
||||
_.each( this.eventListeners["*"], function ( callback ) {
|
||||
try {
|
||||
callback.apply(this,slice.call(args, 0));
|
||||
} catch(exception) {
|
||||
if(console && typeof console.log !== "undefined") {
|
||||
console.log(exception.toString());
|
||||
callback.apply( this, slice.call( args, 0 ) );
|
||||
} catch ( exception ) {
|
||||
if ( console && typeof console.log !== "undefined" ) {
|
||||
console.log( exception.toString() );
|
||||
}
|
||||
}
|
||||
});
|
||||
if(this.eventListeners[eventName]) {
|
||||
_.each(this.eventListeners[eventName], function(callback) {
|
||||
try {
|
||||
callback.apply(this,slice.call(args, 1));
|
||||
} catch(exception) {
|
||||
if(console && typeof console.log !== "undefined") {
|
||||
console.log(exception.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} );
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
_.each( this.eventListeners[eventName], function ( callback ) {
|
||||
try {
|
||||
callback.apply( this, slice.call( args, 1 ) );
|
||||
} catch ( exception ) {
|
||||
if ( console && typeof console.log !== "undefined" ) {
|
||||
console.log( exception.toString() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.handle = function(msgType) {
|
||||
Fsm.prototype.handle = function ( msgType ) {
|
||||
// vars to avoid a "this." fest
|
||||
var states = this.states, current = this.state, args = slice.call(arguments,0), handlerName;
|
||||
var states = this.states, current = this.state, args = slice.call( arguments, 0 ), handlerName;
|
||||
this.currentActionArgs = args;
|
||||
if(states[current] && (states[current][msgType] || states[current]["*"])) {
|
||||
handlerName = states[current][msgType] ? msgType : "*";
|
||||
this._currentAction = current + "." + handlerName;
|
||||
this.fireEvent.apply(this, ["Handling"].concat(args));
|
||||
states[current][handlerName].apply(this, args.slice(1));
|
||||
this.fireEvent.apply(this, ["Handled"].concat(args));
|
||||
this._priorAction = this._currentAction;
|
||||
this._currentAction = "";
|
||||
this.processQueue(NEXT_HANDLER);
|
||||
}
|
||||
else {
|
||||
this.fireEvent.apply(this, ["NoHandler"].concat(args));
|
||||
}
|
||||
if ( states[current] && (states[current][msgType] || states[current]["*"]) ) {
|
||||
handlerName = states[current][msgType] ? msgType : "*";
|
||||
this._currentAction = current + "." + handlerName;
|
||||
this.fireEvent.apply( this, ["Handling"].concat( args ) );
|
||||
states[current][handlerName].apply( this, args.slice( 1 ) );
|
||||
this.fireEvent.apply( this, ["Handled"].concat( args ) );
|
||||
this._priorAction = this._currentAction;
|
||||
this._currentAction = "";
|
||||
this.processQueue( NEXT_HANDLER );
|
||||
}
|
||||
else {
|
||||
this.fireEvent.apply( this, ["NoHandler"].concat( args ) );
|
||||
}
|
||||
this.currentActionArgs = undefined;
|
||||
};
|
||||
|
||||
Fsm.prototype.transition = function(newState) {
|
||||
if(this.states[newState]){
|
||||
var oldState = this.state;
|
||||
this.state = newState;
|
||||
if(this.states[newState]._onEnter) {
|
||||
this.states[newState]._onEnter.call( this );
|
||||
}
|
||||
this.fireEvent.apply(this, ["Transitioned", oldState, this.state ]);
|
||||
this.processQueue(NEXT_TRANSITION);
|
||||
return;
|
||||
}
|
||||
this.fireEvent.apply(this, ["InvalidState", this.state, newState ]);
|
||||
Fsm.prototype.transition = function ( newState ) {
|
||||
if ( this.states[newState] ) {
|
||||
var oldState = this.state;
|
||||
this.state = newState;
|
||||
if ( this.states[newState]._onEnter ) {
|
||||
this.states[newState]._onEnter.call( this );
|
||||
}
|
||||
this.fireEvent.apply( this, ["Transitioned", oldState, this.state ] );
|
||||
this.processQueue( NEXT_TRANSITION );
|
||||
return;
|
||||
}
|
||||
this.fireEvent.apply( this, ["InvalidState", this.state, newState ] );
|
||||
};
|
||||
|
||||
Fsm.prototype.processQueue = function(type) {
|
||||
Fsm.prototype.processQueue = function ( type ) {
|
||||
var filterFn = type === NEXT_TRANSITION ?
|
||||
function(item){
|
||||
return item.type === NEXT_TRANSITION && ((!item.untilState) || (item.untilState === this.state));
|
||||
} :
|
||||
function(item) {
|
||||
return item.type === NEXT_HANDLER;
|
||||
},
|
||||
toProcess = _.filter(this.eventQueue, filterFn, this);
|
||||
this.eventQueue = _.difference(this.eventQueue, toProcess);
|
||||
_.each(toProcess, function(item, index){
|
||||
this.handle.apply(this, item.args);
|
||||
}, this);
|
||||
function ( item ) {
|
||||
return item.type === NEXT_TRANSITION && ((!item.untilState) || (item.untilState === this.state));
|
||||
} :
|
||||
function ( item ) {
|
||||
return item.type === NEXT_HANDLER;
|
||||
},
|
||||
toProcess = _.filter( this.eventQueue, filterFn, this );
|
||||
this.eventQueue = _.difference( this.eventQueue, toProcess );
|
||||
_.each( toProcess, function ( item, index ) {
|
||||
this.handle.apply( this, item.args );
|
||||
}, this );
|
||||
};
|
||||
|
||||
Fsm.prototype.deferUntilTransition = function(stateName) {
|
||||
if(this.currentActionArgs) {
|
||||
var queued = { type: NEXT_TRANSITION, untilState: stateName, args: this.currentActionArgs };
|
||||
this.eventQueue.push(queued);
|
||||
this.fireEvent.apply(this, [ "Deferred", this.state, queued ]);
|
||||
Fsm.prototype.deferUntilTransition = function ( stateName ) {
|
||||
if ( this.currentActionArgs ) {
|
||||
var queued = { type : NEXT_TRANSITION, untilState : stateName, args : this.currentActionArgs };
|
||||
this.eventQueue.push( queued );
|
||||
this.fireEvent.apply( this, [ "Deferred", this.state, queued ] );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.deferUntilNextHandler = function() {
|
||||
if(this.currentActionArgs) {
|
||||
var queued = { type: NEXT_TRANSITION, args: this.currentActionArgs };
|
||||
this.eventQueue.push(queued);
|
||||
this.fireEvent.apply(this, [ "Deferred", this.state, queued ]);
|
||||
Fsm.prototype.deferUntilNextHandler = function () {
|
||||
if ( this.currentActionArgs ) {
|
||||
var queued = { type : NEXT_TRANSITION, args : this.currentActionArgs };
|
||||
this.eventQueue.push( queued );
|
||||
this.fireEvent.apply( this, [ "Deferred", this.state, queued ] );
|
||||
}
|
||||
};
|
||||
|
||||
Fsm.prototype.on = function(eventName, callback) {
|
||||
if(!this.eventListeners[eventName]) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push(callback);
|
||||
Fsm.prototype.on = function ( eventName, callback ) {
|
||||
if ( !this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push( callback );
|
||||
};
|
||||
|
||||
Fsm.prototype.off = function(eventName, callback) {
|
||||
if(this.eventListeners[eventName]){
|
||||
this.eventListeners[eventName] = _.without(this.eventListeners[eventName], callback);
|
||||
}
|
||||
Fsm.prototype.off = function ( eventName, callback ) {
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = _.without( this.eventListeners[eventName], callback );
|
||||
}
|
||||
};
|
||||
|
||||
var machina = {
|
||||
Fsm: Fsm,
|
||||
bus: undefined,
|
||||
utils: utils,
|
||||
on: function(eventName, callback) {
|
||||
if(!this.eventListeners[eventName]) {
|
||||
Fsm : Fsm,
|
||||
bus : undefined,
|
||||
utils : utils,
|
||||
on : function ( eventName, callback ) {
|
||||
if ( !this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push(callback);
|
||||
this.eventListeners[eventName].push( callback );
|
||||
},
|
||||
off: function(eventName, callback) {
|
||||
if(this.eventListeners[eventName]){
|
||||
this.eventListeners[eventName] = _.without(this.eventListeners[eventName], callback);
|
||||
off : function ( eventName, callback ) {
|
||||
if ( this.eventListeners[eventName] ) {
|
||||
this.eventListeners[eventName] = _.without( this.eventListeners[eventName], callback );
|
||||
}
|
||||
},
|
||||
fireEvent: function(eventName) {
|
||||
fireEvent : function ( eventName ) {
|
||||
var i = 0, len, args = arguments, listeners = this.eventListeners[eventName];
|
||||
if(listeners && listeners.length) {
|
||||
_.each(listeners, function(callback) {
|
||||
callback.apply(null,slice.call(args, 1));
|
||||
});
|
||||
if ( listeners && listeners.length ) {
|
||||
_.each( listeners, function ( callback ) {
|
||||
callback.apply( null, slice.call( args, 1 ) );
|
||||
} );
|
||||
}
|
||||
},
|
||||
eventListeners: {
|
||||
eventListeners : {
|
||||
newFsm : []
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
module.exports = function( target, searchChannel, statsChannel ) {
|
||||
module.exports = function ( target, searchChannel, statsChannel ) {
|
||||
target.bus = {
|
||||
subscriptions: [],
|
||||
publishers: [
|
||||
target.on( "newTweets", function( data ) {
|
||||
statsChannel.publish( { topic: "newTweets", data: data } );
|
||||
subscriptions : [],
|
||||
publishers : [
|
||||
target.on( "newTweets", function ( data ) {
|
||||
statsChannel.publish( { topic : "newTweets", data : data } );
|
||||
} ),
|
||||
target.on( "search.current", function( data ) {
|
||||
searchChannel.publish( { topic: "search.current", data: data } );
|
||||
target.on( "search.current", function ( data ) {
|
||||
searchChannel.publish( { topic : "search.current", data : data } );
|
||||
} ),
|
||||
target.on( "search.nodata", function( data ) {
|
||||
searchChannel.publish( { topic: "search.nodata", data: data } );
|
||||
target.on( "search.nodata", function ( data ) {
|
||||
searchChannel.publish( { topic : "search.nodata", data : data } );
|
||||
} ),
|
||||
target.on( "search.init", function ( data ) {
|
||||
searchChannel.publish( { topic : "search.init", data : data } );
|
||||
} )
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
module.exports = function( target, searchChannel, statChannel ) {
|
||||
module.exports = function ( target, searchChannel, statChannel ) {
|
||||
target.bus = {
|
||||
subscriptions: [
|
||||
searchChannel.subscribe( "init", target.init ).withContext( target ),
|
||||
subscriptions : [
|
||||
searchChannel.subscribe( "search.init", target.init ).withContext( target ),
|
||||
searchChannel.subscribe( "newTweets", target.processNewTweets ).withContext( target ),
|
||||
statChannel.subscribe( target.namespace + ".getLatest", function( data, env ){
|
||||
console.log("GET LATEST FOR: " + target.namespace);
|
||||
statChannel.publish( {
|
||||
topic: target.namespace,
|
||||
data: target.lastStats,
|
||||
correlationId: env.correlationId
|
||||
})
|
||||
}).withContext( target )
|
||||
statChannel.subscribe( target.namespace + ".getLatest",
|
||||
function ( data, env ) {
|
||||
console.log( "GET LATEST FOR: " + target.namespace );
|
||||
statChannel.publish( {
|
||||
topic : target.namespace,
|
||||
data : target.lastStats,
|
||||
correlationId : env.correlationId
|
||||
} )
|
||||
} ).withContext( target )
|
||||
],
|
||||
publishers: [
|
||||
target.on( target.namespace, function( data ) {
|
||||
statChannel.publish( { topic: target.namespace, data: data } );
|
||||
publishers : [
|
||||
target.on( target.namespace, function ( data ) {
|
||||
statChannel.publish( { topic : target.namespace, data : data } );
|
||||
} )
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,45 +1,45 @@
|
|||
/*
|
||||
machina.postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
/*
|
||||
machina.postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.1.0
|
||||
*/
|
||||
|
||||
module.exports = function(postal, machina) {
|
||||
module.exports = function ( postal, machina ) {
|
||||
var bus = machina.bus = {
|
||||
channels: {},
|
||||
config: {
|
||||
handlerChannelSuffix: "",
|
||||
eventChannelSuffix: ".events"
|
||||
channels : {},
|
||||
config : {
|
||||
handlerChannelSuffix : "",
|
||||
eventChannelSuffix : ".events"
|
||||
},
|
||||
wireHandlersToBus: function(fsm, handlerChannel) {
|
||||
wireHandlersToBus : function ( fsm, handlerChannel ) {
|
||||
bus.channels[handlerChannel]._subscriptions.push(
|
||||
bus.channels[handlerChannel].subscribe("*", function(data, envelope){
|
||||
fsm.handle.call(fsm, envelope.topic, data, envelope);
|
||||
})
|
||||
bus.channels[handlerChannel].subscribe( "*", function ( data, envelope ) {
|
||||
fsm.handle.call( fsm, envelope.topic, data, envelope );
|
||||
} )
|
||||
);
|
||||
},
|
||||
wireEventsToBus: function(fsm, eventChannel) {
|
||||
var publisher = bus.channels[eventChannel].eventPublisher = function(){
|
||||
wireEventsToBus : function ( fsm, eventChannel ) {
|
||||
var publisher = bus.channels[eventChannel].eventPublisher = function () {
|
||||
try {
|
||||
bus.channels[eventChannel].publish({ topic: arguments[0], data: arguments[1] || {} });
|
||||
} catch(exception) {
|
||||
if(console && typeof console.log !== "undefined") {
|
||||
console.log(exception.toString());
|
||||
bus.channels[eventChannel].publish( { topic : arguments[0], data : arguments[1] || {} } );
|
||||
} catch ( exception ) {
|
||||
if ( console && typeof console.log !== "undefined" ) {
|
||||
console.log( exception.toString() );
|
||||
}
|
||||
}
|
||||
};
|
||||
fsm.on("*", publisher);
|
||||
fsm.on( "*", publisher );
|
||||
},
|
||||
wireUp: function(fsm) {
|
||||
wireUp : function ( fsm ) {
|
||||
var handlerChannel = fsm.namespace + bus.config.handlerChannelSuffix,
|
||||
eventChannel = fsm.namespace + bus.config.eventChannelSuffix;
|
||||
bus.channels[handlerChannel] = postal.channel({ channel: handlerChannel });
|
||||
bus.channels[eventChannel] = postal.channel({ channel: eventChannel });
|
||||
eventChannel = fsm.namespace + bus.config.eventChannelSuffix;
|
||||
bus.channels[handlerChannel] = postal.channel( { channel : handlerChannel } );
|
||||
bus.channels[eventChannel] = postal.channel( { channel : eventChannel } );
|
||||
bus.channels[handlerChannel]._subscriptions = [];
|
||||
bus.wireHandlersToBus(fsm, handlerChannel);
|
||||
bus.wireEventsToBus(fsm, eventChannel);
|
||||
bus.wireHandlersToBus( fsm, handlerChannel );
|
||||
bus.wireEventsToBus( fsm, eventChannel );
|
||||
}
|
||||
};
|
||||
machina.on("newFsm", bus.wireUp);
|
||||
machina.on( "newFsm", bus.wireUp );
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = function( _, postal ) {
|
||||
module.exports = function ( _, postal ) {
|
||||
var filters = [],
|
||||
applyFilter = function ( filter, env ) {
|
||||
var match = 0, possible = 0;
|
||||
|
|
@ -44,7 +44,9 @@ module.exports = function( _, postal ) {
|
|||
}
|
||||
} );
|
||||
|
||||
postal.diagnostics = {
|
||||
postal.diagnostics = postal.diagnostics || {};
|
||||
|
||||
postal.diagnostics.console = {
|
||||
clearFilters : function () {
|
||||
filters = [];
|
||||
},
|
||||
|
|
@ -57,13 +59,13 @@ module.exports = function( _, postal ) {
|
|||
if ( !_.isArray( constraint ) ) {
|
||||
constraint = [ constraint ];
|
||||
}
|
||||
_.each( constraint, function( item ){
|
||||
_.each( constraint, function ( item ) {
|
||||
if ( filters.length === 0 || !_.any( filters, function ( filter ) {
|
||||
return _.isEqual( filter, item );
|
||||
} ) ) {
|
||||
filters.push( item );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
},
|
||||
getCurrentFilters : function () {
|
||||
|
|
|
|||
|
|
@ -1,225 +1,228 @@
|
|||
/*
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
postal.js
|
||||
Author: Jim Cowart
|
||||
License: Dual licensed MIT (http://www.opensource.org/licenses/mit-license) & GPL (http://www.opensource.org/licenses/gpl-license)
|
||||
Version 0.6.0
|
||||
*/
|
||||
|
||||
// This is the node.js version of postal.js
|
||||
// If you need the standard or amd client lib version, go to http://github.com/ifandelse/postal.js
|
||||
var _ = require('underscore');
|
||||
var _ = require( 'underscore' );
|
||||
|
||||
var DEFAULT_CHANNEL = "/",
|
||||
DEFAULT_PRIORITY = 50,
|
||||
DEFAULT_DISPOSEAFTER = 0,
|
||||
SYSTEM_CHANNEL = "postal",
|
||||
NO_OP = function() { };
|
||||
NO_OP = function () {
|
||||
};
|
||||
|
||||
var DistinctPredicate = function() {
|
||||
var DistinctPredicate = function () {
|
||||
var previous;
|
||||
return function(data) {
|
||||
return function ( data ) {
|
||||
var eq = false;
|
||||
if(_.isString(data)) {
|
||||
if ( _.isString( data ) ) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
eq = _.isEqual( data, previous );
|
||||
previous = _.clone( data );
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var ChannelDefinition = function(channelName, defaultTopic) {
|
||||
var ChannelDefinition = function ( channelName, defaultTopic ) {
|
||||
this.channel = channelName || DEFAULT_CHANNEL;
|
||||
this._topic = defaultTopic || "";
|
||||
};
|
||||
|
||||
ChannelDefinition.prototype = {
|
||||
subscribe: function() {
|
||||
subscribe : function () {
|
||||
var len = arguments.length;
|
||||
if(len === 1) {
|
||||
return new SubscriptionDefinition(this.channel, this._topic, arguments[0]);
|
||||
if ( len === 1 ) {
|
||||
return new SubscriptionDefinition( this.channel, this._topic, arguments[0] );
|
||||
}
|
||||
else if (len === 2) {
|
||||
return new SubscriptionDefinition(this.channel, arguments[0], arguments[1]);
|
||||
else if ( len === 2 ) {
|
||||
return new SubscriptionDefinition( this.channel, arguments[0], arguments[1] );
|
||||
}
|
||||
},
|
||||
|
||||
publish: function(obj) {
|
||||
publish : function ( obj ) {
|
||||
var envelope = {
|
||||
channel: this.channel,
|
||||
topic: this._topic,
|
||||
data: obj || {}
|
||||
channel : this.channel,
|
||||
topic : this._topic,
|
||||
data : obj || {}
|
||||
};
|
||||
// If this is an envelope....
|
||||
if( obj.topic && obj.data ) {
|
||||
if ( obj.topic && obj.data ) {
|
||||
envelope = obj;
|
||||
envelope.channel = envelope.channel || this.channel;
|
||||
}
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
|
||||
topic: function(topic) {
|
||||
if(topic === this._topic) {
|
||||
topic : function ( topic ) {
|
||||
if ( topic === this._topic ) {
|
||||
return this;
|
||||
}
|
||||
return new ChannelDefinition(this.channel, topic);
|
||||
return new ChannelDefinition( this.channel, topic );
|
||||
}
|
||||
};
|
||||
|
||||
var SubscriptionDefinition = function(channel, topic, callback) {
|
||||
var SubscriptionDefinition = function ( channel, topic, callback ) {
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.callback = callback;
|
||||
this.priority = DEFAULT_PRIORITY;
|
||||
this.constraints = new Array(0);
|
||||
this.constraints = new Array( 0 );
|
||||
this.maxCalls = DEFAULT_DISPOSEAFTER;
|
||||
this.onHandled = NO_OP;
|
||||
this.context = null;
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.created",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.created",
|
||||
channel: channel,
|
||||
topic: topic
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.created",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.created",
|
||||
channel : channel,
|
||||
topic : topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
postal.configuration.bus.subscribe(this);
|
||||
postal.configuration.bus.subscribe( this );
|
||||
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function() {
|
||||
postal.configuration.bus.unsubscribe(this);
|
||||
postal.configuration.bus.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "subscription.removed",
|
||||
timeStamp: new Date(),
|
||||
data: {
|
||||
event: "subscription.removed",
|
||||
channel: this.channel,
|
||||
topic: this.topic
|
||||
unsubscribe : function () {
|
||||
postal.configuration.bus.unsubscribe( this );
|
||||
postal.configuration.bus.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "subscription.removed",
|
||||
timeStamp : new Date(),
|
||||
data : {
|
||||
event : "subscription.removed",
|
||||
channel : this.channel,
|
||||
topic : this.topic
|
||||
}
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
defer: function() {
|
||||
defer : function () {
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(fn,0,data);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( fn, 0, data );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
disposeAfter: function(maxCalls) {
|
||||
if(_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
disposeAfter : function ( maxCalls ) {
|
||||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
|
||||
var fn = this.onHandled;
|
||||
var dispose = _.after(maxCalls, _.bind(function() {
|
||||
this.unsubscribe(this);
|
||||
}, this));
|
||||
var dispose = _.after( maxCalls, _.bind( function () {
|
||||
this.unsubscribe( this );
|
||||
}, this ) );
|
||||
|
||||
this.onHandled = function() {
|
||||
fn.apply(this.context, arguments);
|
||||
this.onHandled = function () {
|
||||
fn.apply( this.context, arguments );
|
||||
dispose();
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
ignoreDuplicates: function() {
|
||||
this.withConstraint(new DistinctPredicate());
|
||||
ignoreDuplicates : function () {
|
||||
this.withConstraint( new DistinctPredicate() );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraint: function(predicate) {
|
||||
if(! _.isFunction(predicate)) {
|
||||
withConstraint : function ( predicate ) {
|
||||
if ( !_.isFunction( predicate ) ) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
this.constraints.push(predicate);
|
||||
this.constraints.push( predicate );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraints: function(predicates) {
|
||||
withConstraints : function ( predicates ) {
|
||||
var self = this;
|
||||
if(_.isArray(predicates)) {
|
||||
_.each(predicates, function(predicate) { self.withConstraint(predicate); } );
|
||||
if ( _.isArray( predicates ) ) {
|
||||
_.each( predicates, function ( predicate ) {
|
||||
self.withConstraint( predicate );
|
||||
} );
|
||||
}
|
||||
return self;
|
||||
},
|
||||
|
||||
withContext: function(context) {
|
||||
withContext : function ( context ) {
|
||||
this.context = context;
|
||||
return this;
|
||||
},
|
||||
|
||||
withDebounce: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDebounce : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.debounce(fn, milliseconds);
|
||||
this.callback = _.debounce( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
withDelay: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withDelay : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = function(data) {
|
||||
setTimeout(function(){
|
||||
fn(data);
|
||||
}, milliseconds);
|
||||
this.callback = function ( data ) {
|
||||
setTimeout( function () {
|
||||
fn( data );
|
||||
}, milliseconds );
|
||||
};
|
||||
return this;
|
||||
},
|
||||
|
||||
withPriority: function(priority) {
|
||||
if(_.isNaN(priority)) {
|
||||
withPriority : function ( priority ) {
|
||||
if ( _.isNaN( priority ) ) {
|
||||
throw "Priority must be a number";
|
||||
}
|
||||
this.priority = priority;
|
||||
return this;
|
||||
},
|
||||
|
||||
withThrottle: function(milliseconds) {
|
||||
if(_.isNaN(milliseconds)) {
|
||||
withThrottle : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
var fn = this.callback;
|
||||
this.callback = _.throttle(fn, milliseconds);
|
||||
this.callback = _.throttle( fn, milliseconds );
|
||||
return this;
|
||||
},
|
||||
|
||||
subscribe: function(callback) {
|
||||
subscribe : function ( callback ) {
|
||||
this.callback = callback;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
var bindingsResolver = {
|
||||
cache: { },
|
||||
cache : { },
|
||||
|
||||
compare: function(binding, topic) {
|
||||
if(this.cache[topic] && this.cache[topic][binding]) {
|
||||
compare : function ( binding, topic ) {
|
||||
if ( this.cache[topic] && this.cache[topic][binding] ) {
|
||||
return true;
|
||||
}
|
||||
// binding.replace(/\./g,"\\.") // escape actual periods
|
||||
// .replace(/\*/g, ".*") // asterisks match any value
|
||||
// .replace(/#/g, "[A-Z,a-z,0-9]*"); // hash matches any alpha-numeric 'word'
|
||||
var rgx = new RegExp("^" + binding.replace(/\./g,"\\.").replace(/\*/g, ".*").replace(/#/g, "[A-Z,a-z,0-9]*") + "$"),
|
||||
result = rgx.test(topic);
|
||||
if(result) {
|
||||
if(!this.cache[topic]) {
|
||||
var rgx = new RegExp( "^" + binding.replace( /\./g, "\\." ).replace( /\*/g, ".*" ).replace( /#/g, "[A-Z,a-z,0-9]*" ) + "$" ),
|
||||
result = rgx.test( topic );
|
||||
if ( result ) {
|
||||
if ( !this.cache[topic] ) {
|
||||
this.cache[topic] = {};
|
||||
}
|
||||
this.cache[topic][binding] = true;
|
||||
|
|
@ -227,91 +230,93 @@ var bindingsResolver = {
|
|||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
this.cache = {};
|
||||
}
|
||||
};
|
||||
|
||||
var localBus = {
|
||||
|
||||
addWireTap: function(callback) {
|
||||
addWireTap : function ( callback ) {
|
||||
var self = this;
|
||||
self.wireTaps.push(callback);
|
||||
return function() {
|
||||
var idx = self.wireTaps.indexOf(callback);
|
||||
if(idx !== -1) {
|
||||
self.wireTaps.splice(idx,1);
|
||||
self.wireTaps.push( callback );
|
||||
return function () {
|
||||
var idx = self.wireTaps.indexOf( callback );
|
||||
if ( idx !== -1 ) {
|
||||
self.wireTaps.splice( idx, 1 );
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
publish: function(envelope) {
|
||||
_.each(this.wireTaps,function(tap) {
|
||||
tap(envelope.data, envelope);
|
||||
});
|
||||
publish : function ( envelope ) {
|
||||
_.each( this.wireTaps, function ( tap ) {
|
||||
tap( envelope.data, envelope );
|
||||
} );
|
||||
|
||||
_.each(this.subscriptions[envelope.channel], function(topic) {
|
||||
_.each(topic, function(subDef){
|
||||
if(postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
||||
if(_.all(subDef.constraints, function(constraint) { return constraint(envelope.data,envelope); })) {
|
||||
if(typeof subDef.callback === 'function') {
|
||||
subDef.callback.apply(subDef.context, [envelope.data, envelope]);
|
||||
_.each( this.subscriptions[envelope.channel], function ( topic ) {
|
||||
_.each( topic, function ( subDef ) {
|
||||
if ( postal.configuration.resolver.compare( subDef.topic, envelope.topic ) ) {
|
||||
if ( _.all( subDef.constraints, function ( constraint ) {
|
||||
return constraint( envelope.data, envelope );
|
||||
} ) ) {
|
||||
if ( typeof subDef.callback === 'function' ) {
|
||||
subDef.callback.apply( subDef.context, [envelope.data, envelope] );
|
||||
subDef.onHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if( this.subscriptions ) {
|
||||
_.each( this.subscriptions , function( channel ){
|
||||
_.each( channel, function( topic ){
|
||||
while( topic.length ) {
|
||||
reset : function () {
|
||||
if ( this.subscriptions ) {
|
||||
_.each( this.subscriptions, function ( channel ) {
|
||||
_.each( channel, function ( topic ) {
|
||||
while ( topic.length ) {
|
||||
topic.pop().unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
this.subscriptions = {};
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(subDef) {
|
||||
subscribe : function ( subDef ) {
|
||||
var idx, found, fn, channel = this.subscriptions[subDef.channel], subs;
|
||||
|
||||
if(!channel) {
|
||||
if ( !channel ) {
|
||||
channel = this.subscriptions[subDef.channel] = {};
|
||||
}
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
||||
if(!subs) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array(0);
|
||||
if ( !subs ) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = new Array( 0 );
|
||||
}
|
||||
|
||||
idx = subs.length - 1;
|
||||
for(; idx >= 0; idx--) {
|
||||
if(subs[idx].priority <= subDef.priority) {
|
||||
subs.splice(idx + 1, 0, subDef);
|
||||
for ( ; idx >= 0; idx-- ) {
|
||||
if ( subs[idx].priority <= subDef.priority ) {
|
||||
subs.splice( idx + 1, 0, subDef );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
subs.unshift(subDef);
|
||||
if ( !found ) {
|
||||
subs.unshift( subDef );
|
||||
}
|
||||
return subDef;
|
||||
},
|
||||
|
||||
subscriptions: {},
|
||||
subscriptions : {},
|
||||
|
||||
wireTaps: new Array(0),
|
||||
wireTaps : new Array( 0 ),
|
||||
|
||||
unsubscribe: function(config) {
|
||||
if(this.subscriptions[config.channel][config.topic]) {
|
||||
unsubscribe : function ( config ) {
|
||||
if ( this.subscriptions[config.channel][config.topic] ) {
|
||||
var len = this.subscriptions[config.channel][config.topic].length,
|
||||
idx = 0;
|
||||
for ( ; idx < len; idx++ ) {
|
||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
||||
if ( this.subscriptions[config.channel][config.topic][idx] === config ) {
|
||||
this.subscriptions[config.channel][config.topic].splice( idx, 1 );
|
||||
break;
|
||||
}
|
||||
|
|
@ -321,50 +326,50 @@ var localBus = {
|
|||
};
|
||||
|
||||
var publishPicker = {
|
||||
"1" : function(envelope) {
|
||||
if(!envelope) {
|
||||
throw new Error("publishing from the 'global' postal.publish call requires a valid envelope.");
|
||||
"1" : function ( envelope ) {
|
||||
if ( !envelope ) {
|
||||
throw new Error( "publishing from the 'global' postal.publish call requires a valid envelope." );
|
||||
}
|
||||
envelope.channel = envelope.channel || DEFAULT_CHANNEL;
|
||||
envelope.timeStamp = new Date();
|
||||
postal.configuration.bus.publish(envelope);
|
||||
return envelope;
|
||||
},
|
||||
"2" : function(topic, data) {
|
||||
var envelope = { channel: DEFAULT_CHANNEL, topic: topic, timeStamp: new Date(), data: data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function(channel, topic, data) {
|
||||
var envelope = { channel: channel, topic: topic, timeStamp: new Date(), data: data };
|
||||
"2" : function ( topic, data ) {
|
||||
var envelope = { channel : DEFAULT_CHANNEL, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
},
|
||||
"3" : function ( channel, topic, data ) {
|
||||
var envelope = { channel : channel, topic : topic, timeStamp : new Date(), data : data };
|
||||
postal.configuration.bus.publish( envelope );
|
||||
return envelope;
|
||||
}
|
||||
},
|
||||
channelPicker = {
|
||||
"1" : function( chn ) {
|
||||
"1" : function ( chn ) {
|
||||
var channel = chn, topic, options = {};
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
}
|
||||
else {
|
||||
channel = chn.channel || DEFAULT_CHANNEL;
|
||||
topic = chn.topic;
|
||||
topic = chn.topic;
|
||||
options = chn.options || options;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"2" : function( chn, tpc ) {
|
||||
"2" : function ( chn, tpc ) {
|
||||
var channel = chn, topic = tpc, options = {};
|
||||
if( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
if ( Object.prototype.toString.call( tpc ) === "[object Object]" ) {
|
||||
channel = DEFAULT_CHANNEL;
|
||||
topic = chn;
|
||||
topic = chn;
|
||||
options = tpc;
|
||||
}
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
},
|
||||
"3" : function( channel, topic, options ) {
|
||||
"3" : function ( channel, topic, options ) {
|
||||
return new postal.channelTypes[ options.type || "local" ]( channel, topic );
|
||||
}
|
||||
},
|
||||
|
|
@ -374,110 +379,110 @@ var publishPicker = {
|
|||
localBus.subscriptions[SYSTEM_CHANNEL] = {};
|
||||
|
||||
var postal = {
|
||||
configuration: {
|
||||
bus: localBus,
|
||||
resolver: bindingsResolver,
|
||||
getSessionIdAction: function( callback ) {
|
||||
configuration : {
|
||||
bus : localBus,
|
||||
resolver : bindingsResolver,
|
||||
getSessionIdAction : function ( callback ) {
|
||||
callback( sessionInfo );
|
||||
},
|
||||
setSessionIdAction: function( info, callback ) {
|
||||
setSessionIdAction : function ( info, callback ) {
|
||||
sessionInfo = info;
|
||||
callback( sessionInfo );
|
||||
},
|
||||
DEFAULT_CHANNEL: DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY: DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER: DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL: SYSTEM_CHANNEL
|
||||
DEFAULT_CHANNEL : DEFAULT_CHANNEL,
|
||||
DEFAULT_PRIORITY : DEFAULT_PRIORITY,
|
||||
DEFAULT_DISPOSEAFTER : DEFAULT_DISPOSEAFTER,
|
||||
SYSTEM_CHANNEL : SYSTEM_CHANNEL
|
||||
},
|
||||
|
||||
channelTypes: {
|
||||
local: ChannelDefinition
|
||||
channelTypes : {
|
||||
local : ChannelDefinition
|
||||
},
|
||||
|
||||
channel: function() {
|
||||
channel : function () {
|
||||
var len = arguments.length;
|
||||
if(channelPicker[len]) {
|
||||
return channelPicker[len].apply(this, arguments);
|
||||
if ( channelPicker[len] ) {
|
||||
return channelPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(options) {
|
||||
subscribe : function ( options ) {
|
||||
var callback = options.callback,
|
||||
topic = options.topic,
|
||||
channel = options.channel || DEFAULT_CHANNEL;
|
||||
return new SubscriptionDefinition(channel, topic, callback);
|
||||
return new SubscriptionDefinition( channel, topic, callback );
|
||||
},
|
||||
|
||||
publish: function() {
|
||||
publish : function () {
|
||||
var len = arguments.length;
|
||||
if(publishPicker[len]) {
|
||||
return publishPicker[len].apply(this, arguments);
|
||||
if ( publishPicker[len] ) {
|
||||
return publishPicker[len].apply( this, arguments );
|
||||
}
|
||||
},
|
||||
|
||||
addWireTap: function(callback) {
|
||||
return this.configuration.bus.addWireTap(callback);
|
||||
addWireTap : function ( callback ) {
|
||||
return this.configuration.bus.addWireTap( callback );
|
||||
},
|
||||
|
||||
linkChannels: function(sources, destinations) {
|
||||
linkChannels : function ( sources, destinations ) {
|
||||
var result = [];
|
||||
if(!_.isArray(sources)) {
|
||||
if ( !_.isArray( sources ) ) {
|
||||
sources = [sources];
|
||||
}
|
||||
if(!_.isArray(destinations)) {
|
||||
if ( !_.isArray( destinations ) ) {
|
||||
destinations = [destinations];
|
||||
}
|
||||
_.each(sources, function(source){
|
||||
_.each( sources, function ( source ) {
|
||||
var sourceTopic = source.topic || "*";
|
||||
_.each(destinations, function(destination) {
|
||||
_.each( destinations, function ( destination ) {
|
||||
var destChannel = destination.channel || DEFAULT_CHANNEL;
|
||||
result.push(
|
||||
postal.subscribe({
|
||||
channel: source.channel || DEFAULT_CHANNEL,
|
||||
topic: source.topic || "*",
|
||||
callback : function(data, env) {
|
||||
postal.subscribe( {
|
||||
channel : source.channel || DEFAULT_CHANNEL,
|
||||
topic : source.topic || "*",
|
||||
callback : function ( data, env ) {
|
||||
var newEnv = env;
|
||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
||||
newEnv.topic = _.isFunction( destination.topic ) ? destination.topic( env.topic ) : destination.topic || env.topic;
|
||||
newEnv.channel = destChannel;
|
||||
newEnv.data = data;
|
||||
postal.publish(newEnv);
|
||||
postal.publish( newEnv );
|
||||
}
|
||||
})
|
||||
} )
|
||||
);
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
return result;
|
||||
},
|
||||
|
||||
utils: {
|
||||
getSessionId: function( callback ) {
|
||||
utils : {
|
||||
getSessionId : function ( callback ) {
|
||||
postal.configuration.getSessionIdAction.call( this, callback );
|
||||
},
|
||||
|
||||
setSessionId: function( value, callback ) {
|
||||
postal.utils.getSessionId( function( info ) {
|
||||
setSessionId : function ( value, callback ) {
|
||||
postal.utils.getSessionId( function ( info ) {
|
||||
// get the session info to move id to last id
|
||||
info.lastId = info.id;
|
||||
info.id = value;
|
||||
// invoke the callback the user provided to handle storing session
|
||||
postal.configuration.setSessionIdAction( info, function( session ) {
|
||||
postal.configuration.setSessionIdAction( info, function ( session ) {
|
||||
callback( session );
|
||||
// publish postal event msg about the change
|
||||
postal.publish({
|
||||
channel: SYSTEM_CHANNEL,
|
||||
topic: "sessionId.changed",
|
||||
data: session
|
||||
});
|
||||
postal.publish( {
|
||||
channel : SYSTEM_CHANNEL,
|
||||
topic : "sessionId.changed",
|
||||
data : session
|
||||
} );
|
||||
} );
|
||||
});
|
||||
} );
|
||||
},
|
||||
|
||||
getSubscribersFor: function() {
|
||||
getSubscribersFor : function () {
|
||||
var channel = arguments[ 0 ],
|
||||
tpc = arguments[ 1 ],
|
||||
result = [];
|
||||
if( arguments.length === 1 ) {
|
||||
if( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
if ( arguments.length === 1 ) {
|
||||
if ( Object.prototype.toString.call( channel ) === "[object String]" ) {
|
||||
channel = postal.configuration.DEFAULT_CHANNEL;
|
||||
tpc = arguments[ 0 ];
|
||||
}
|
||||
|
|
@ -486,14 +491,14 @@ var postal = {
|
|||
tpc = arguments[ 0 ].topic;
|
||||
}
|
||||
}
|
||||
if( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc )) {
|
||||
if ( postal.configuration.bus.subscriptions[ channel ] &&
|
||||
postal.configuration.bus.subscriptions[ channel ].hasOwnProperty( tpc ) ) {
|
||||
result = postal.configuration.bus.subscriptions[ channel ][ tpc ];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset : function () {
|
||||
postal.configuration.bus.reset();
|
||||
postal.configuration.resolver.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +1,69 @@
|
|||
var _ = require('underscore'),
|
||||
machina = require('../machina.js');
|
||||
var _ = require( 'underscore' ),
|
||||
machina = require( '../machina.js' );
|
||||
|
||||
/*
|
||||
A RemoteClientProxy instance is a finite state machine that manages
|
||||
how a socket is used, and how it is (or isn't) allowed to interact
|
||||
with the server-side instance of postal, depending on the state
|
||||
related to the connection and the client on the other end of the socket.
|
||||
A RemoteClientProxy instance is a finite state machine that manages
|
||||
how a socket is used, and how it is (or isn't) allowed to interact
|
||||
with the server-side instance of postal, depending on the state
|
||||
related to the connection and the client on the other end of the socket.
|
||||
*/
|
||||
var RemoteClientProxy = function( postal, socketClient, bridge ) {
|
||||
var RemoteClientProxy = function ( postal, socketClient, bridge ) {
|
||||
// helper function to handle when a socket client wants
|
||||
// to set up a subscription to server-side messages
|
||||
var subscribe = function( data ) {
|
||||
var subscribe = function ( data ) {
|
||||
var self = this;
|
||||
if( !self.subscriptions[ data.channel ] ) {
|
||||
if ( !self.subscriptions[ data.channel ] ) {
|
||||
self.subscriptions[ data.channel ] = {};
|
||||
}
|
||||
if( !self.subscriptions[ data.channel ][ data.topic ] ) {
|
||||
if ( !self.subscriptions[ data.channel ][ data.topic ] ) {
|
||||
self.subscriptions[ data.channel ][ data.topic ] =
|
||||
postal.subscribe({
|
||||
channel : data.channel,
|
||||
topic : data.topic,
|
||||
callback: function( d, e ) {
|
||||
self.handle( "socketTransmit", d, e );
|
||||
postal.subscribe( {
|
||||
channel : data.channel,
|
||||
topic : data.topic,
|
||||
callback : function ( d, e ) {
|
||||
self.handle( "socketTransmit", d, e );
|
||||
}
|
||||
} ).withConstraint( function ( data, env ) {
|
||||
if ( !env.correlationId ) {
|
||||
return true;
|
||||
}
|
||||
}).withConstraint(function( data, env ) {
|
||||
if( !env.correlationId ) {
|
||||
return true;
|
||||
}
|
||||
return env.correlationId === self.sessionId;
|
||||
});
|
||||
return env.correlationId === self.sessionId;
|
||||
} );
|
||||
}
|
||||
},
|
||||
// The actual FSM managing the socketClient
|
||||
fsm = new machina.Fsm({
|
||||
// The actual FSM managing the socketClient
|
||||
fsm = new machina.Fsm( {
|
||||
// handle to the socket client wrapper
|
||||
socket: socketClient,
|
||||
socket : socketClient,
|
||||
|
||||
// object used to store (and lookup) subscriptions owned by this connection/client
|
||||
subscriptions: {},
|
||||
subscriptions : {},
|
||||
|
||||
// method to allow a RemoteClientProxy to hand off state to another RemoteClientProxy
|
||||
// as part of a migration
|
||||
getClientState: function() {
|
||||
getClientState : function () {
|
||||
return {
|
||||
queuedMsgs: _.filter( this.eventQueue, function( item ) {
|
||||
queuedMsgs : _.filter( this.eventQueue, function ( item ) {
|
||||
return item.args[0] === "socketTransmit";
|
||||
})
|
||||
} )
|
||||
};
|
||||
},
|
||||
|
||||
sessionId: null,
|
||||
sessionId : null,
|
||||
|
||||
states: {
|
||||
states : {
|
||||
// we start here after an explicit transition from uninitialized
|
||||
// the only message we are interested in is "clientId" - in which
|
||||
// the client tells us who they are, and we determine if we need
|
||||
// to move through a migration first, or go directly to 'connected'
|
||||
connecting: {
|
||||
"*" : function() {
|
||||
connecting : {
|
||||
"*" : function () {
|
||||
this.deferUntilTransition();
|
||||
},
|
||||
clientId : function( session ) {
|
||||
clientId : function ( session ) {
|
||||
console.log( "SESSION STUFF: " + JSON.stringify( session ) );
|
||||
this.sessionId = session.id;
|
||||
if( bridge.enableMigration && session.lastId && session.lastId !== session.id ) {
|
||||
if ( bridge.enableMigration && session.lastId && session.lastId !== session.id ) {
|
||||
this.lastSessionId = session.lastId;
|
||||
this.transition( "migrating" );
|
||||
}
|
||||
|
|
@ -74,105 +75,107 @@ var RemoteClientProxy = function( postal, socketClient, bridge ) {
|
|||
// we're going to get any relevant state from the old RemoteClientProxy
|
||||
// and apply it to this instance. This includes the publishing of
|
||||
// messages that got queued up at the old RemoteClientProxy.
|
||||
migrating: {
|
||||
migrating : {
|
||||
// We tell the client to handle it's migration work (if any) first.
|
||||
_onEnter: function() {
|
||||
_onEnter : function () {
|
||||
console.log( "TELLING CLIENT TO MIGRATE" )
|
||||
this.socket.migrateClientSubscriptions();
|
||||
},
|
||||
// Once the client has completed its migration tasks, it will
|
||||
// publish a message that triggers this handler. This is where we
|
||||
// transfer queued messages from the old RemoteClientProxy, etc.
|
||||
migrationComplete: function ( data ) {
|
||||
if( bridge.clientMap[ this.lastSessionId ] ){
|
||||
migrationComplete : function ( data ) {
|
||||
if ( bridge.clientMap[ this.lastSessionId ] ) {
|
||||
console.log( "LAST SESSION ID EXISTS" )
|
||||
var priorState = bridge.clientMap[ this.lastSessionId ].getClientState();
|
||||
_.each(priorState.queuedMsgs, function( item ) {
|
||||
_.each( priorState.queuedMsgs, function ( item ) {
|
||||
this.eventQueue.unshift( item );
|
||||
}, this );
|
||||
}
|
||||
postal.publish( {
|
||||
channel: "postal.socket",
|
||||
topic: "client.migrated",
|
||||
data: {
|
||||
sessionId: this.socket.id,
|
||||
lastSessionId: this.lastSessionId
|
||||
channel : "postal.socket",
|
||||
topic : "client.migrated",
|
||||
data : {
|
||||
sessionId : this.socket.id,
|
||||
lastSessionId : this.lastSessionId
|
||||
}
|
||||
} );
|
||||
this.transition( "connected" );
|
||||
},
|
||||
subscribe : subscribe,
|
||||
"*": function() {
|
||||
"*" : function () {
|
||||
this.deferUntilTransition();
|
||||
}
|
||||
},
|
||||
// We're online and this is how to handle it....
|
||||
connected: {
|
||||
_onEnter: function() {
|
||||
connected : {
|
||||
_onEnter : function () {
|
||||
bridge.clientMap[ this.sessionId ] = this;
|
||||
this.socket.confirmClientIdentified( this.sessionId );
|
||||
},
|
||||
disconnect: function() {
|
||||
disconnect : function () {
|
||||
this.transition( "disconnected" );
|
||||
},
|
||||
subscribe : subscribe,
|
||||
unsubscribe: function( data ) {
|
||||
if( this.subscriptions[ data.channel ] && this.subscriptions[ data.channel ][ data.topic ] ) {
|
||||
unsubscribe : function ( data ) {
|
||||
if ( this.subscriptions[ data.channel ] && this.subscriptions[ data.channel ][ data.topic ] ) {
|
||||
this.subscriptions[ data.channel ] && this.subscriptions[ data.channel ][ data.topic ].unsubscribe();
|
||||
}
|
||||
},
|
||||
publish: function( envelope ) {
|
||||
publish : function ( envelope ) {
|
||||
postal.publish( envelope );
|
||||
},
|
||||
socketTransmit: function( data, envelope ) {
|
||||
socketTransmit : function ( data, envelope ) {
|
||||
this.socket.publish.call( this.socket, data, envelope );
|
||||
}
|
||||
},
|
||||
disconnected: {
|
||||
_onEnter: function() {
|
||||
disconnected : {
|
||||
_onEnter : function () {
|
||||
postal.publish( {
|
||||
channel: "postal.socket",
|
||||
topic: "client.disconnect",
|
||||
data: {
|
||||
sessionId: this.sessionId
|
||||
channel : "postal.socket",
|
||||
topic : "client.disconnect",
|
||||
data : {
|
||||
sessionId : this.sessionId
|
||||
}
|
||||
} );
|
||||
},
|
||||
"*" : function() {
|
||||
"*" : function () {
|
||||
this.deferUntilTransition();
|
||||
},
|
||||
socketTransmit: function() {
|
||||
this.deferUntilTransition("connected");
|
||||
socketTransmit : function () {
|
||||
this.deferUntilTransition( "connected" );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} );
|
||||
// These are all the events from our Socket Client wrapper to which we need to listen.
|
||||
_.each([ "disconnect", "subscribe", "unsubscribe", "publish", "clientId", "migrationComplete" ], function ( evnt ) {
|
||||
socketClient.on( evnt, function( data ) {
|
||||
_.each( [ "disconnect", "subscribe", "unsubscribe", "publish", "clientId", "migrationComplete" ], function ( evnt ) {
|
||||
socketClient.on( evnt, function ( data ) {
|
||||
fsm.handle( evnt, data );
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
||||
// This is currently here for debugging purposes only
|
||||
fsm.on("*", function(evnt, data){
|
||||
var args = [].slice.call(arguments,1);
|
||||
if(evnt === "Deferred" || args[0] === "socketTransmit") {
|
||||
console.log("Socket FSM: " + evnt + " - " + JSON.stringify(args[0]));
|
||||
fsm.on( "*", function ( evnt, data ) {
|
||||
var args = [].slice.call( arguments, 1 );
|
||||
if ( evnt === "Deferred" || args[0] === "socketTransmit" ) {
|
||||
console.log( "Socket FSM: " + evnt + " - " + JSON.stringify( args[0] ) );
|
||||
}
|
||||
else {
|
||||
console.log("Socket FSM: " + evnt + " - " + JSON.stringify(args));
|
||||
console.log( "Socket FSM: " + evnt + " - " + JSON.stringify( args ) );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
// every RemoteClientProxy gets a private subscription that can talk to the client
|
||||
// apart from any application-level channels. This is a "utility" conduit.
|
||||
fsm.subscriptions._direct = {
|
||||
_private: postal.subscribe({
|
||||
_private : postal.subscribe( {
|
||||
channel : socketClient.id,
|
||||
topic : "*",
|
||||
callback: function(d, e) {
|
||||
fsm.handle("socketTransmit", d, e);
|
||||
topic : "*",
|
||||
callback : function ( d, e ) {
|
||||
fsm.handle( "socketTransmit", d, e );
|
||||
}
|
||||
})
|
||||
} )
|
||||
};
|
||||
|
||||
// we explicitly start the FSM now that we've wired everything up, etc.
|
||||
|
|
@ -180,7 +183,7 @@ var RemoteClientProxy = function( postal, socketClient, bridge ) {
|
|||
return fsm;
|
||||
};
|
||||
|
||||
var PostalSocketHost = function( postal, socketProvider ) {
|
||||
var PostalSocketHost = function ( postal, socketProvider ) {
|
||||
var self = this;
|
||||
|
||||
// if enableMigration === true, then clients are allowed to migrate
|
||||
|
|
@ -195,7 +198,7 @@ var PostalSocketHost = function( postal, socketProvider ) {
|
|||
self.enableMigration = true;
|
||||
|
||||
|
||||
self.channel = postal.channel("postal.socket", "client.connect");
|
||||
self.channel = postal.channel( "postal.socket", "client.connect" );
|
||||
|
||||
// array of clients - confirmed or not
|
||||
self.clients = [];
|
||||
|
|
@ -205,19 +208,19 @@ var PostalSocketHost = function( postal, socketProvider ) {
|
|||
self.clientMap = {};
|
||||
|
||||
// how to clean up a client
|
||||
self.removeClient = function( id ) {
|
||||
if( self.clientMap[ id ] ) {
|
||||
_.each( self.clientMap[ id ].subscriptions, function( channel ){
|
||||
_.each( channel, function( sub ){
|
||||
console.log("unsubscribing: " + sub.channel + " - " + sub.topic);
|
||||
self.removeClient = function ( id ) {
|
||||
if ( self.clientMap[ id ] ) {
|
||||
_.each( self.clientMap[ id ].subscriptions, function ( channel ) {
|
||||
_.each( channel, function ( sub ) {
|
||||
console.log( "unsubscribing: " + sub.channel + " - " + sub.topic );
|
||||
sub.unsubscribe();
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
delete self.clientMap[ id ];
|
||||
}
|
||||
self.clients = _.filter(self.clients, function( item ) {
|
||||
self.clients = _.filter( self.clients, function ( item ) {
|
||||
return item.sessionId !== id;
|
||||
});
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -225,22 +228,22 @@ var PostalSocketHost = function( postal, socketProvider ) {
|
|||
|
||||
// when our provider indicates a new socket has connected, we pass
|
||||
// the socket wrapper to an fsm (RemoteClientProxy) to be managed by it.
|
||||
self.provider.on( "connect", function( socket ) {
|
||||
self.provider.on( "connect", function ( socket ) {
|
||||
self.clients.push( new RemoteClientProxy( postal, socket, self ) );
|
||||
});
|
||||
} );
|
||||
|
||||
// when a client disconnects, if enableMigration is true, we don't delete
|
||||
// the old session until it has been used in a migration
|
||||
self.channel.subscribe("client.disconnect", function ( data, envelope ){
|
||||
if( !self.enableMigration ) {
|
||||
self.channel.subscribe( "client.disconnect", function ( data, envelope ) {
|
||||
if ( !self.enableMigration ) {
|
||||
self.removeClient( data.sessionId );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
// if a session has been used in a migration and is no longer needed, remove it
|
||||
self.channel.subscribe("client.migrated", function ( data, envelope ){
|
||||
self.channel.subscribe( "client.migrated", function ( data, envelope ) {
|
||||
self.removeClient( data.lastSessionId );
|
||||
});
|
||||
} );
|
||||
};
|
||||
|
||||
module.exports = PostalSocketHost;
|
||||
|
|
@ -1,96 +1,96 @@
|
|||
var _ = require('underscore'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
util = require('util');
|
||||
var _ = require( 'underscore' ),
|
||||
EventEmitter = require( 'events' ).EventEmitter,
|
||||
util = require( 'util' );
|
||||
|
||||
module.exports = {
|
||||
getSocketProvider:function( postal, app, options ) {
|
||||
getSocketProvider : function ( postal, app, options ) {
|
||||
/*
|
||||
Socket client wrappers must provide the following:
|
||||
1.) an "id" property which returns the session identifier for the connection
|
||||
2.) EventEmitter's "on" method call (to subscribe callbacks to events)
|
||||
3.) publish the following events (consumed by the postal socket host:
|
||||
a.) disconnect - triggered when the socket disconnects.
|
||||
b.) publish - triggered when the client at the other end of the socket
|
||||
publishes a message. The callback(s) for this event should receive
|
||||
a valid postal.js message envelope, and should ideally include a
|
||||
correlationId that matches the client wrapper id.
|
||||
{
|
||||
channel: "someChannel",
|
||||
topic: "some.topic",
|
||||
data: {
|
||||
greeting: "Oh, hai!"
|
||||
},
|
||||
timeStamp: "2012-04-17T07:11:14.731Z",
|
||||
correlationId: "195371348624696856"
|
||||
}
|
||||
c.) unsubscribe - triggered when the client at the other end of the socket
|
||||
specified that they want to unsubscribe a server-side subscription tied
|
||||
to the socket. The callback(s) for this event should receive an object
|
||||
that contains the channel name and topic to unsubscribe:
|
||||
{ channel: "someChannel", topic: "some.topic" }
|
||||
d.) subscribe - triggered when the client at the other end of the socket
|
||||
specifies that they want to subscribe on the server-side, and have messages
|
||||
forwarded over the socket down the client. The callback(s) for this event
|
||||
should receive an object that contains the channel name and topic to which
|
||||
the client wants to subscribe:
|
||||
{ channel: "someChannel", topic: "some.topic" }
|
||||
e.) clientId - triggered when the client sends a message containing the current
|
||||
and previous (if one exists) session id. The callback(s) for this event
|
||||
should receive an object similar to the following:
|
||||
{ sessionId: "5072013211555684761", lastSessionId: "15075244651115973710" }
|
||||
f.) migrationComplete - triggered when the client is done migrating any state from
|
||||
an old session id to the current one. The callbacks do not need an arg provided.
|
||||
Socket client wrappers must provide the following:
|
||||
1.) an "id" property which returns the session identifier for the connection
|
||||
2.) EventEmitter's "on" method call (to subscribe callbacks to events)
|
||||
3.) publish the following events (consumed by the postal socket host:
|
||||
a.) disconnect - triggered when the socket disconnects.
|
||||
b.) publish - triggered when the client at the other end of the socket
|
||||
publishes a message. The callback(s) for this event should receive
|
||||
a valid postal.js message envelope, and should ideally include a
|
||||
correlationId that matches the client wrapper id.
|
||||
{
|
||||
channel: "someChannel",
|
||||
topic: "some.topic",
|
||||
data: {
|
||||
greeting: "Oh, hai!"
|
||||
},
|
||||
timeStamp: "2012-04-17T07:11:14.731Z",
|
||||
correlationId: "195371348624696856"
|
||||
}
|
||||
c.) unsubscribe - triggered when the client at the other end of the socket
|
||||
specified that they want to unsubscribe a server-side subscription tied
|
||||
to the socket. The callback(s) for this event should receive an object
|
||||
that contains the channel name and topic to unsubscribe:
|
||||
{ channel: "someChannel", topic: "some.topic" }
|
||||
d.) subscribe - triggered when the client at the other end of the socket
|
||||
specifies that they want to subscribe on the server-side, and have messages
|
||||
forwarded over the socket down the client. The callback(s) for this event
|
||||
should receive an object that contains the channel name and topic to which
|
||||
the client wants to subscribe:
|
||||
{ channel: "someChannel", topic: "some.topic" }
|
||||
e.) clientId - triggered when the client sends a message containing the current
|
||||
and previous (if one exists) session id. The callback(s) for this event
|
||||
should receive an object similar to the following:
|
||||
{ sessionId: "5072013211555684761", lastSessionId: "15075244651115973710" }
|
||||
f.) migrationComplete - triggered when the client is done migrating any state from
|
||||
an old session id to the current one. The callbacks do not need an arg provided.
|
||||
|
||||
*/
|
||||
var SocketIoClient = function( socket ) {
|
||||
var SocketIoClient = function ( socket ) {
|
||||
var self = this;
|
||||
EventEmitter.call(self);
|
||||
EventEmitter.call( self );
|
||||
|
||||
self.socket = socket;
|
||||
Object.defineProperty( self, "id", {
|
||||
get: function() {
|
||||
get : function () {
|
||||
return self.socket.id;
|
||||
},
|
||||
enumerable : true
|
||||
});
|
||||
} );
|
||||
|
||||
// wire up what to do when this socket disconnects
|
||||
self.socket.on( 'disconnect', function () {
|
||||
self.emit( "disconnect", self );
|
||||
});
|
||||
} );
|
||||
|
||||
// set up event hooks for postal specific events
|
||||
_.each( [ "publish", "unsubscribe", "subscribe", "clientId", "migrationComplete" ], function( evnt ) {
|
||||
self.socket.on( "postal." + evnt, function( data ){
|
||||
_.each( [ "publish", "unsubscribe", "subscribe", "clientId", "migrationComplete" ], function ( evnt ) {
|
||||
self.socket.on( "postal." + evnt, function ( data ) {
|
||||
self.emit( evnt, data );
|
||||
} );
|
||||
});
|
||||
} );
|
||||
};
|
||||
|
||||
util.inherits(SocketIoClient, EventEmitter);
|
||||
util.inherits( SocketIoClient, EventEmitter );
|
||||
|
||||
SocketIoClient.prototype.publish = function( data, envelope ) {
|
||||
SocketIoClient.prototype.publish = function ( data, envelope ) {
|
||||
this.socket.emit( "postal.socket.remote", envelope );
|
||||
};
|
||||
SocketIoClient.prototype.confirmClientIdentified = function( uid ) {
|
||||
this.socket.emit( "postal.socket.identified", { uid: uid } );
|
||||
SocketIoClient.prototype.confirmClientIdentified = function ( uid ) {
|
||||
this.socket.emit( "postal.socket.identified", { uid : uid } );
|
||||
};
|
||||
SocketIoClient.prototype.migrateClientSubscriptions = function() {
|
||||
SocketIoClient.prototype.migrateClientSubscriptions = function () {
|
||||
this.socket.emit( "postal.socket.migration", {} );
|
||||
};
|
||||
|
||||
/*
|
||||
The Socket Provider is a wrapper around the framework being
|
||||
used to provide websocket functionality to postal.socket.
|
||||
The implementation below wraps socket.io.
|
||||
The Socket Provider is a wrapper around the framework being
|
||||
used to provide websocket functionality to postal.socket.
|
||||
The implementation below wraps socket.io.
|
||||
*/
|
||||
var SocketIoProvider = function( webApp, opt ) {
|
||||
var SocketIoProvider = function ( webApp, opt ) {
|
||||
var opt = opt || {},
|
||||
io = require( 'socket.io' ).listen( webApp ),
|
||||
self = this;
|
||||
io.set( 'log level', opt.ioLogLevel || 1 );
|
||||
|
||||
EventEmitter.call(self);
|
||||
EventEmitter.call( self );
|
||||
|
||||
self.events = {
|
||||
"connect" : []
|
||||
|
|
@ -100,13 +100,13 @@ module.exports = {
|
|||
// Then we take that socket instance and wrap it in our SocketIoClient
|
||||
// wrapper. The PostalSocketHost receives an instance of this
|
||||
// SocketIoProvider object and subscribes to the "connect" event.
|
||||
io.sockets.on( "connection", function( socket ) {
|
||||
io.sockets.on( "connection", function ( socket ) {
|
||||
var _socket = new SocketIoClient( socket );
|
||||
self.emit("connect", _socket);
|
||||
});
|
||||
self.emit( "connect", _socket );
|
||||
} );
|
||||
};
|
||||
|
||||
util.inherits(SocketIoProvider, EventEmitter);
|
||||
util.inherits( SocketIoProvider, EventEmitter );
|
||||
|
||||
return new SocketIoProvider( app, options );
|
||||
}
|
||||
|
|
|
|||
3
example/node/node_modules/express/index.js
generated
vendored
3
example/node/node_modules/express/index.js
generated
vendored
|
|
@ -1,2 +1 @@
|
|||
|
||||
module.exports = require('./lib/express');
|
||||
module.exports = require( './lib/express' );
|
||||
29
example/node/node_modules/express/lib/express.js
generated
vendored
29
example/node/node_modules/express/lib/express.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,14 +8,14 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var connect = require('connect')
|
||||
, HTTPSServer = require('./https')
|
||||
, HTTPServer = require('./http')
|
||||
, Route = require('./router/route')
|
||||
var connect = require( 'connect' )
|
||||
, HTTPSServer = require( './https' )
|
||||
, HTTPServer = require( './http' )
|
||||
, Route = require( './router/route' )
|
||||
|
||||
/**
|
||||
* Re-export connect auto-loaders.
|
||||
*
|
||||
*
|
||||
* This prevents the need to `require('connect')` in order
|
||||
* to access core middleware, so for example `express.logger()` instead
|
||||
* of `require('connect').logger()`.
|
||||
|
|
@ -38,12 +37,12 @@ exports.version = '2.5.8';
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports.createServer = function(options){
|
||||
if ('object' == typeof options) {
|
||||
return new HTTPSServer(options, Array.prototype.slice.call(arguments, 1));
|
||||
} else {
|
||||
return new HTTPServer(Array.prototype.slice.call(arguments));
|
||||
}
|
||||
exports.createServer = function ( options ) {
|
||||
if ( 'object' == typeof options ) {
|
||||
return new HTTPSServer( options, Array.prototype.slice.call( arguments, 1 ) );
|
||||
} else {
|
||||
return new HTTPServer( Array.prototype.slice.call( arguments ) );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -59,19 +58,19 @@ exports.Route = Route;
|
|||
*/
|
||||
|
||||
exports.View =
|
||||
exports.view = require('./view');
|
||||
exports.view = require( './view' );
|
||||
|
||||
/**
|
||||
* Response extensions.
|
||||
*/
|
||||
|
||||
require('./response');
|
||||
require( './response' );
|
||||
|
||||
/**
|
||||
* Request extensions.
|
||||
*/
|
||||
|
||||
require('./request');
|
||||
require( './request' );
|
||||
|
||||
// Error handler title
|
||||
|
||||
|
|
|
|||
440
example/node/node_modules/express/lib/http.js
generated
vendored
440
example/node/node_modules/express/lib/http.js
generated
vendored
|
|
@ -8,15 +8,15 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var qs = require('qs')
|
||||
, connect = require('connect')
|
||||
, router = require('./router')
|
||||
, Router = require('./router')
|
||||
, view = require('./view')
|
||||
, toArray = require('./utils').toArray
|
||||
, methods = router.methods.concat('del', 'all')
|
||||
, url = require('url')
|
||||
, utils = connect.utils;
|
||||
var qs = require( 'qs' )
|
||||
, connect = require( 'connect' )
|
||||
, router = require( './router' )
|
||||
, Router = require( './router' )
|
||||
, view = require( './view' )
|
||||
, toArray = require( './utils' ).toArray
|
||||
, methods = router.methods.concat( 'del', 'all' )
|
||||
, url = require( 'url' )
|
||||
, utils = connect.utils;
|
||||
|
||||
/**
|
||||
* Expose `HTTPServer`.
|
||||
|
|
@ -37,10 +37,11 @@ var app = HTTPServer.prototype;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
function HTTPServer(middleware){
|
||||
connect.HTTPServer.call(this, []);
|
||||
this.init(middleware);
|
||||
};
|
||||
function HTTPServer( middleware ) {
|
||||
connect.HTTPServer.call( this, [] );
|
||||
this.init( middleware );
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Inherit from `connect.HTTPServer`.
|
||||
|
|
@ -55,83 +56,84 @@ app.__proto__ = connect.HTTPServer.prototype;
|
|||
* @api private
|
||||
*/
|
||||
|
||||
app.init = function(middleware){
|
||||
var self = this;
|
||||
this.cache = {};
|
||||
this.settings = {};
|
||||
this.redirects = {};
|
||||
this.isCallbacks = {};
|
||||
this._locals = {};
|
||||
this.dynamicViewHelpers = {};
|
||||
this.errorHandlers = [];
|
||||
app.init = function ( middleware ) {
|
||||
var self = this;
|
||||
this.cache = {};
|
||||
this.settings = {};
|
||||
this.redirects = {};
|
||||
this.isCallbacks = {};
|
||||
this._locals = {};
|
||||
this.dynamicViewHelpers = {};
|
||||
this.errorHandlers = [];
|
||||
|
||||
this.set('env', process.env.NODE_ENV || 'development');
|
||||
this.set( 'env', process.env.NODE_ENV || 'development' );
|
||||
|
||||
// expose objects to each other
|
||||
this.use(function(req, res, next){
|
||||
req.query = req.query || {};
|
||||
res.setHeader('X-Powered-By', 'Express');
|
||||
req.app = res.app = self;
|
||||
req.res = res;
|
||||
res.req = req;
|
||||
req.next = next;
|
||||
// assign req.query
|
||||
if (req.url.indexOf('?') > 0) {
|
||||
var query = url.parse(req.url).query;
|
||||
req.query = qs.parse(query);
|
||||
}
|
||||
next();
|
||||
});
|
||||
// expose objects to each other
|
||||
this.use( function ( req, res, next ) {
|
||||
req.query = req.query || {};
|
||||
res.setHeader( 'X-Powered-By', 'Express' );
|
||||
req.app = res.app = self;
|
||||
req.res = res;
|
||||
res.req = req;
|
||||
req.next = next;
|
||||
// assign req.query
|
||||
if ( req.url.indexOf( '?' ) > 0 ) {
|
||||
var query = url.parse( req.url ).query;
|
||||
req.query = qs.parse( query );
|
||||
}
|
||||
next();
|
||||
} );
|
||||
|
||||
// apply middleware
|
||||
if (middleware) middleware.forEach(self.use.bind(self));
|
||||
// apply middleware
|
||||
if ( middleware ) {
|
||||
middleware.forEach( self.use.bind( self ) );
|
||||
}
|
||||
|
||||
// router
|
||||
this.routes = new Router(this);
|
||||
this.__defineGetter__('router', function(){
|
||||
this.__usedRouter = true;
|
||||
return self.routes.middleware;
|
||||
});
|
||||
// router
|
||||
this.routes = new Router( this );
|
||||
this.__defineGetter__( 'router', function () {
|
||||
this.__usedRouter = true;
|
||||
return self.routes.middleware;
|
||||
} );
|
||||
|
||||
// default locals
|
||||
this.locals({
|
||||
settings: this.settings
|
||||
, app: this
|
||||
});
|
||||
// default locals
|
||||
this.locals( {
|
||||
settings : this.settings, app : this
|
||||
} );
|
||||
|
||||
// default development configuration
|
||||
this.configure('development', function(){
|
||||
this.enable('hints');
|
||||
});
|
||||
// default development configuration
|
||||
this.configure( 'development', function () {
|
||||
this.enable( 'hints' );
|
||||
} );
|
||||
|
||||
// default production configuration
|
||||
this.configure('production', function(){
|
||||
this.enable('view cache');
|
||||
});
|
||||
// default production configuration
|
||||
this.configure( 'production', function () {
|
||||
this.enable( 'view cache' );
|
||||
} );
|
||||
|
||||
// register error handlers on "listening"
|
||||
// so that they disregard definition position.
|
||||
this.on('listening', this.registerErrorHandlers.bind(this));
|
||||
// register error handlers on "listening"
|
||||
// so that they disregard definition position.
|
||||
this.on( 'listening', this.registerErrorHandlers.bind( this ) );
|
||||
|
||||
// route manipulation methods
|
||||
methods.forEach(function(method){
|
||||
self.lookup[method] = function(path){
|
||||
return self.routes.lookup(method, path);
|
||||
};
|
||||
// route manipulation methods
|
||||
methods.forEach( function ( method ) {
|
||||
self.lookup[method] = function ( path ) {
|
||||
return self.routes.lookup( method, path );
|
||||
};
|
||||
|
||||
self.match[method] = function(path){
|
||||
return self.routes.match(method, path);
|
||||
};
|
||||
self.match[method] = function ( path ) {
|
||||
return self.routes.match( method, path );
|
||||
};
|
||||
|
||||
self.remove[method] = function(path){
|
||||
return self.routes.lookup(method, path).remove();
|
||||
};
|
||||
});
|
||||
self.remove[method] = function ( path ) {
|
||||
return self.routes.lookup( method, path ).remove();
|
||||
};
|
||||
} );
|
||||
|
||||
// del -> delete
|
||||
self.lookup.del = self.lookup.delete;
|
||||
self.match.del = self.match.delete;
|
||||
self.remove.del = self.remove.delete;
|
||||
// del -> delete
|
||||
self.lookup.del = self.lookup.delete;
|
||||
self.match.del = self.match.delete;
|
||||
self.remove.del = self.remove.delete;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -142,8 +144,8 @@ app.init = function(middleware){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.remove = function(path){
|
||||
return this.routes.lookup('all', path).remove();
|
||||
app.remove = function ( path ) {
|
||||
return this.routes.lookup( 'all', path ).remove();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -155,8 +157,8 @@ app.remove = function(path){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.lookup = function(path){
|
||||
return this.routes.lookup('all', path);
|
||||
app.lookup = function ( path ) {
|
||||
return this.routes.lookup( 'all', path );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -167,16 +169,16 @@ app.lookup = function(path){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.match = function(url){
|
||||
return this.routes.match('all', url);
|
||||
app.match = function ( url ) {
|
||||
return this.routes.match( 'all', url );
|
||||
};
|
||||
|
||||
/**
|
||||
* When using the vhost() middleware register error handlers.
|
||||
*/
|
||||
|
||||
app.onvhost = function(){
|
||||
this.registerErrorHandlers();
|
||||
app.onvhost = function () {
|
||||
this.registerErrorHandlers();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -186,13 +188,13 @@ app.onvhost = function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.registerErrorHandlers = function(){
|
||||
this.errorHandlers.forEach(function(fn){
|
||||
this.use(function(err, req, res, next){
|
||||
fn.apply(this, arguments);
|
||||
});
|
||||
}, this);
|
||||
return this;
|
||||
app.registerErrorHandlers = function () {
|
||||
this.errorHandlers.forEach( function ( fn ) {
|
||||
this.use( function ( err, req, res, next ) {
|
||||
fn.apply( this, arguments );
|
||||
} );
|
||||
}, this );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -205,42 +207,48 @@ app.registerErrorHandlers = function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.use = function(route, middleware){
|
||||
var app, base, handle;
|
||||
app.use = function ( route, middleware ) {
|
||||
var app, base, handle;
|
||||
|
||||
if ('string' != typeof route) {
|
||||
middleware = route, route = '/';
|
||||
}
|
||||
if ( 'string' != typeof route ) {
|
||||
middleware = route, route = '/';
|
||||
}
|
||||
|
||||
// express app
|
||||
if (middleware.handle && middleware.set) app = middleware;
|
||||
// express app
|
||||
if ( middleware.handle && middleware.set ) {
|
||||
app = middleware;
|
||||
}
|
||||
|
||||
// restore .app property on req and res
|
||||
if (app) {
|
||||
app.route = route;
|
||||
middleware = function(req, res, next) {
|
||||
var orig = req.app;
|
||||
app.handle(req, res, function(err){
|
||||
req.app = res.app = orig;
|
||||
next(err);
|
||||
});
|
||||
};
|
||||
}
|
||||
// restore .app property on req and res
|
||||
if ( app ) {
|
||||
app.route = route;
|
||||
middleware = function ( req, res, next ) {
|
||||
var orig = req.app;
|
||||
app.handle( req, res, function ( err ) {
|
||||
req.app = res.app = orig;
|
||||
next( err );
|
||||
} );
|
||||
};
|
||||
}
|
||||
|
||||
connect.HTTPServer.prototype.use.call(this, route, middleware);
|
||||
connect.HTTPServer.prototype.use.call( this, route, middleware );
|
||||
|
||||
// mounted an app, invoke the hook
|
||||
// and adjust some settings
|
||||
if (app) {
|
||||
base = this.set('basepath') || this.route;
|
||||
if ('/' == base) base = '';
|
||||
base = base + (app.set('basepath') || app.route);
|
||||
app.set('basepath', base);
|
||||
app.parent = this;
|
||||
if (app.__mounted) app.__mounted.call(app, this);
|
||||
}
|
||||
// mounted an app, invoke the hook
|
||||
// and adjust some settings
|
||||
if ( app ) {
|
||||
base = this.set( 'basepath' ) || this.route;
|
||||
if ( '/' == base ) {
|
||||
base = '';
|
||||
}
|
||||
base = base + (app.set( 'basepath' ) || app.route);
|
||||
app.set( 'basepath', base );
|
||||
app.parent = this;
|
||||
if ( app.__mounted ) {
|
||||
app.__mounted.call( app, this );
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -264,9 +272,9 @@ app.use = function(route, middleware){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.mounted = function(fn){
|
||||
this.__mounted = fn;
|
||||
return this;
|
||||
app.mounted = function ( fn ) {
|
||||
this.__mounted = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -276,9 +284,9 @@ app.mounted = function(fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.register = function(){
|
||||
view.register.apply(this, arguments);
|
||||
return this;
|
||||
app.register = function () {
|
||||
view.register.apply( this, arguments );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -291,9 +299,9 @@ app.register = function(){
|
|||
*/
|
||||
|
||||
app.helpers =
|
||||
app.locals = function(obj){
|
||||
utils.merge(this._locals, obj);
|
||||
return this;
|
||||
app.locals = function ( obj ) {
|
||||
utils.merge( this._locals, obj );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -305,9 +313,9 @@ app.locals = function(obj){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.dynamicHelpers = function(obj){
|
||||
utils.merge(this.dynamicViewHelpers, obj);
|
||||
return this;
|
||||
app.dynamicHelpers = function ( obj ) {
|
||||
utils.merge( this.dynamicViewHelpers, obj );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -369,29 +377,31 @@ app.dynamicHelpers = function(obj){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.param = function(name, fn){
|
||||
var self = this
|
||||
, fns = [].slice.call(arguments, 1);
|
||||
app.param = function ( name, fn ) {
|
||||
var self = this
|
||||
, fns = [].slice.call( arguments, 1 );
|
||||
|
||||
// array
|
||||
if (Array.isArray(name)) {
|
||||
name.forEach(function(name){
|
||||
fns.forEach(function(fn){
|
||||
self.param(name, fn);
|
||||
});
|
||||
});
|
||||
// param logic
|
||||
} else if ('function' == typeof name) {
|
||||
this.routes.param(name);
|
||||
// single
|
||||
} else {
|
||||
if (':' == name[0]) name = name.substr(1);
|
||||
fns.forEach(function(fn){
|
||||
self.routes.param(name, fn);
|
||||
});
|
||||
}
|
||||
// array
|
||||
if ( Array.isArray( name ) ) {
|
||||
name.forEach( function ( name ) {
|
||||
fns.forEach( function ( fn ) {
|
||||
self.param( name, fn );
|
||||
} );
|
||||
} );
|
||||
// param logic
|
||||
} else if ( 'function' == typeof name ) {
|
||||
this.routes.param( name );
|
||||
// single
|
||||
} else {
|
||||
if ( ':' == name[0] ) {
|
||||
name = name.substr( 1 );
|
||||
}
|
||||
fns.forEach( function ( fn ) {
|
||||
self.routes.param( name, fn );
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -403,9 +413,9 @@ app.param = function(name, fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.error = function(fn){
|
||||
this.errorHandlers.push(fn);
|
||||
return this;
|
||||
app.error = function ( fn ) {
|
||||
this.errorHandlers.push( fn );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -417,10 +427,12 @@ app.error = function(fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.is = function(type, fn){
|
||||
if (!fn) return this.isCallbacks[type];
|
||||
this.isCallbacks[type] = fn;
|
||||
return this;
|
||||
app.is = function ( type, fn ) {
|
||||
if ( !fn ) {
|
||||
return this.isCallbacks[type];
|
||||
}
|
||||
this.isCallbacks[type] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -433,17 +445,17 @@ app.is = function(type, fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.set = function(setting, val){
|
||||
if (val === undefined) {
|
||||
if (this.settings.hasOwnProperty(setting)) {
|
||||
return this.settings[setting];
|
||||
} else if (this.parent) {
|
||||
return this.parent.set(setting);
|
||||
}
|
||||
} else {
|
||||
this.settings[setting] = val;
|
||||
return this;
|
||||
}
|
||||
app.set = function ( setting, val ) {
|
||||
if ( val === undefined ) {
|
||||
if ( this.settings.hasOwnProperty( setting ) ) {
|
||||
return this.settings[setting];
|
||||
} else if ( this.parent ) {
|
||||
return this.parent.set( setting );
|
||||
}
|
||||
} else {
|
||||
this.settings[setting] = val;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -454,8 +466,8 @@ app.set = function(setting, val){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.enabled = function(setting){
|
||||
return !!this.set(setting);
|
||||
app.enabled = function ( setting ) {
|
||||
return !!this.set( setting );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -466,8 +478,8 @@ app.enabled = function(setting){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.disabled = function(setting){
|
||||
return !this.set(setting);
|
||||
app.disabled = function ( setting ) {
|
||||
return !this.set( setting );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -478,8 +490,8 @@ app.disabled = function(setting){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.enable = function(setting){
|
||||
return this.set(setting, true);
|
||||
app.enable = function ( setting ) {
|
||||
return this.set( setting, true );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -490,8 +502,8 @@ app.enable = function(setting){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.disable = function(setting){
|
||||
return this.set(setting, false);
|
||||
app.disable = function ( setting ) {
|
||||
return this.set( setting, false );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -503,9 +515,9 @@ app.disable = function(setting){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.redirect = function(key, url){
|
||||
this.redirects[key] = url;
|
||||
return this;
|
||||
app.redirect = function ( key, url ) {
|
||||
this.redirects[key] = url;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -534,27 +546,35 @@ app.redirect = function(key, url){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.configure = function(env, fn){
|
||||
var envs = 'all'
|
||||
, args = toArray(arguments);
|
||||
fn = args.pop();
|
||||
if (args.length) envs = args;
|
||||
if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this);
|
||||
return this;
|
||||
app.configure = function ( env, fn ) {
|
||||
var envs = 'all'
|
||||
, args = toArray( arguments );
|
||||
fn = args.pop();
|
||||
if ( args.length ) {
|
||||
envs = args;
|
||||
}
|
||||
if ( 'all' == envs || ~envs.indexOf( this.settings.env ) ) {
|
||||
fn.call( this );
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delegate `.VERB(...)` calls to `.route(VERB, ...)`.
|
||||
*/
|
||||
|
||||
methods.forEach(function(method){
|
||||
app[method] = function(path){
|
||||
if (1 == arguments.length) return this.routes.lookup(method, path);
|
||||
var args = [method].concat(toArray(arguments));
|
||||
if (!this.__usedRouter) this.use(this.router);
|
||||
return this.routes._route.apply(this.routes, args);
|
||||
}
|
||||
});
|
||||
methods.forEach( function ( method ) {
|
||||
app[method] = function ( path ) {
|
||||
if ( 1 == arguments.length ) {
|
||||
return this.routes.lookup( method, path );
|
||||
}
|
||||
var args = [method].concat( toArray( arguments ) );
|
||||
if ( !this.__usedRouter ) {
|
||||
this.use( this.router );
|
||||
}
|
||||
return this.routes._route.apply( this.routes, args );
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Special-cased "all" method, applying the given route `path`,
|
||||
|
|
@ -566,14 +586,18 @@ methods.forEach(function(method){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
app.all = function(path){
|
||||
var args = arguments;
|
||||
if (1 == args.length) return this.routes.lookup('all', path);
|
||||
methods.forEach(function(method){
|
||||
if ('all' == method || 'del' == method) return;
|
||||
app[method].apply(this, args);
|
||||
}, this);
|
||||
return this;
|
||||
app.all = function ( path ) {
|
||||
var args = arguments;
|
||||
if ( 1 == args.length ) {
|
||||
return this.routes.lookup( 'all', path );
|
||||
}
|
||||
methods.forEach( function ( method ) {
|
||||
if ( 'all' == method || 'del' == method ) {
|
||||
return;
|
||||
}
|
||||
app[method].apply( this, args );
|
||||
}, this );
|
||||
return this;
|
||||
};
|
||||
|
||||
// del -> delete alias
|
||||
|
|
|
|||
24
example/node/node_modules/express/lib/https.js
generated
vendored
24
example/node/node_modules/express/lib/https.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - HTTPSServer
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,9 +8,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var connect = require('connect')
|
||||
, HTTPServer = require('./http')
|
||||
, https = require('https');
|
||||
var connect = require( 'connect' )
|
||||
, HTTPServer = require( './http' )
|
||||
, https = require( 'https' );
|
||||
|
||||
/**
|
||||
* Expose `HTTPSServer`.
|
||||
|
|
@ -26,7 +25,7 @@ exports = module.exports = HTTPSServer;
|
|||
var app = HTTPSServer.prototype;
|
||||
|
||||
/**
|
||||
* Initialize a new `HTTPSServer` with the
|
||||
* Initialize a new `HTTPSServer` with the
|
||||
* given `options`, and optional `middleware`.
|
||||
*
|
||||
* @param {Object} options
|
||||
|
|
@ -34,10 +33,11 @@ var app = HTTPSServer.prototype;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
function HTTPSServer(options, middleware){
|
||||
connect.HTTPSServer.call(this, options, []);
|
||||
this.init(middleware);
|
||||
};
|
||||
function HTTPSServer( options, middleware ) {
|
||||
connect.HTTPSServer.call( this, options, [] );
|
||||
this.init( middleware );
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Inherit from `connect.HTTPSServer`.
|
||||
|
|
@ -47,6 +47,6 @@ app.__proto__ = connect.HTTPSServer.prototype;
|
|||
|
||||
// mixin HTTPServer methods
|
||||
|
||||
Object.keys(HTTPServer.prototype).forEach(function(method){
|
||||
app[method] = HTTPServer.prototype[method];
|
||||
});
|
||||
Object.keys( HTTPServer.prototype ).forEach( function ( method ) {
|
||||
app[method] = HTTPServer.prototype[method];
|
||||
} );
|
||||
|
|
|
|||
249
example/node/node_modules/express/lib/request.js
generated
vendored
249
example/node/node_modules/express/lib/request.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - request
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,11 +8,11 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, req = http.IncomingMessage.prototype
|
||||
, utils = require('./utils')
|
||||
, parse = require('url').parse
|
||||
, mime = require('mime');
|
||||
var http = require( 'http' )
|
||||
, req = http.IncomingMessage.prototype
|
||||
, utils = require( './utils' )
|
||||
, parse = require( 'url' ).parse
|
||||
, mime = require( 'mime' );
|
||||
|
||||
/**
|
||||
* Default flash formatters.
|
||||
|
|
@ -22,9 +21,9 @@ var http = require('http')
|
|||
*/
|
||||
|
||||
var flashFormatters = exports.flashFormatters = {
|
||||
s: function(val){
|
||||
return String(val);
|
||||
}
|
||||
s : function ( val ) {
|
||||
return String( val );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -38,32 +37,32 @@ var flashFormatters = exports.flashFormatters = {
|
|||
*
|
||||
* req.header('Content-Type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
*
|
||||
* req.header('content-type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
*
|
||||
* req.header('Accept');
|
||||
* // => undefined
|
||||
*
|
||||
*
|
||||
* req.header('Accept', 'text/html');
|
||||
* // => "text/html"
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String} defaultValue
|
||||
* @return {String}
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.header = function(name, defaultValue){
|
||||
switch (name = name.toLowerCase()) {
|
||||
case 'referer':
|
||||
case 'referrer':
|
||||
return this.headers.referrer
|
||||
|| this.headers.referer
|
||||
|| defaultValue;
|
||||
default:
|
||||
return this.headers[name] || defaultValue;
|
||||
}
|
||||
req.header = function ( name, defaultValue ) {
|
||||
switch ( name = name.toLowerCase() ) {
|
||||
case 'referer':
|
||||
case 'referrer':
|
||||
return this.headers.referrer
|
||||
|| this.headers.referer
|
||||
|| defaultValue;
|
||||
default:
|
||||
return this.headers[name] || defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -80,12 +79,16 @@ req.header = function(name, defaultValue){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.get = function(field, param){
|
||||
var val = this.header(field);
|
||||
if (!val) return '';
|
||||
var regexp = new RegExp(param + ' *= *(?:"([^"]+)"|([^;]+))', 'i');
|
||||
if (!regexp.exec(val)) return '';
|
||||
return RegExp.$1 || RegExp.$2;
|
||||
req.get = function ( field, param ) {
|
||||
var val = this.header( field );
|
||||
if ( !val ) {
|
||||
return '';
|
||||
}
|
||||
var regexp = new RegExp( param + ' *= *(?:"([^"]+)"|([^;]+))', 'i' );
|
||||
if ( !regexp.exec( val ) ) {
|
||||
return '';
|
||||
}
|
||||
return RegExp.$1 || RegExp.$2;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -95,9 +98,9 @@ req.get = function(field, param){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('path', function(){
|
||||
return parse(this.url).pathname;
|
||||
});
|
||||
req.__defineGetter__( 'path', function () {
|
||||
return parse( this.url ).pathname;
|
||||
} );
|
||||
|
||||
/**
|
||||
* Check if the _Accept_ header is present, and includes the given `type`.
|
||||
|
|
@ -108,7 +111,7 @@ req.__defineGetter__('path', function(){
|
|||
* to "text/html" using the mime lookup table.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
*
|
||||
* // Accept: text/html
|
||||
* req.accepts('html');
|
||||
* // => true
|
||||
|
|
@ -129,28 +132,34 @@ req.__defineGetter__('path', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.accepts = function(type){
|
||||
var accept = this.header('Accept');
|
||||
req.accepts = function ( type ) {
|
||||
var accept = this.header( 'Accept' );
|
||||
|
||||
// normalize extensions ".json" -> "json"
|
||||
if (type && '.' == type[0]) type = type.substr(1);
|
||||
// normalize extensions ".json" -> "json"
|
||||
if ( type && '.' == type[0] ) {
|
||||
type = type.substr( 1 );
|
||||
}
|
||||
|
||||
// when Accept does not exist, or is '*/*' return true
|
||||
if (!accept || '*/*' == accept) {
|
||||
return true;
|
||||
} else if (type) {
|
||||
// allow "html" vs "text/html" etc
|
||||
if (!~type.indexOf('/')) type = mime.lookup(type);
|
||||
// when Accept does not exist, or is '*/*' return true
|
||||
if ( !accept || '*/*' == accept ) {
|
||||
return true;
|
||||
} else if ( type ) {
|
||||
// allow "html" vs "text/html" etc
|
||||
if ( !~type.indexOf( '/' ) ) {
|
||||
type = mime.lookup( type );
|
||||
}
|
||||
|
||||
// check if we have a direct match
|
||||
if (~accept.indexOf(type)) return true;
|
||||
// check if we have a direct match
|
||||
if ( ~accept.indexOf( type ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if we have type/*
|
||||
type = type.split('/')[0] + '/*';
|
||||
return !!~accept.indexOf(type);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// check if we have type/*
|
||||
type = type.split( '/' )[0] + '/*';
|
||||
return !!~accept.indexOf( type );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -170,20 +179,20 @@ req.accepts = function(type){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.param = function(name, defaultValue){
|
||||
// route params like /user/:id
|
||||
if (this.params && this.params.hasOwnProperty(name) && undefined !== this.params[name]) {
|
||||
return this.params[name];
|
||||
}
|
||||
// query string params
|
||||
if (undefined !== this.query[name]) {
|
||||
return this.query[name];
|
||||
}
|
||||
// request body params via connect.bodyParser
|
||||
if (this.body && undefined !== this.body[name]) {
|
||||
return this.body[name];
|
||||
}
|
||||
return defaultValue;
|
||||
req.param = function ( name, defaultValue ) {
|
||||
// route params like /user/:id
|
||||
if ( this.params && this.params.hasOwnProperty( name ) && undefined !== this.params[name] ) {
|
||||
return this.params[name];
|
||||
}
|
||||
// query string params
|
||||
if ( undefined !== this.query[name] ) {
|
||||
return this.query[name];
|
||||
}
|
||||
// request body params via connect.bodyParser
|
||||
if ( this.body && undefined !== this.body[name] ) {
|
||||
return this.body[name];
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -221,32 +230,36 @@ req.param = function(name, defaultValue){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.flash = function(type, msg){
|
||||
if (this.session === undefined) throw Error('req.flash() requires sessions');
|
||||
var msgs = this.session.flash = this.session.flash || {};
|
||||
if (type && msg) {
|
||||
var i = 2
|
||||
, args = arguments
|
||||
, formatters = this.app.flashFormatters || {};
|
||||
formatters.__proto__ = flashFormatters;
|
||||
msg = utils.miniMarkdown(msg);
|
||||
msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
|
||||
var formatter = formatters[format];
|
||||
if (formatter) return formatter(utils.escape(args[i++]));
|
||||
});
|
||||
return (msgs[type] = msgs[type] || []).push(msg);
|
||||
} else if (type) {
|
||||
var arr = msgs[type];
|
||||
delete msgs[type];
|
||||
return arr || [];
|
||||
} else {
|
||||
this.session.flash = {};
|
||||
return msgs;
|
||||
}
|
||||
req.flash = function ( type, msg ) {
|
||||
if ( this.session === undefined ) {
|
||||
throw Error( 'req.flash() requires sessions' );
|
||||
}
|
||||
var msgs = this.session.flash = this.session.flash || {};
|
||||
if ( type && msg ) {
|
||||
var i = 2
|
||||
, args = arguments
|
||||
, formatters = this.app.flashFormatters || {};
|
||||
formatters.__proto__ = flashFormatters;
|
||||
msg = utils.miniMarkdown( msg );
|
||||
msg = msg.replace( /%([a-zA-Z])/g, function ( _, format ) {
|
||||
var formatter = formatters[format];
|
||||
if ( formatter ) {
|
||||
return formatter( utils.escape( args[i++] ) );
|
||||
}
|
||||
} );
|
||||
return (msgs[type] = msgs[type] || []).push( msg );
|
||||
} else if ( type ) {
|
||||
var arr = msgs[type];
|
||||
delete msgs[type];
|
||||
return arr || [];
|
||||
} else {
|
||||
this.session.flash = {};
|
||||
return msgs;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the incoming request contains the "Content-Type"
|
||||
* Check if the incoming request contains the "Content-Type"
|
||||
* header field, and it contains the give mime `type`.
|
||||
*
|
||||
* Examples:
|
||||
|
|
@ -255,27 +268,27 @@ req.flash = function(type, msg){
|
|||
* req.is('html');
|
||||
* req.is('text/html');
|
||||
* // => true
|
||||
*
|
||||
*
|
||||
* // When Content-Type is application/json
|
||||
* req.is('json');
|
||||
* req.is('application/json');
|
||||
* // => true
|
||||
*
|
||||
*
|
||||
* req.is('html');
|
||||
* // => false
|
||||
*
|
||||
*
|
||||
* Ad-hoc callbacks can also be registered with Express, to perform
|
||||
* assertions again the request, for example if we need an expressive
|
||||
* way to check if our incoming request is an image, we can register "an image"
|
||||
* callback:
|
||||
*
|
||||
*
|
||||
* app.is('an image', function(req){
|
||||
* return 0 == req.headers['content-type'].indexOf('image');
|
||||
* });
|
||||
*
|
||||
*
|
||||
* Now within our route callbacks, we can use to to assert content types
|
||||
* such as "image/jpeg", "image/png", etc.
|
||||
*
|
||||
*
|
||||
* app.post('/image/upload', function(req, res, next){
|
||||
* if (req.is('an image')) {
|
||||
* // do something
|
||||
|
|
@ -283,33 +296,43 @@ req.flash = function(type, msg){
|
|||
* next();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.is = function(type){
|
||||
var fn = this.app.is(type);
|
||||
if (fn) return fn(this);
|
||||
var ct = this.headers['content-type'];
|
||||
if (!ct) return false;
|
||||
ct = ct.split(';')[0];
|
||||
if (!~type.indexOf('/')) type = mime.lookup(type);
|
||||
if (~type.indexOf('*')) {
|
||||
type = type.split('/');
|
||||
ct = ct.split('/');
|
||||
if ('*' == type[0] && type[1] == ct[1]) return true;
|
||||
if ('*' == type[1] && type[0] == ct[0]) return true;
|
||||
return false;
|
||||
}
|
||||
return !! ~ct.indexOf(type);
|
||||
req.is = function ( type ) {
|
||||
var fn = this.app.is( type );
|
||||
if ( fn ) {
|
||||
return fn( this );
|
||||
}
|
||||
var ct = this.headers['content-type'];
|
||||
if ( !ct ) {
|
||||
return false;
|
||||
}
|
||||
ct = ct.split( ';' )[0];
|
||||
if ( !~type.indexOf( '/' ) ) {
|
||||
type = mime.lookup( type );
|
||||
}
|
||||
if ( ~type.indexOf( '*' ) ) {
|
||||
type = type.split( '/' );
|
||||
ct = ct.split( '/' );
|
||||
if ( '*' == type[0] && type[1] == ct[1] ) {
|
||||
return true;
|
||||
}
|
||||
if ( '*' == type[1] && type[0] == ct[0] ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return !!~ct.indexOf( type );
|
||||
};
|
||||
|
||||
// Callback for isXMLHttpRequest / xhr
|
||||
|
||||
function isxhr() {
|
||||
return this.header('X-Requested-With', '').toLowerCase() === 'xmlhttprequest';
|
||||
return this.header( 'X-Requested-With', '' ).toLowerCase() === 'xmlhttprequest';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -319,5 +342,5 @@ function isxhr() {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('isXMLHttpRequest', isxhr);
|
||||
req.__defineGetter__('xhr', isxhr);
|
||||
req.__defineGetter__( 'isXMLHttpRequest', isxhr );
|
||||
req.__defineGetter__( 'xhr', isxhr );
|
||||
|
|
|
|||
416
example/node/node_modules/express/lib/response.js
generated
vendored
416
example/node/node_modules/express/lib/response.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - response
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,17 +8,17 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, http = require('http')
|
||||
, path = require('path')
|
||||
, connect = require('connect')
|
||||
, utils = connect.utils
|
||||
, parseRange = require('./utils').parseRange
|
||||
, res = http.ServerResponse.prototype
|
||||
, send = connect.static.send
|
||||
, mime = require('mime')
|
||||
, basename = path.basename
|
||||
, join = path.join;
|
||||
var fs = require( 'fs' )
|
||||
, http = require( 'http' )
|
||||
, path = require( 'path' )
|
||||
, connect = require( 'connect' )
|
||||
, utils = connect.utils
|
||||
, parseRange = require( './utils' ).parseRange
|
||||
, res = http.ServerResponse.prototype
|
||||
, send = connect.static.send
|
||||
, mime = require( 'mime' )
|
||||
, basename = path.basename
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
* Send a response with the given `body` and optional `headers` and `status` code.
|
||||
|
|
@ -41,72 +40,74 @@ var fs = require('fs')
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.send = function(body, headers, status){
|
||||
// allow status as second arg
|
||||
if ('number' == typeof headers) {
|
||||
status = headers,
|
||||
headers = null;
|
||||
}
|
||||
res.send = function ( body, headers, status ) {
|
||||
// allow status as second arg
|
||||
if ( 'number' == typeof headers ) {
|
||||
status = headers,
|
||||
headers = null;
|
||||
}
|
||||
|
||||
// default status
|
||||
status = status || this.statusCode;
|
||||
// default status
|
||||
status = status || this.statusCode;
|
||||
|
||||
// allow 0 args as 204
|
||||
if (!arguments.length || undefined === body) status = 204;
|
||||
// allow 0 args as 204
|
||||
if ( !arguments.length || undefined === body ) {
|
||||
status = 204;
|
||||
}
|
||||
|
||||
// determine content type
|
||||
switch (typeof body) {
|
||||
case 'number':
|
||||
if (!this.header('Content-Type')) {
|
||||
this.contentType('.txt');
|
||||
}
|
||||
body = http.STATUS_CODES[status = body];
|
||||
break;
|
||||
case 'string':
|
||||
if (!this.header('Content-Type')) {
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.contentType('.html');
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'object':
|
||||
if (Buffer.isBuffer(body)) {
|
||||
if (!this.header('Content-Type')) {
|
||||
this.contentType('.bin');
|
||||
}
|
||||
} else {
|
||||
return this.json(body, headers, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// determine content type
|
||||
switch ( typeof body ) {
|
||||
case 'number':
|
||||
if ( !this.header( 'Content-Type' ) ) {
|
||||
this.contentType( '.txt' );
|
||||
}
|
||||
body = http.STATUS_CODES[status = body];
|
||||
break;
|
||||
case 'string':
|
||||
if ( !this.header( 'Content-Type' ) ) {
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.contentType( '.html' );
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'object':
|
||||
if ( Buffer.isBuffer( body ) ) {
|
||||
if ( !this.header( 'Content-Type' ) ) {
|
||||
this.contentType( '.bin' );
|
||||
}
|
||||
} else {
|
||||
return this.json( body, headers, status );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// populate Content-Length
|
||||
if (undefined !== body && !this.header('Content-Length')) {
|
||||
this.header('Content-Length', Buffer.isBuffer(body)
|
||||
? body.length
|
||||
: Buffer.byteLength(body));
|
||||
}
|
||||
// populate Content-Length
|
||||
if ( undefined !== body && !this.header( 'Content-Length' ) ) {
|
||||
this.header( 'Content-Length', Buffer.isBuffer( body )
|
||||
? body.length
|
||||
: Buffer.byteLength( body ) );
|
||||
}
|
||||
|
||||
// merge headers passed
|
||||
if (headers) {
|
||||
var fields = Object.keys(headers);
|
||||
for (var i = 0, len = fields.length; i < len; ++i) {
|
||||
var field = fields[i];
|
||||
this.header(field, headers[field]);
|
||||
}
|
||||
}
|
||||
// merge headers passed
|
||||
if ( headers ) {
|
||||
var fields = Object.keys( headers );
|
||||
for ( var i = 0, len = fields.length; i < len; ++i ) {
|
||||
var field = fields[i];
|
||||
this.header( field, headers[field] );
|
||||
}
|
||||
}
|
||||
|
||||
// strip irrelevant headers
|
||||
if (204 == status || 304 == status) {
|
||||
this.removeHeader('Content-Type');
|
||||
this.removeHeader('Content-Length');
|
||||
body = '';
|
||||
}
|
||||
// strip irrelevant headers
|
||||
if ( 204 == status || 304 == status ) {
|
||||
this.removeHeader( 'Content-Type' );
|
||||
this.removeHeader( 'Content-Length' );
|
||||
body = '';
|
||||
}
|
||||
|
||||
// respond
|
||||
this.statusCode = status;
|
||||
this.end('HEAD' == this.req.method ? null : body);
|
||||
return this;
|
||||
// respond
|
||||
this.statusCode = status;
|
||||
this.end( 'HEAD' == this.req.method ? null : body );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -126,20 +127,20 @@ res.send = function(body, headers, status){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.json = function(obj, headers, status){
|
||||
var body = JSON.stringify(obj)
|
||||
, callback = this.req.query.callback
|
||||
, jsonp = this.app.enabled('jsonp callback');
|
||||
res.json = function ( obj, headers, status ) {
|
||||
var body = JSON.stringify( obj )
|
||||
, callback = this.req.query.callback
|
||||
, jsonp = this.app.enabled( 'jsonp callback' );
|
||||
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.header('Content-Type', 'application/json');
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.header( 'Content-Type', 'application/json' );
|
||||
|
||||
if (callback && jsonp) {
|
||||
this.header('Content-Type', 'text/javascript');
|
||||
body = callback.replace(/[^\w$.]/g, '') + '(' + body + ');';
|
||||
}
|
||||
if ( callback && jsonp ) {
|
||||
this.header( 'Content-Type', 'text/javascript' );
|
||||
body = callback.replace( /[^\w$.]/g, '' ) + '(' + body + ');';
|
||||
}
|
||||
|
||||
return this.send(body, headers, status);
|
||||
return this.send( body, headers, status );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -150,13 +151,13 @@ res.json = function(obj, headers, status){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.status = function(code){
|
||||
this.statusCode = code;
|
||||
return this;
|
||||
res.status = function ( code ) {
|
||||
this.statusCode = code;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfer the file at the given `path`. Automatically sets
|
||||
* Transfer the file at the given `path`. Automatically sets
|
||||
* the _Content-Type_ response header field. `next()` is called
|
||||
* when `path` is a directory, or when an error occurs.
|
||||
*
|
||||
|
|
@ -171,19 +172,19 @@ res.status = function(code){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.sendfile = function(path, options, fn){
|
||||
var next = this.req.next;
|
||||
options = options || {};
|
||||
res.sendfile = function ( path, options, fn ) {
|
||||
var next = this.req.next;
|
||||
options = options || {};
|
||||
|
||||
// support function as second arg
|
||||
if ('function' == typeof options) {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
// support function as second arg
|
||||
if ( 'function' == typeof options ) {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
options.path = encodeURIComponent(path);
|
||||
options.callback = fn;
|
||||
send(this.req, this, next, options);
|
||||
options.path = encodeURIComponent( path );
|
||||
options.callback = fn;
|
||||
send( this.req, this, next, options );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -205,8 +206,8 @@ res.sendfile = function(path, options, fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.contentType = function(type){
|
||||
return this.header('Content-Type', mime.lookup(type));
|
||||
res.contentType = function ( type ) {
|
||||
return this.header( 'Content-Type', mime.lookup( type ) );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -217,16 +218,18 @@ res.contentType = function(type){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.attachment = function(filename){
|
||||
if (filename) this.contentType(filename);
|
||||
this.header('Content-Disposition', filename
|
||||
? 'attachment; filename="' + basename(filename) + '"'
|
||||
: 'attachment');
|
||||
return this;
|
||||
res.attachment = function ( filename ) {
|
||||
if ( filename ) {
|
||||
this.contentType( filename );
|
||||
}
|
||||
this.header( 'Content-Disposition', filename
|
||||
? 'attachment; filename="' + basename( filename ) + '"'
|
||||
: 'attachment' );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfer the file at the given `path`, with optional
|
||||
* Transfer the file at the given `path`, with optional
|
||||
* `filename` as an attachment and optional callback `fn(err)`,
|
||||
* and optional `fn2(err)` which is invoked when an error has
|
||||
* occurred after header has been sent.
|
||||
|
|
@ -238,32 +241,34 @@ res.attachment = function(filename){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.download = function(path, filename, fn, fn2){
|
||||
var self = this;
|
||||
res.download = function ( path, filename, fn, fn2 ) {
|
||||
var self = this;
|
||||
|
||||
// support callback as second arg
|
||||
if ('function' == typeof filename) {
|
||||
fn2 = fn;
|
||||
fn = filename;
|
||||
filename = null;
|
||||
}
|
||||
// support callback as second arg
|
||||
if ( 'function' == typeof filename ) {
|
||||
fn2 = fn;
|
||||
fn = filename;
|
||||
filename = null;
|
||||
}
|
||||
|
||||
// transfer the file
|
||||
this.attachment(filename || path).sendfile(path, function(err){
|
||||
var sentHeader = self._header;
|
||||
if (err) {
|
||||
if (!sentHeader) self.removeHeader('Content-Disposition');
|
||||
if (sentHeader) {
|
||||
fn2 && fn2(err);
|
||||
} else if (fn) {
|
||||
fn(err);
|
||||
} else {
|
||||
self.req.next(err);
|
||||
}
|
||||
} else if (fn) {
|
||||
fn();
|
||||
}
|
||||
});
|
||||
// transfer the file
|
||||
this.attachment( filename || path ).sendfile( path, function ( err ) {
|
||||
var sentHeader = self._header;
|
||||
if ( err ) {
|
||||
if ( !sentHeader ) {
|
||||
self.removeHeader( 'Content-Disposition' );
|
||||
}
|
||||
if ( sentHeader ) {
|
||||
fn2 && fn2( err );
|
||||
} else if ( fn ) {
|
||||
fn( err );
|
||||
} else {
|
||||
self.req.next( err );
|
||||
}
|
||||
} else if ( fn ) {
|
||||
fn();
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -275,10 +280,12 @@ res.download = function(path, filename, fn, fn2){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.header = function(name, val){
|
||||
if (1 == arguments.length) return this.getHeader(name);
|
||||
this.setHeader(name, val);
|
||||
return this;
|
||||
res.header = function ( name, val ) {
|
||||
if ( 1 == arguments.length ) {
|
||||
return this.getHeader( name );
|
||||
}
|
||||
this.setHeader( name, val );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -289,11 +296,11 @@ res.header = function(name, val){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.clearCookie = function(name, options){
|
||||
var opts = { expires: new Date(1) };
|
||||
this.cookie(name, '', options
|
||||
? utils.merge(options, opts)
|
||||
: opts);
|
||||
res.clearCookie = function ( name, options ) {
|
||||
var opts = { expires : new Date( 1 ) };
|
||||
this.cookie( name, '', options
|
||||
? utils.merge( options, opts )
|
||||
: opts );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -318,12 +325,16 @@ res.clearCookie = function(name, options){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.cookie = function(name, val, options){
|
||||
options = options || {};
|
||||
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
|
||||
if (undefined === options.path) options.path = this.app.set('basepath');
|
||||
var cookie = utils.serializeCookie(name, val, options);
|
||||
this.header('Set-Cookie', cookie);
|
||||
res.cookie = function ( name, val, options ) {
|
||||
options = options || {};
|
||||
if ( 'maxAge' in options ) {
|
||||
options.expires = new Date( Date.now() + options.maxAge );
|
||||
}
|
||||
if ( undefined === options.path ) {
|
||||
options.path = this.app.set( 'basepath' );
|
||||
}
|
||||
var cookie = utils.serializeCookie( name, val, options );
|
||||
this.header( 'Set-Cookie', cookie );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -338,12 +349,12 @@ res.cookie = function(name, val, options){
|
|||
* to '/'.
|
||||
*
|
||||
* Redirect Mapping:
|
||||
*
|
||||
*
|
||||
* To extend the redirect mapping capabilities that Express provides,
|
||||
* we may use the `app.redirect()` method:
|
||||
*
|
||||
*
|
||||
* app.redirect('google', 'http://google.com');
|
||||
*
|
||||
*
|
||||
* Now in a route we may call:
|
||||
*
|
||||
* res.redirect('google');
|
||||
|
|
@ -371,55 +382,56 @@ res.cookie = function(name, val, options){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.redirect = function(url, status){
|
||||
var app = this.app
|
||||
, req = this.req
|
||||
, base = app.set('basepath') || app.route
|
||||
, status = status || 302
|
||||
, head = 'HEAD' == req.method
|
||||
, body;
|
||||
res.redirect = function ( url, status ) {
|
||||
var app = this.app
|
||||
, req = this.req
|
||||
, base = app.set( 'basepath' ) || app.route
|
||||
, status = status || 302
|
||||
, head = 'HEAD' == req.method
|
||||
, body;
|
||||
|
||||
// Setup redirect map
|
||||
var map = {
|
||||
back: req.header('Referrer', base)
|
||||
, home: base
|
||||
};
|
||||
// Setup redirect map
|
||||
var map = {
|
||||
back : req.header( 'Referrer', base ), home : base
|
||||
};
|
||||
|
||||
// Support custom redirect map
|
||||
map.__proto__ = app.redirects;
|
||||
// Support custom redirect map
|
||||
map.__proto__ = app.redirects;
|
||||
|
||||
// Attempt mapped redirect
|
||||
var mapped = 'function' == typeof map[url]
|
||||
? map[url](req, this)
|
||||
: map[url];
|
||||
// Attempt mapped redirect
|
||||
var mapped = 'function' == typeof map[url]
|
||||
? map[url]( req, this )
|
||||
: map[url];
|
||||
|
||||
// Perform redirect
|
||||
url = mapped || url;
|
||||
// Perform redirect
|
||||
url = mapped || url;
|
||||
|
||||
// Relative
|
||||
if (!~url.indexOf('://')) {
|
||||
// Respect mount-point
|
||||
if ('/' != base && 0 != url.indexOf(base)) url = base + url;
|
||||
// Relative
|
||||
if ( !~url.indexOf( '://' ) ) {
|
||||
// Respect mount-point
|
||||
if ( '/' != base && 0 != url.indexOf( base ) ) {
|
||||
url = base + url;
|
||||
}
|
||||
|
||||
// Absolute
|
||||
var host = req.headers.host
|
||||
, tls = req.connection.encrypted;
|
||||
url = 'http' + (tls ? 's' : '') + '://' + host + url;
|
||||
}
|
||||
// Absolute
|
||||
var host = req.headers.host
|
||||
, tls = req.connection.encrypted;
|
||||
url = 'http' + (tls ? 's' : '') + '://' + host + url;
|
||||
}
|
||||
|
||||
// Support text/{plain,html} by default
|
||||
if (req.accepts('html')) {
|
||||
body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
|
||||
this.header('Content-Type', 'text/html');
|
||||
} else {
|
||||
body = http.STATUS_CODES[status] + '. Redirecting to ' + url;
|
||||
this.header('Content-Type', 'text/plain');
|
||||
}
|
||||
// Support text/{plain,html} by default
|
||||
if ( req.accepts( 'html' ) ) {
|
||||
body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
|
||||
this.header( 'Content-Type', 'text/html' );
|
||||
} else {
|
||||
body = http.STATUS_CODES[status] + '. Redirecting to ' + url;
|
||||
this.header( 'Content-Type', 'text/plain' );
|
||||
}
|
||||
|
||||
// Respond
|
||||
this.statusCode = status;
|
||||
this.header('Location', url);
|
||||
this.end(head ? null : body);
|
||||
// Respond
|
||||
this.statusCode = status;
|
||||
this.header( 'Location', url );
|
||||
this.end( head ? null : body );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -432,11 +444,11 @@ res.redirect = function(url, status){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.local = function(name, val){
|
||||
this._locals = this._locals || {};
|
||||
return undefined === val
|
||||
? this._locals[name]
|
||||
: this._locals[name] = val;
|
||||
res.local = function ( name, val ) {
|
||||
this._locals = this._locals || {};
|
||||
return undefined === val
|
||||
? this._locals[name]
|
||||
: this._locals[name] = val;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -449,12 +461,12 @@ res.local = function(name, val){
|
|||
*/
|
||||
|
||||
res.locals =
|
||||
res.helpers = function(obj){
|
||||
if (obj) {
|
||||
for (var key in obj) {
|
||||
this.local(key, obj[key]);
|
||||
}
|
||||
} else {
|
||||
return this._locals;
|
||||
}
|
||||
res.helpers = function ( obj ) {
|
||||
if ( obj ) {
|
||||
for ( var key in obj ) {
|
||||
this.local( key, obj[key] );
|
||||
}
|
||||
} else {
|
||||
return this._locals;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
29
example/node/node_modules/express/lib/router/collection.js
generated
vendored
29
example/node/node_modules/express/lib/router/collection.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - router - Collection
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -14,14 +13,14 @@ module.exports = Collection;
|
|||
/**
|
||||
* Initialize a new route `Collection`
|
||||
* with the given `router`.
|
||||
*
|
||||
*
|
||||
* @param {Router} router
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Collection(router) {
|
||||
Array.apply(this, arguments);
|
||||
this.router = router;
|
||||
function Collection( router ) {
|
||||
Array.apply( this, arguments );
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,17 +36,17 @@ Collection.prototype.__proto__ = Array.prototype;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Collection.prototype.remove = function(){
|
||||
var router = this.router
|
||||
, len = this.length
|
||||
, ret = new Collection(this.router);
|
||||
Collection.prototype.remove = function () {
|
||||
var router = this.router
|
||||
, len = this.length
|
||||
, ret = new Collection( this.router );
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (router.remove(this[i])) {
|
||||
ret.push(this[i]);
|
||||
}
|
||||
}
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
if ( router.remove( this[i] ) ) {
|
||||
ret.push( this[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
|
|
|||
467
example/node/node_modules/express/lib/router/index.js
generated
vendored
467
example/node/node_modules/express/lib/router/index.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - Router
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,11 +8,11 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Route = require('./route')
|
||||
, Collection = require('./collection')
|
||||
, utils = require('../utils')
|
||||
, parse = require('url').parse
|
||||
, toArray = utils.toArray;
|
||||
var Route = require( './route' )
|
||||
, Collection = require( './collection' )
|
||||
, utils = require( '../utils' )
|
||||
, parse = require( 'url' ).parse
|
||||
, toArray = utils.toArray;
|
||||
|
||||
/**
|
||||
* Expose `Router` constructor.
|
||||
|
|
@ -25,25 +24,25 @@ exports = module.exports = Router;
|
|||
* Expose HTTP methods.
|
||||
*/
|
||||
|
||||
var methods = exports.methods = require('./methods');
|
||||
var methods = exports.methods = require( './methods' );
|
||||
|
||||
/**
|
||||
* Initialize a new `Router` with the given `app`.
|
||||
*
|
||||
*
|
||||
* @param {express.HTTPServer} app
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Router(app) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.routes = {};
|
||||
this.params = {};
|
||||
this._params = [];
|
||||
function Router( app ) {
|
||||
var self = this;
|
||||
this.app = app;
|
||||
this.routes = {};
|
||||
this.params = {};
|
||||
this._params = [];
|
||||
|
||||
this.middleware = function(req, res, next){
|
||||
self._dispatch(req, res, next);
|
||||
};
|
||||
this.middleware = function ( req, res, next ) {
|
||||
self._dispatch( req, res, next );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -55,32 +54,32 @@ function Router(app) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.param = function(name, fn){
|
||||
// param logic
|
||||
if ('function' == typeof name) {
|
||||
this._params.push(name);
|
||||
return;
|
||||
}
|
||||
Router.prototype.param = function ( name, fn ) {
|
||||
// param logic
|
||||
if ( 'function' == typeof name ) {
|
||||
this._params.push( name );
|
||||
return;
|
||||
}
|
||||
|
||||
// apply param functions
|
||||
var params = this._params
|
||||
, len = params.length
|
||||
, ret;
|
||||
// apply param functions
|
||||
var params = this._params
|
||||
, len = params.length
|
||||
, ret;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (ret = params[i](name, fn)) {
|
||||
fn = ret;
|
||||
}
|
||||
}
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
if ( ret = params[i]( name, fn ) ) {
|
||||
fn = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we end up with a
|
||||
// middleware function
|
||||
if ('function' != typeof fn) {
|
||||
throw new Error('invalid param() call for ' + name + ', got ' + fn);
|
||||
}
|
||||
// ensure we end up with a
|
||||
// middleware function
|
||||
if ( 'function' != typeof fn ) {
|
||||
throw new Error( 'invalid param() call for ' + name + ', got ' + fn );
|
||||
}
|
||||
|
||||
(this.params[name] = this.params[name] || []).push(fn);
|
||||
return this;
|
||||
(this.params[name] = this.params[name] || []).push( fn );
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -90,10 +89,10 @@ Router.prototype.param = function(name, fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.all = function(){
|
||||
return this.find(function(){
|
||||
return true;
|
||||
});
|
||||
Router.prototype.all = function () {
|
||||
return this.find( function () {
|
||||
return true;
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -106,16 +105,16 @@ Router.prototype.all = function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.remove = function(route){
|
||||
var routes = this.routes[route.method]
|
||||
, len = routes.length;
|
||||
Router.prototype.remove = function ( route ) {
|
||||
var routes = this.routes[route.method]
|
||||
, len = routes.length;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (route == routes[i]) {
|
||||
routes.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
if ( route == routes[i] ) {
|
||||
routes.splice( i, 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -127,12 +126,12 @@ Router.prototype.remove = function(route){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.lookup = function(method, path){
|
||||
return this.find(function(route){
|
||||
return path == route.path
|
||||
&& (route.method == method
|
||||
|| method == 'all');
|
||||
});
|
||||
Router.prototype.lookup = function ( method, path ) {
|
||||
return this.find( function ( route ) {
|
||||
return path == route.path
|
||||
&& (route.method == method
|
||||
|| method == 'all');
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -144,12 +143,12 @@ Router.prototype.lookup = function(method, path){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.match = function(method, url){
|
||||
return this.find(function(route){
|
||||
return route.match(url)
|
||||
&& (route.method == method
|
||||
|| method == 'all');
|
||||
});
|
||||
Router.prototype.match = function ( method, url ) {
|
||||
return this.find( function ( route ) {
|
||||
return route.match( url )
|
||||
&& (route.method == method
|
||||
|| method == 'all');
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -161,24 +160,28 @@ Router.prototype.match = function(method, url){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.find = function(fn){
|
||||
var len = methods.length
|
||||
, ret = new Collection(this)
|
||||
, method
|
||||
, routes
|
||||
, route;
|
||||
Router.prototype.find = function ( fn ) {
|
||||
var len = methods.length
|
||||
, ret = new Collection( this )
|
||||
, method
|
||||
, routes
|
||||
, route;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
method = methods[i];
|
||||
routes = this.routes[method];
|
||||
if (!routes) continue;
|
||||
for (var j = 0, jlen = routes.length; j < jlen; ++j) {
|
||||
route = routes[j];
|
||||
if (fn(route)) ret.push(route);
|
||||
}
|
||||
}
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
method = methods[i];
|
||||
routes = this.routes[method];
|
||||
if ( !routes ) {
|
||||
continue;
|
||||
}
|
||||
for ( var j = 0, jlen = routes.length; j < jlen; ++j ) {
|
||||
route = routes[j];
|
||||
if ( fn( route ) ) {
|
||||
ret.push( route );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -190,94 +193,104 @@ Router.prototype.find = function(fn){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._dispatch = function(req, res, next){
|
||||
var params = this.params
|
||||
, self = this;
|
||||
Router.prototype._dispatch = function ( req, res, next ) {
|
||||
var params = this.params
|
||||
, self = this;
|
||||
|
||||
// route dispatch
|
||||
(function pass(i, err){
|
||||
var paramCallbacks
|
||||
, paramIndex = 0
|
||||
, paramVal
|
||||
, route
|
||||
, keys
|
||||
, key
|
||||
, ret;
|
||||
// route dispatch
|
||||
(function pass( i, err ) {
|
||||
var paramCallbacks
|
||||
, paramIndex = 0
|
||||
, paramVal
|
||||
, route
|
||||
, keys
|
||||
, key
|
||||
, ret;
|
||||
|
||||
// match next route
|
||||
function nextRoute(err) {
|
||||
pass(req._route_index + 1, err);
|
||||
}
|
||||
// match next route
|
||||
function nextRoute( err ) {
|
||||
pass( req._route_index + 1, err );
|
||||
}
|
||||
|
||||
// match route
|
||||
req.route = route = self._match(req, i);
|
||||
// match route
|
||||
req.route = route = self._match( req, i );
|
||||
|
||||
// implied OPTIONS
|
||||
if (!route && 'OPTIONS' == req.method) return self._options(req, res);
|
||||
// implied OPTIONS
|
||||
if ( !route && 'OPTIONS' == req.method ) {
|
||||
return self._options( req, res );
|
||||
}
|
||||
|
||||
// no route
|
||||
if (!route) return next(err);
|
||||
// no route
|
||||
if ( !route ) {
|
||||
return next( err );
|
||||
}
|
||||
|
||||
// we have a route
|
||||
// start at param 0
|
||||
req.params = route.params;
|
||||
keys = route.keys;
|
||||
i = 0;
|
||||
// we have a route
|
||||
// start at param 0
|
||||
req.params = route.params;
|
||||
keys = route.keys;
|
||||
i = 0;
|
||||
|
||||
// param callbacks
|
||||
function param(err) {
|
||||
paramIndex = 0;
|
||||
key = keys[i++];
|
||||
paramVal = key && req.params[key.name];
|
||||
paramCallbacks = key && params[key.name];
|
||||
// param callbacks
|
||||
function param( err ) {
|
||||
paramIndex = 0;
|
||||
key = keys[i++];
|
||||
paramVal = key && req.params[key.name];
|
||||
paramCallbacks = key && params[key.name];
|
||||
|
||||
try {
|
||||
if ('route' == err) {
|
||||
nextRoute();
|
||||
} else if (err) {
|
||||
i = 0;
|
||||
callbacks(err);
|
||||
} else if (paramCallbacks && undefined !== paramVal) {
|
||||
paramCallback();
|
||||
} else if (key) {
|
||||
param();
|
||||
} else {
|
||||
i = 0;
|
||||
callbacks();
|
||||
}
|
||||
} catch (err) {
|
||||
param(err);
|
||||
}
|
||||
};
|
||||
try {
|
||||
if ( 'route' == err ) {
|
||||
nextRoute();
|
||||
} else if ( err ) {
|
||||
i = 0;
|
||||
callbacks( err );
|
||||
} else if ( paramCallbacks && undefined !== paramVal ) {
|
||||
paramCallback();
|
||||
} else if ( key ) {
|
||||
param();
|
||||
} else {
|
||||
i = 0;
|
||||
callbacks();
|
||||
}
|
||||
} catch ( err ) {
|
||||
param( err );
|
||||
}
|
||||
}
|
||||
|
||||
param(err);
|
||||
|
||||
// single param callbacks
|
||||
function paramCallback(err) {
|
||||
var fn = paramCallbacks[paramIndex++];
|
||||
if (err || !fn) return param(err);
|
||||
fn(req, res, paramCallback, paramVal, key.name);
|
||||
}
|
||||
;
|
||||
|
||||
// invoke route callbacks
|
||||
function callbacks(err) {
|
||||
var fn = route.callbacks[i++];
|
||||
try {
|
||||
if ('route' == err) {
|
||||
nextRoute();
|
||||
} else if (err && fn) {
|
||||
if (fn.length < 4) return callbacks(err);
|
||||
fn(err, req, res, callbacks);
|
||||
} else if (fn) {
|
||||
fn(req, res, callbacks);
|
||||
} else {
|
||||
nextRoute(err);
|
||||
}
|
||||
} catch (err) {
|
||||
callbacks(err);
|
||||
}
|
||||
}
|
||||
})(0);
|
||||
param( err );
|
||||
|
||||
// single param callbacks
|
||||
function paramCallback( err ) {
|
||||
var fn = paramCallbacks[paramIndex++];
|
||||
if ( err || !fn ) {
|
||||
return param( err );
|
||||
}
|
||||
fn( req, res, paramCallback, paramVal, key.name );
|
||||
}
|
||||
|
||||
// invoke route callbacks
|
||||
function callbacks( err ) {
|
||||
var fn = route.callbacks[i++];
|
||||
try {
|
||||
if ( 'route' == err ) {
|
||||
nextRoute();
|
||||
} else if ( err && fn ) {
|
||||
if ( fn.length < 4 ) {
|
||||
return callbacks( err );
|
||||
}
|
||||
fn( err, req, res, callbacks );
|
||||
} else if ( fn ) {
|
||||
fn( req, res, callbacks );
|
||||
} else {
|
||||
nextRoute( err );
|
||||
}
|
||||
} catch ( err ) {
|
||||
callbacks( err );
|
||||
}
|
||||
}
|
||||
})( 0 );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -288,10 +301,10 @@ Router.prototype._dispatch = function(req, res, next){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._options = function(req, res){
|
||||
var path = parse(req.url).pathname
|
||||
, body = this._optionsFor(path).join(',');
|
||||
res.send(body, { Allow: body });
|
||||
Router.prototype._options = function ( req, res ) {
|
||||
var path = parse( req.url ).pathname
|
||||
, body = this._optionsFor( path ).join( ',' );
|
||||
res.send( body, { Allow : body } );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -302,17 +315,22 @@ Router.prototype._options = function(req, res){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._optionsFor = function(path){
|
||||
var self = this;
|
||||
return methods.filter(function(method){
|
||||
var routes = self.routes[method];
|
||||
if (!routes || 'options' == method) return;
|
||||
for (var i = 0, len = routes.length; i < len; ++i) {
|
||||
if (routes[i].match(path)) return true;
|
||||
}
|
||||
}).map(function(method){
|
||||
return method.toUpperCase();
|
||||
});
|
||||
Router.prototype._optionsFor = function ( path ) {
|
||||
var self = this;
|
||||
return methods.filter(
|
||||
function ( method ) {
|
||||
var routes = self.routes[method];
|
||||
if ( !routes || 'options' == method ) {
|
||||
return;
|
||||
}
|
||||
for ( var i = 0, len = routes.length; i < len; ++i ) {
|
||||
if ( routes[i].match( path ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} ).map( function ( method ) {
|
||||
return method.toUpperCase();
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -325,47 +343,49 @@ Router.prototype._optionsFor = function(path){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._match = function(req, i){
|
||||
var method = req.method.toLowerCase()
|
||||
, url = parse(req.url)
|
||||
, path = url.pathname
|
||||
, routes = this.routes
|
||||
, captures
|
||||
, route
|
||||
, keys;
|
||||
Router.prototype._match = function ( req, i ) {
|
||||
var method = req.method.toLowerCase()
|
||||
, url = parse( req.url )
|
||||
, path = url.pathname
|
||||
, routes = this.routes
|
||||
, captures
|
||||
, route
|
||||
, keys;
|
||||
|
||||
// pass HEAD to GET routes
|
||||
if ('head' == method) method = 'get';
|
||||
// pass HEAD to GET routes
|
||||
if ( 'head' == method ) {
|
||||
method = 'get';
|
||||
}
|
||||
|
||||
// routes for this method
|
||||
if (routes = routes[method]) {
|
||||
// routes for this method
|
||||
if ( routes = routes[method] ) {
|
||||
|
||||
// matching routes
|
||||
for (var len = routes.length; i < len; ++i) {
|
||||
route = routes[i];
|
||||
if (captures = route.match(path)) {
|
||||
keys = route.keys;
|
||||
route.params = [];
|
||||
// matching routes
|
||||
for ( var len = routes.length; i < len; ++i ) {
|
||||
route = routes[i];
|
||||
if ( captures = route.match( path ) ) {
|
||||
keys = route.keys;
|
||||
route.params = [];
|
||||
|
||||
// params from capture groups
|
||||
for (var j = 1, jlen = captures.length; j < jlen; ++j) {
|
||||
var key = keys[j-1]
|
||||
, val = 'string' == typeof captures[j]
|
||||
? decodeURIComponent(captures[j])
|
||||
: captures[j];
|
||||
if (key) {
|
||||
route.params[key.name] = val;
|
||||
} else {
|
||||
route.params.push(val);
|
||||
}
|
||||
}
|
||||
// params from capture groups
|
||||
for ( var j = 1, jlen = captures.length; j < jlen; ++j ) {
|
||||
var key = keys[j - 1]
|
||||
, val = 'string' == typeof captures[j]
|
||||
? decodeURIComponent( captures[j] )
|
||||
: captures[j];
|
||||
if ( key ) {
|
||||
route.params[key.name] = val;
|
||||
} else {
|
||||
route.params.push( val );
|
||||
}
|
||||
}
|
||||
|
||||
// all done
|
||||
req._route_index = i;
|
||||
return route;
|
||||
}
|
||||
}
|
||||
}
|
||||
// all done
|
||||
req._route_index = i;
|
||||
return route;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -378,21 +398,22 @@ Router.prototype._match = function(req, i){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._route = function(method, path, callbacks){
|
||||
var app = this.app
|
||||
, callbacks = utils.flatten(toArray(arguments, 2));
|
||||
Router.prototype._route = function ( method, path, callbacks ) {
|
||||
var app = this.app
|
||||
, callbacks = utils.flatten( toArray( arguments, 2 ) );
|
||||
|
||||
// ensure path was given
|
||||
if (!path) throw new Error('app.' + method + '() requires a path');
|
||||
// ensure path was given
|
||||
if ( !path ) {
|
||||
throw new Error( 'app.' + method + '() requires a path' );
|
||||
}
|
||||
|
||||
// create the route
|
||||
var route = new Route(method, path, callbacks, {
|
||||
sensitive: app.enabled('case sensitive routes')
|
||||
, strict: app.enabled('strict routing')
|
||||
});
|
||||
// create the route
|
||||
var route = new Route( method, path, callbacks, {
|
||||
sensitive : app.enabled( 'case sensitive routes' ), strict : app.enabled( 'strict routing' )
|
||||
} );
|
||||
|
||||
// add it
|
||||
(this.routes[method] = this.routes[method] || [])
|
||||
.push(route);
|
||||
return this;
|
||||
// add it
|
||||
(this.routes[method] = this.routes[method] || [])
|
||||
.push( route );
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
29
example/node/node_modules/express/lib/router/methods.js
generated
vendored
29
example/node/node_modules/express/lib/router/methods.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - router - methods
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -6,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Hypertext Transfer Protocol -- HTTP/1.1
|
||||
* Hypertext Transfer Protocol -- HTTP/1.1
|
||||
* http://www.ietf.org/rfc/rfc2616.txt
|
||||
*/
|
||||
|
||||
|
|
@ -20,21 +19,21 @@ var RFC2616 = ['OPTIONS', 'GET', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'];
|
|||
var RFC2518 = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'];
|
||||
|
||||
/**
|
||||
* Versioning Extensions to WebDAV
|
||||
* Versioning Extensions to WebDAV
|
||||
* http://www.ietf.org/rfc/rfc3253.txt
|
||||
*/
|
||||
|
||||
var RFC3253 = ['VERSION-CONTROL', 'REPORT', 'CHECKOUT', 'CHECKIN', 'UNCHECKOUT', 'MKWORKSPACE', 'UPDATE', 'LABEL', 'MERGE', 'BASELINE-CONTROL', 'MKACTIVITY'];
|
||||
|
||||
/**
|
||||
* Ordered Collections Protocol (WebDAV)
|
||||
* Ordered Collections Protocol (WebDAV)
|
||||
* http://www.ietf.org/rfc/rfc3648.txt
|
||||
*/
|
||||
|
||||
var RFC3648 = ['ORDERPATCH'];
|
||||
|
||||
/**
|
||||
* Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol
|
||||
* Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol
|
||||
* http://www.ietf.org/rfc/rfc3744.txt
|
||||
*/
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ var RFC3744 = ['ACL'];
|
|||
var RFC5323 = ['SEARCH'];
|
||||
|
||||
/**
|
||||
* PATCH Method for HTTP
|
||||
* PATCH Method for HTTP
|
||||
* http://www.ietf.org/rfc/rfc5789.txt
|
||||
*/
|
||||
|
||||
|
|
@ -59,12 +58,12 @@ var RFC5789 = ['PATCH'];
|
|||
*/
|
||||
|
||||
module.exports = [].concat(
|
||||
RFC2616
|
||||
, RFC2518
|
||||
, RFC3253
|
||||
, RFC3648
|
||||
, RFC3744
|
||||
, RFC5323
|
||||
, RFC5789).map(function(method){
|
||||
return method.toLowerCase();
|
||||
});
|
||||
RFC2616
|
||||
, RFC2518
|
||||
, RFC3253
|
||||
, RFC3648
|
||||
, RFC3744
|
||||
, RFC5323
|
||||
, RFC5789 ).map( function ( method ) {
|
||||
return method.toLowerCase();
|
||||
} );
|
||||
|
|
|
|||
61
example/node/node_modules/express/lib/router/route.js
generated
vendored
61
example/node/node_modules/express/lib/router/route.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - router - Route
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -27,15 +26,15 @@ module.exports = Route;
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function Route(method, path, callbacks, options) {
|
||||
options = options || {};
|
||||
this.path = path;
|
||||
this.method = method;
|
||||
this.callbacks = callbacks;
|
||||
this.regexp = normalize(path
|
||||
, this.keys = []
|
||||
, options.sensitive
|
||||
, options.strict);
|
||||
function Route( method, path, callbacks, options ) {
|
||||
options = options || {};
|
||||
this.path = path;
|
||||
this.method = method;
|
||||
this.callbacks = callbacks;
|
||||
this.regexp = normalize( path
|
||||
, this.keys = []
|
||||
, options.sensitive
|
||||
, options.strict );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -46,8 +45,8 @@ function Route(method, path, callbacks, options) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Route.prototype.match = function(path){
|
||||
return this.regexp.exec(path);
|
||||
Route.prototype.match = function ( path ) {
|
||||
return this.regexp.exec( path );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -67,22 +66,24 @@ Route.prototype.match = function(path){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function normalize(path, keys, sensitive, strict) {
|
||||
if (path instanceof RegExp) return path;
|
||||
path = path
|
||||
.concat(strict ? '' : '/?')
|
||||
.replace(/\/\(/g, '(?:/')
|
||||
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
||||
keys.push({ name: key, optional: !! optional });
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'
|
||||
+ (optional || '');
|
||||
})
|
||||
.replace(/([\/.])/g, '\\$1')
|
||||
.replace(/\*/g, '(.*)');
|
||||
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||
function normalize( path, keys, sensitive, strict ) {
|
||||
if ( path instanceof RegExp ) {
|
||||
return path;
|
||||
}
|
||||
path = path
|
||||
.concat( strict ? '' : '/?' )
|
||||
.replace( /\/\(/g, '(?:/' )
|
||||
.replace( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function ( _, slash, format, key, capture, optional ) {
|
||||
keys.push( { name : key, optional : !!optional } );
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'
|
||||
+ (optional || '');
|
||||
} )
|
||||
.replace( /([\/.])/g, '\\$1' )
|
||||
.replace( /\*/g, '(.*)' );
|
||||
return new RegExp( '^' + path + '$', sensitive ? '' : 'i' );
|
||||
}
|
||||
|
|
|
|||
135
example/node/node_modules/express/lib/utils.js
generated
vendored
135
example/node/node_modules/express/lib/utils.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - Utils
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -13,9 +12,13 @@
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.isAbsolute = function(path){
|
||||
if ('/' == path[0]) return true;
|
||||
if (':' == path[1] && '\\' == path[2]) return true;
|
||||
exports.isAbsolute = function ( path ) {
|
||||
if ( '/' == path[0] ) {
|
||||
return true;
|
||||
}
|
||||
if ( ':' == path[1] && '\\' == path[2] ) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -28,19 +31,19 @@ exports.isAbsolute = function(path){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.union = function(a, b){
|
||||
if (a && b) {
|
||||
var keys = Object.keys(b)
|
||||
, len = keys.length
|
||||
, key;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
key = keys[i];
|
||||
if (!a.hasOwnProperty(key)) {
|
||||
a[key] = b[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
exports.union = function ( a, b ) {
|
||||
if ( a && b ) {
|
||||
var keys = Object.keys( b )
|
||||
, len = keys.length
|
||||
, key;
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
key = keys[i];
|
||||
if ( !a.hasOwnProperty( key ) ) {
|
||||
a[key] = b[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -51,17 +54,17 @@ exports.union = function(a, b){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.flatten = function(arr, ret){
|
||||
var ret = ret || []
|
||||
, len = arr.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (Array.isArray(arr[i])) {
|
||||
exports.flatten(arr[i], ret);
|
||||
} else {
|
||||
ret.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
exports.flatten = function ( arr, ret ) {
|
||||
var ret = ret || []
|
||||
, len = arr.length;
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
if ( Array.isArray( arr[i] ) ) {
|
||||
exports.flatten( arr[i], ret );
|
||||
} else {
|
||||
ret.push( arr[i] );
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -78,11 +81,11 @@ exports.flatten = function(arr, ret){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.miniMarkdown = function(str){
|
||||
return String(str)
|
||||
.replace(/(__|\*\*)(.*?)\1/g, '<strong>$2</strong>')
|
||||
.replace(/(_|\*)(.*?)\1/g, '<em>$2</em>')
|
||||
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
|
||||
exports.miniMarkdown = function ( str ) {
|
||||
return String( str )
|
||||
.replace( /(__|\*\*)(.*?)\1/g, '<strong>$2</strong>' )
|
||||
.replace( /(_|\*)(.*?)\1/g, '<em>$2</em>' )
|
||||
.replace( /\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -93,12 +96,12 @@ exports.miniMarkdown = function(str){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.escape = function(html) {
|
||||
return String(html)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
exports.escape = function ( html ) {
|
||||
return String( html )
|
||||
.replace( /&/g, '&' )
|
||||
.replace( /"/g, '"' )
|
||||
.replace( /</g, '<' )
|
||||
.replace( />/g, '>' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -110,28 +113,30 @@ exports.escape = function(html) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.parseRange = function(size, str){
|
||||
var valid = true;
|
||||
var arr = str.substr(6).split(',').map(function(range){
|
||||
var range = range.split('-')
|
||||
, start = parseInt(range[0], 10)
|
||||
, end = parseInt(range[1], 10);
|
||||
exports.parseRange = function ( size, str ) {
|
||||
var valid = true;
|
||||
var arr = str.substr( 6 ).split( ',' ).map( function ( range ) {
|
||||
var range = range.split( '-' )
|
||||
, start = parseInt( range[0], 10 )
|
||||
, end = parseInt( range[1], 10 );
|
||||
|
||||
// -500
|
||||
if (isNaN(start)) {
|
||||
start = size - end;
|
||||
end = size - 1;
|
||||
// 500-
|
||||
} else if (isNaN(end)) {
|
||||
end = size - 1;
|
||||
}
|
||||
// -500
|
||||
if ( isNaN( start ) ) {
|
||||
start = size - end;
|
||||
end = size - 1;
|
||||
// 500-
|
||||
} else if ( isNaN( end ) ) {
|
||||
end = size - 1;
|
||||
}
|
||||
|
||||
// Invalid
|
||||
if (isNaN(start) || isNaN(end) || start > end) valid = false;
|
||||
// Invalid
|
||||
if ( isNaN( start ) || isNaN( end ) || start > end ) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return { start: start, end: end };
|
||||
});
|
||||
return valid ? arr : undefined;
|
||||
return { start : start, end : end };
|
||||
} );
|
||||
return valid ? arr : undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -143,10 +148,12 @@ exports.parseRange = function(size, str){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports.toArray = function(args, i){
|
||||
var arr = []
|
||||
, len = args.length
|
||||
, i = i || 0;
|
||||
for (; i < len; ++i) arr.push(args[i]);
|
||||
return arr;
|
||||
exports.toArray = function ( args, i ) {
|
||||
var arr = []
|
||||
, len = args.length
|
||||
, i = i || 0;
|
||||
for ( ; i < len; ++i ) {
|
||||
arr.push( args[i] );
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
|
|
|||
590
example/node/node_modules/express/lib/view.js
generated
vendored
590
example/node/node_modules/express/lib/view.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - view
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,17 +8,17 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
, extname = path.extname
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, utils = require('connect').utils
|
||||
, View = require('./view/view')
|
||||
, partial = require('./view/partial')
|
||||
, union = require('./utils').union
|
||||
, merge = utils.merge
|
||||
, http = require('http')
|
||||
, res = http.ServerResponse.prototype;
|
||||
var path = require( 'path' )
|
||||
, extname = path.extname
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, utils = require( 'connect' ).utils
|
||||
, View = require( './view/view' )
|
||||
, partial = require( './view/partial' )
|
||||
, union = require( './utils' ).union
|
||||
, merge = utils.merge
|
||||
, http = require( 'http' )
|
||||
, res = http.ServerResponse.prototype;
|
||||
|
||||
/**
|
||||
* Expose constructors.
|
||||
|
|
@ -46,29 +45,31 @@ exports.register = View.register;
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.compile = function(view, cache, cid, options){
|
||||
if (cache && cid && cache[cid]){
|
||||
options.filename = cache[cid].path;
|
||||
return cache[cid];
|
||||
}
|
||||
exports.compile = function ( view, cache, cid, options ) {
|
||||
if ( cache && cid && cache[cid] ) {
|
||||
options.filename = cache[cid].path;
|
||||
return cache[cid];
|
||||
}
|
||||
|
||||
// lookup
|
||||
view = exports.lookup(view, options);
|
||||
// lookup
|
||||
view = exports.lookup( view, options );
|
||||
|
||||
// hints
|
||||
if (!view.exists) {
|
||||
if (options.hint) hintAtViewPaths(view.original, options);
|
||||
var err = new Error('failed to locate view "' + view.original.view + '"');
|
||||
err.view = view.original;
|
||||
throw err;
|
||||
}
|
||||
// hints
|
||||
if ( !view.exists ) {
|
||||
if ( options.hint ) {
|
||||
hintAtViewPaths( view.original, options );
|
||||
}
|
||||
var err = new Error( 'failed to locate view "' + view.original.view + '"' );
|
||||
err.view = view.original;
|
||||
throw err;
|
||||
}
|
||||
|
||||
// compile
|
||||
options.filename = view.path;
|
||||
view.fn = view.templateEngine.compile(view.contents, options);
|
||||
cache[cid] = view;
|
||||
// compile
|
||||
options.filename = view.path;
|
||||
view.fn = view.templateEngine.compile( view.contents, options );
|
||||
cache[cid] = view;
|
||||
|
||||
return view;
|
||||
return view;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -96,33 +97,43 @@ exports.compile = function(view, cache, cid, options){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.lookup = function(view, options){
|
||||
var orig = view = new View(view, options)
|
||||
, partial = options.isPartial
|
||||
, layout = options.isLayout;
|
||||
exports.lookup = function ( view, options ) {
|
||||
var orig = view = new View( view, options )
|
||||
, partial = options.isPartial
|
||||
, layout = options.isLayout;
|
||||
|
||||
// Try _ prefix ex: ./views/_<name>.jade
|
||||
// taking precedence over the direct path
|
||||
if (partial) {
|
||||
view = new View(orig.prefixPath, options);
|
||||
if (!view.exists) view = orig;
|
||||
}
|
||||
// Try _ prefix ex: ./views/_<name>.jade
|
||||
// taking precedence over the direct path
|
||||
if ( partial ) {
|
||||
view = new View( orig.prefixPath, options );
|
||||
if ( !view.exists ) {
|
||||
view = orig;
|
||||
}
|
||||
}
|
||||
|
||||
// Try index ex: ./views/user/index.jade
|
||||
if (!layout && !view.exists) view = new View(orig.indexPath, options);
|
||||
// Try index ex: ./views/user/index.jade
|
||||
if ( !layout && !view.exists ) {
|
||||
view = new View( orig.indexPath, options );
|
||||
}
|
||||
|
||||
// Try ../<name>/index ex: ../user/index.jade
|
||||
// when calling partial('user') within the same dir
|
||||
if (!layout && !view.exists) view = new View(orig.upIndexPath, options);
|
||||
// Try ../<name>/index ex: ../user/index.jade
|
||||
// when calling partial('user') within the same dir
|
||||
if ( !layout && !view.exists ) {
|
||||
view = new View( orig.upIndexPath, options );
|
||||
}
|
||||
|
||||
// Try root ex: <root>/user.jade
|
||||
if (!view.exists) view = new View(orig.rootPath, options);
|
||||
// Try root ex: <root>/user.jade
|
||||
if ( !view.exists ) {
|
||||
view = new View( orig.rootPath, options );
|
||||
}
|
||||
|
||||
// Try root _ prefix ex: <root>/_user.jade
|
||||
if (!view.exists && partial) view = new View(view.prefixPath, options);
|
||||
// Try root _ prefix ex: <root>/_user.jade
|
||||
if ( !view.exists && partial ) {
|
||||
view = new View( view.prefixPath, options );
|
||||
}
|
||||
|
||||
view.original = orig;
|
||||
return view;
|
||||
view.original = orig;
|
||||
return view;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -131,103 +142,106 @@ exports.lookup = function(view, options){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function renderPartial(res, view, options, parentLocals, parent){
|
||||
var collection, object, locals;
|
||||
function renderPartial( res, view, options, parentLocals, parent ) {
|
||||
var collection, object, locals;
|
||||
|
||||
if (options) {
|
||||
// collection
|
||||
if (options.collection) {
|
||||
collection = options.collection;
|
||||
delete options.collection;
|
||||
} else if ('length' in options) {
|
||||
collection = options;
|
||||
options = {};
|
||||
}
|
||||
if ( options ) {
|
||||
// collection
|
||||
if ( options.collection ) {
|
||||
collection = options.collection;
|
||||
delete options.collection;
|
||||
} else if ( 'length' in options ) {
|
||||
collection = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
// locals
|
||||
if (options.locals) {
|
||||
locals = options.locals;
|
||||
delete options.locals;
|
||||
}
|
||||
// locals
|
||||
if ( options.locals ) {
|
||||
locals = options.locals;
|
||||
delete options.locals;
|
||||
}
|
||||
|
||||
// object
|
||||
if ('Object' != options.constructor.name) {
|
||||
object = options;
|
||||
options = {};
|
||||
} else if (undefined != options.object) {
|
||||
object = options.object;
|
||||
delete options.object;
|
||||
}
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
// object
|
||||
if ( 'Object' != options.constructor.name ) {
|
||||
object = options;
|
||||
options = {};
|
||||
} else if ( undefined != options.object ) {
|
||||
object = options.object;
|
||||
delete options.object;
|
||||
}
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
// Inherit locals from parent
|
||||
union(options, parentLocals);
|
||||
// Inherit locals from parent
|
||||
union( options, parentLocals );
|
||||
|
||||
// Merge locals
|
||||
if (locals) merge(options, locals);
|
||||
// Merge locals
|
||||
if ( locals ) {
|
||||
merge( options, locals );
|
||||
}
|
||||
|
||||
// Partials dont need layouts
|
||||
options.isPartial = true;
|
||||
options.layout = false;
|
||||
// Partials dont need layouts
|
||||
options.isPartial = true;
|
||||
options.layout = false;
|
||||
|
||||
// Deduce name from view path
|
||||
var name = options.as || partial.resolveObjectName(view);
|
||||
// Deduce name from view path
|
||||
var name = options.as || partial.resolveObjectName( view );
|
||||
|
||||
// Render partial
|
||||
function render(){
|
||||
if (object) {
|
||||
if ('string' == typeof name) {
|
||||
options[name] = object;
|
||||
} else if (name === global) {
|
||||
merge(options, object);
|
||||
}
|
||||
}
|
||||
return res.render(view, options, null, parent, true);
|
||||
}
|
||||
// Render partial
|
||||
function render() {
|
||||
if ( object ) {
|
||||
if ( 'string' == typeof name ) {
|
||||
options[name] = object;
|
||||
} else if ( name === global ) {
|
||||
merge( options, object );
|
||||
}
|
||||
}
|
||||
return res.render( view, options, null, parent, true );
|
||||
}
|
||||
|
||||
// Collection support
|
||||
if (collection) {
|
||||
var len = collection.length
|
||||
, buf = ''
|
||||
, keys
|
||||
, key
|
||||
, val;
|
||||
// Collection support
|
||||
if ( collection ) {
|
||||
var len = collection.length
|
||||
, buf = ''
|
||||
, keys
|
||||
, key
|
||||
, val;
|
||||
|
||||
options.collectionLength = len;
|
||||
options.collectionLength = len;
|
||||
|
||||
if ('number' == typeof len || Array.isArray(collection)) {
|
||||
for (var i = 0; i < len; ++i) {
|
||||
val = collection[i];
|
||||
options.firstInCollection = i == 0;
|
||||
options.indexInCollection = i;
|
||||
options.lastInCollection = i == len - 1;
|
||||
object = val;
|
||||
buf += render();
|
||||
}
|
||||
} else {
|
||||
keys = Object.keys(collection);
|
||||
len = keys.length;
|
||||
options.collectionLength = len;
|
||||
options.collectionKeys = keys;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
key = keys[i];
|
||||
val = collection[key];
|
||||
options.keyInCollection = key;
|
||||
options.firstInCollection = i == 0;
|
||||
options.indexInCollection = i;
|
||||
options.lastInCollection = i == len - 1;
|
||||
object = val;
|
||||
buf += render();
|
||||
}
|
||||
}
|
||||
if ( 'number' == typeof len || Array.isArray( collection ) ) {
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
val = collection[i];
|
||||
options.firstInCollection = i == 0;
|
||||
options.indexInCollection = i;
|
||||
options.lastInCollection = i == len - 1;
|
||||
object = val;
|
||||
buf += render();
|
||||
}
|
||||
} else {
|
||||
keys = Object.keys( collection );
|
||||
len = keys.length;
|
||||
options.collectionLength = len;
|
||||
options.collectionKeys = keys;
|
||||
for ( var i = 0; i < len; ++i ) {
|
||||
key = keys[i];
|
||||
val = collection[key];
|
||||
options.keyInCollection = key;
|
||||
options.firstInCollection = i == 0;
|
||||
options.indexInCollection = i;
|
||||
options.lastInCollection = i == len - 1;
|
||||
object = val;
|
||||
buf += render();
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
} else {
|
||||
return render();
|
||||
}
|
||||
};
|
||||
return buf;
|
||||
} else {
|
||||
return render();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Render `view` partial with the given `options`. Optionally a
|
||||
|
|
@ -253,42 +267,44 @@ function renderPartial(res, view, options, parentLocals, parent){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.partial = function(view, options, fn){
|
||||
var app = this.app
|
||||
, options = options || {}
|
||||
, viewEngine = app.set('view engine')
|
||||
, parent = {};
|
||||
res.partial = function ( view, options, fn ) {
|
||||
var app = this.app
|
||||
, options = options || {}
|
||||
, viewEngine = app.set( 'view engine' )
|
||||
, parent = {};
|
||||
|
||||
// accept callback as second argument
|
||||
if ('function' == typeof options) {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
// accept callback as second argument
|
||||
if ( 'function' == typeof options ) {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
// root "views" option
|
||||
parent.dirname = app.set('views') || process.cwd() + '/views';
|
||||
// root "views" option
|
||||
parent.dirname = app.set( 'views' ) || process.cwd() + '/views';
|
||||
|
||||
// utilize "view engine" option
|
||||
if (viewEngine) parent.engine = viewEngine;
|
||||
// utilize "view engine" option
|
||||
if ( viewEngine ) {
|
||||
parent.engine = viewEngine;
|
||||
}
|
||||
|
||||
// render the partial
|
||||
try {
|
||||
var str = renderPartial(this, view, options, null, parent);
|
||||
} catch (err) {
|
||||
if (fn) {
|
||||
fn(err);
|
||||
} else {
|
||||
this.req.next(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// render the partial
|
||||
try {
|
||||
var str = renderPartial( this, view, options, null, parent );
|
||||
} catch ( err ) {
|
||||
if ( fn ) {
|
||||
fn( err );
|
||||
} else {
|
||||
this.req.next( err );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// callback or transfer
|
||||
if (fn) {
|
||||
fn(null, str);
|
||||
} else {
|
||||
this.send(str);
|
||||
}
|
||||
// callback or transfer
|
||||
if ( fn ) {
|
||||
fn( null, str );
|
||||
} else {
|
||||
this.send( str );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -308,139 +324,151 @@ res.partial = function(view, options, fn){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
res.render = function(view, opts, fn, parent, sub){
|
||||
// support callback function as second arg
|
||||
if ('function' == typeof opts) {
|
||||
fn = opts, opts = null;
|
||||
}
|
||||
res.render = function ( view, opts, fn, parent, sub ) {
|
||||
// support callback function as second arg
|
||||
if ( 'function' == typeof opts ) {
|
||||
fn = opts, opts = null;
|
||||
}
|
||||
|
||||
try {
|
||||
return this._render(view, opts, fn, parent, sub);
|
||||
} catch (err) {
|
||||
// callback given
|
||||
if (fn) {
|
||||
fn(err);
|
||||
// unwind to root call to prevent multiple callbacks
|
||||
} else if (sub) {
|
||||
throw err;
|
||||
// root template, next(err)
|
||||
} else {
|
||||
this.req.next(err);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return this._render( view, opts, fn, parent, sub );
|
||||
} catch ( err ) {
|
||||
// callback given
|
||||
if ( fn ) {
|
||||
fn( err );
|
||||
// unwind to root call to prevent multiple callbacks
|
||||
} else if ( sub ) {
|
||||
throw err;
|
||||
// root template, next(err)
|
||||
} else {
|
||||
this.req.next( err );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// private render()
|
||||
|
||||
res._render = function(view, opts, fn, parent, sub){
|
||||
var options = {}
|
||||
, self = this
|
||||
, app = this.app
|
||||
, helpers = app._locals
|
||||
, dynamicHelpers = app.dynamicViewHelpers
|
||||
, viewOptions = app.set('view options')
|
||||
, root = app.set('views') || process.cwd() + '/views';
|
||||
res._render = function ( view, opts, fn, parent, sub ) {
|
||||
var options = {}
|
||||
, self = this
|
||||
, app = this.app
|
||||
, helpers = app._locals
|
||||
, dynamicHelpers = app.dynamicViewHelpers
|
||||
, viewOptions = app.set( 'view options' )
|
||||
, root = app.set( 'views' ) || process.cwd() + '/views';
|
||||
|
||||
// cache id
|
||||
var cid = app.enabled('view cache')
|
||||
? view + (parent ? ':' + parent.path : '')
|
||||
: false;
|
||||
// cache id
|
||||
var cid = app.enabled( 'view cache' )
|
||||
? view + (parent ? ':' + parent.path : '')
|
||||
: false;
|
||||
|
||||
// merge "view options"
|
||||
if (viewOptions) merge(options, viewOptions);
|
||||
// merge "view options"
|
||||
if ( viewOptions ) {
|
||||
merge( options, viewOptions );
|
||||
}
|
||||
|
||||
// merge res._locals
|
||||
if (this._locals) merge(options, this._locals);
|
||||
// merge res._locals
|
||||
if ( this._locals ) {
|
||||
merge( options, this._locals );
|
||||
}
|
||||
|
||||
// merge render() options
|
||||
if (opts) merge(options, opts);
|
||||
// merge render() options
|
||||
if ( opts ) {
|
||||
merge( options, opts );
|
||||
}
|
||||
|
||||
// merge render() .locals
|
||||
if (opts && opts.locals) merge(options, opts.locals);
|
||||
// merge render() .locals
|
||||
if ( opts && opts.locals ) {
|
||||
merge( options, opts.locals );
|
||||
}
|
||||
|
||||
// status support
|
||||
if (options.status) this.statusCode = options.status;
|
||||
// status support
|
||||
if ( options.status ) {
|
||||
this.statusCode = options.status;
|
||||
}
|
||||
|
||||
// capture attempts
|
||||
options.attempts = [];
|
||||
// capture attempts
|
||||
options.attempts = [];
|
||||
|
||||
var partial = options.isPartial
|
||||
, layout = options.layout;
|
||||
var partial = options.isPartial
|
||||
, layout = options.layout;
|
||||
|
||||
// Layout support
|
||||
if (true === layout || undefined === layout) {
|
||||
layout = 'layout';
|
||||
}
|
||||
// Layout support
|
||||
if ( true === layout || undefined === layout ) {
|
||||
layout = 'layout';
|
||||
}
|
||||
|
||||
// Default execution scope to a plain object
|
||||
options.scope = options.scope || {};
|
||||
// Default execution scope to a plain object
|
||||
options.scope = options.scope || {};
|
||||
|
||||
// Populate view
|
||||
options.parentView = parent;
|
||||
// Populate view
|
||||
options.parentView = parent;
|
||||
|
||||
// "views" setting
|
||||
options.root = root;
|
||||
// "views" setting
|
||||
options.root = root;
|
||||
|
||||
// "view engine" setting
|
||||
options.defaultEngine = app.set('view engine');
|
||||
// "view engine" setting
|
||||
options.defaultEngine = app.set( 'view engine' );
|
||||
|
||||
// charset option
|
||||
if (options.charset) this.charset = options.charset;
|
||||
// charset option
|
||||
if ( options.charset ) {
|
||||
this.charset = options.charset;
|
||||
}
|
||||
|
||||
// Dynamic helper support
|
||||
if (false !== options.dynamicHelpers) {
|
||||
// cache
|
||||
if (!this.__dynamicHelpers) {
|
||||
this.__dynamicHelpers = {};
|
||||
for (var key in dynamicHelpers) {
|
||||
this.__dynamicHelpers[key] = dynamicHelpers[key].call(
|
||||
this.app
|
||||
, this.req
|
||||
, this);
|
||||
}
|
||||
}
|
||||
// Dynamic helper support
|
||||
if ( false !== options.dynamicHelpers ) {
|
||||
// cache
|
||||
if ( !this.__dynamicHelpers ) {
|
||||
this.__dynamicHelpers = {};
|
||||
for ( var key in dynamicHelpers ) {
|
||||
this.__dynamicHelpers[key] = dynamicHelpers[key].call(
|
||||
this.app
|
||||
, this.req
|
||||
, this );
|
||||
}
|
||||
}
|
||||
|
||||
// apply
|
||||
merge(options, this.__dynamicHelpers);
|
||||
}
|
||||
// apply
|
||||
merge( options, this.__dynamicHelpers );
|
||||
}
|
||||
|
||||
// Merge view helpers
|
||||
union(options, helpers);
|
||||
// Merge view helpers
|
||||
union( options, helpers );
|
||||
|
||||
// Always expose partial() as a local
|
||||
options.partial = function(path, opts){
|
||||
return renderPartial(self, path, opts, options, view);
|
||||
};
|
||||
// Always expose partial() as a local
|
||||
options.partial = function ( path, opts ) {
|
||||
return renderPartial( self, path, opts, options, view );
|
||||
};
|
||||
|
||||
// View lookup
|
||||
options.hint = app.enabled('hints');
|
||||
view = exports.compile(view, app.cache, cid, options);
|
||||
// View lookup
|
||||
options.hint = app.enabled( 'hints' );
|
||||
view = exports.compile( view, app.cache, cid, options );
|
||||
|
||||
// layout helper
|
||||
options.layout = function(path){
|
||||
layout = path;
|
||||
};
|
||||
// layout helper
|
||||
options.layout = function ( path ) {
|
||||
layout = path;
|
||||
};
|
||||
|
||||
// render
|
||||
var str = view.fn.call(options.scope, options);
|
||||
// render
|
||||
var str = view.fn.call( options.scope, options );
|
||||
|
||||
// layout expected
|
||||
if (layout) {
|
||||
options.isLayout = true;
|
||||
options.layout = false;
|
||||
options.body = str;
|
||||
this.render(layout, options, fn, view, true);
|
||||
// partial return
|
||||
} else if (partial) {
|
||||
return str;
|
||||
// render complete, and
|
||||
// callback given
|
||||
} else if (fn) {
|
||||
fn(null, str);
|
||||
// respond
|
||||
} else {
|
||||
this.send(str);
|
||||
}
|
||||
// layout expected
|
||||
if ( layout ) {
|
||||
options.isLayout = true;
|
||||
options.layout = false;
|
||||
options.body = str;
|
||||
this.render( layout, options, fn, view, true );
|
||||
// partial return
|
||||
} else if ( partial ) {
|
||||
return str;
|
||||
// render complete, and
|
||||
// callback given
|
||||
} else if ( fn ) {
|
||||
fn( null, str );
|
||||
// respond
|
||||
} else {
|
||||
this.send( str );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -450,11 +478,11 @@ res._render = function(view, opts, fn, parent, sub){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function hintAtViewPaths(view, options) {
|
||||
console.error();
|
||||
console.error('failed to locate view "' + view.view + '", tried:');
|
||||
options.attempts.forEach(function(path){
|
||||
console.error(' - %s', path);
|
||||
});
|
||||
console.error();
|
||||
function hintAtViewPaths( view, options ) {
|
||||
console.error();
|
||||
console.error( 'failed to locate view "' + view.view + '", tried:' );
|
||||
options.attempts.forEach( function ( path ) {
|
||||
console.error( ' - %s', path );
|
||||
} );
|
||||
console.error();
|
||||
}
|
||||
|
|
|
|||
26
example/node/node_modules/express/lib/view/partial.js
generated
vendored
26
example/node/node_modules/express/lib/view/partial.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - view - Partial
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -25,16 +24,17 @@ var cache = {};
|
|||
* @api private
|
||||
*/
|
||||
|
||||
exports.resolveObjectName = function(view){
|
||||
return cache[view] || (cache[view] = view
|
||||
.split('/')
|
||||
.slice(-1)[0]
|
||||
.split('.')[0]
|
||||
.replace(/^_/, '')
|
||||
.replace(/[^a-zA-Z0-9 ]+/g, ' ')
|
||||
.split(/ +/).map(function(word, i){
|
||||
return i
|
||||
? word[0].toUpperCase() + word.substr(1)
|
||||
: word;
|
||||
}).join(''));
|
||||
exports.resolveObjectName = function ( view ) {
|
||||
return cache[view] || (cache[view] = view
|
||||
.split( '/' )
|
||||
.slice( -1 )[0]
|
||||
.split( '.' )[0]
|
||||
.replace( /^_/, '' )
|
||||
.replace( /[^a-zA-Z0-9 ]+/g, ' ' )
|
||||
.split( / +/ ).map(
|
||||
function ( word, i ) {
|
||||
return i
|
||||
? word[0].toUpperCase() + word.substr( 1 )
|
||||
: word;
|
||||
} ).join( '' ));
|
||||
};
|
||||
169
example/node/node_modules/express/lib/view/view.js
generated
vendored
169
example/node/node_modules/express/lib/view/view.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Express - View
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
|
@ -9,13 +8,13 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
, utils = require('../utils')
|
||||
, extname = path.extname
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, fs = require('fs')
|
||||
, stat = fs.statSync;
|
||||
var path = require( 'path' )
|
||||
, utils = require( '../utils' )
|
||||
, extname = path.extname
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, fs = require( 'fs' )
|
||||
, stat = fs.statSync;
|
||||
|
||||
/**
|
||||
* Expose `View`.
|
||||
|
|
@ -37,24 +36,26 @@ var cache = {};
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function View(view, options) {
|
||||
options = options || {};
|
||||
this.view = view;
|
||||
this.root = options.root;
|
||||
this.relative = false !== options.relative;
|
||||
this.defaultEngine = options.defaultEngine;
|
||||
this.parent = options.parentView;
|
||||
this.basename = basename(view);
|
||||
this.engine = this.resolveEngine();
|
||||
this.extension = '.' + this.engine;
|
||||
this.name = this.basename.replace(this.extension, '');
|
||||
this.path = this.resolvePath();
|
||||
this.dirname = dirname(this.path);
|
||||
if (options.attempts) {
|
||||
if (!~options.attempts.indexOf(this.path))
|
||||
options.attempts.push(this.path);
|
||||
}
|
||||
};
|
||||
function View( view, options ) {
|
||||
options = options || {};
|
||||
this.view = view;
|
||||
this.root = options.root;
|
||||
this.relative = false !== options.relative;
|
||||
this.defaultEngine = options.defaultEngine;
|
||||
this.parent = options.parentView;
|
||||
this.basename = basename( view );
|
||||
this.engine = this.resolveEngine();
|
||||
this.extension = '.' + this.engine;
|
||||
this.name = this.basename.replace( this.extension, '' );
|
||||
this.path = this.resolvePath();
|
||||
this.dirname = dirname( this.path );
|
||||
if ( options.attempts ) {
|
||||
if ( !~options.attempts.indexOf( this.path ) ) {
|
||||
options.attempts.push( this.path );
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Check if the view path exists.
|
||||
|
|
@ -63,14 +64,14 @@ function View(view, options) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('exists', function(){
|
||||
try {
|
||||
stat(this.path);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
View.prototype.__defineGetter__( 'exists', function () {
|
||||
try {
|
||||
stat( this.path );
|
||||
return true;
|
||||
} catch ( err ) {
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Resolve view engine.
|
||||
|
|
@ -79,13 +80,17 @@ View.prototype.__defineGetter__('exists', function(){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
View.prototype.resolveEngine = function(){
|
||||
// Explicit
|
||||
if (~this.basename.indexOf('.')) return extname(this.basename).substr(1);
|
||||
// Inherit from parent
|
||||
if (this.parent) return this.parent.engine;
|
||||
// Default
|
||||
return this.defaultEngine;
|
||||
View.prototype.resolveEngine = function () {
|
||||
// Explicit
|
||||
if ( ~this.basename.indexOf( '.' ) ) {
|
||||
return extname( this.basename ).substr( 1 );
|
||||
}
|
||||
// Inherit from parent
|
||||
if ( this.parent ) {
|
||||
return this.parent.engine;
|
||||
}
|
||||
// Default
|
||||
return this.defaultEngine;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -95,18 +100,24 @@ View.prototype.resolveEngine = function(){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
View.prototype.resolvePath = function(){
|
||||
var path = this.view;
|
||||
// Implicit engine
|
||||
if (!~this.basename.indexOf('.')) path += this.extension;
|
||||
// Absolute
|
||||
if (utils.isAbsolute(path)) return path;
|
||||
// Relative to parent
|
||||
if (this.relative && this.parent) return this.parent.dirname + '/' + path;
|
||||
// Relative to root
|
||||
return this.root
|
||||
? this.root + '/' + path
|
||||
: path;
|
||||
View.prototype.resolvePath = function () {
|
||||
var path = this.view;
|
||||
// Implicit engine
|
||||
if ( !~this.basename.indexOf( '.' ) ) {
|
||||
path += this.extension;
|
||||
}
|
||||
// Absolute
|
||||
if ( utils.isAbsolute( path ) ) {
|
||||
return path;
|
||||
}
|
||||
// Relative to parent
|
||||
if ( this.relative && this.parent ) {
|
||||
return this.parent.dirname + '/' + path;
|
||||
}
|
||||
// Relative to root
|
||||
return this.root
|
||||
? this.root + '/' + path
|
||||
: path;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -117,9 +128,9 @@ View.prototype.resolvePath = function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('contents', function(){
|
||||
return fs.readFileSync(this.path, 'utf8');
|
||||
});
|
||||
View.prototype.__defineGetter__( 'contents', function () {
|
||||
return fs.readFileSync( this.path, 'utf8' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Get template engine api, cache exports to reduce
|
||||
|
|
@ -129,10 +140,10 @@ View.prototype.__defineGetter__('contents', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('templateEngine', function(){
|
||||
var ext = this.extension;
|
||||
return cache[ext] || (cache[ext] = require(this.engine));
|
||||
});
|
||||
View.prototype.__defineGetter__( 'templateEngine', function () {
|
||||
var ext = this.extension;
|
||||
return cache[ext] || (cache[ext] = require( this.engine ));
|
||||
} );
|
||||
|
||||
/**
|
||||
* Return root path alternative.
|
||||
|
|
@ -141,10 +152,10 @@ View.prototype.__defineGetter__('templateEngine', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('rootPath', function(){
|
||||
this.relative = false;
|
||||
return this.resolvePath();
|
||||
});
|
||||
View.prototype.__defineGetter__( 'rootPath', function () {
|
||||
this.relative = false;
|
||||
return this.resolvePath();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Return index path alternative.
|
||||
|
|
@ -153,11 +164,11 @@ View.prototype.__defineGetter__('rootPath', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('indexPath', function(){
|
||||
return this.dirname
|
||||
+ '/' + this.basename.replace(this.extension, '')
|
||||
+ '/index' + this.extension;
|
||||
});
|
||||
View.prototype.__defineGetter__( 'indexPath', function () {
|
||||
return this.dirname
|
||||
+ '/' + this.basename.replace( this.extension, '' )
|
||||
+ '/index' + this.extension;
|
||||
} );
|
||||
|
||||
/**
|
||||
* Return ../<name>/index path alternative.
|
||||
|
|
@ -166,9 +177,9 @@ View.prototype.__defineGetter__('indexPath', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('upIndexPath', function(){
|
||||
return this.dirname + '/../' + this.name + '/index' + this.extension;
|
||||
});
|
||||
View.prototype.__defineGetter__( 'upIndexPath', function () {
|
||||
return this.dirname + '/../' + this.name + '/index' + this.extension;
|
||||
} );
|
||||
|
||||
/**
|
||||
* Return _ prefix path alternative
|
||||
|
|
@ -177,9 +188,9 @@ View.prototype.__defineGetter__('upIndexPath', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
View.prototype.__defineGetter__('prefixPath', function(){
|
||||
return this.dirname + '/_' + this.basename;
|
||||
});
|
||||
View.prototype.__defineGetter__( 'prefixPath', function () {
|
||||
return this.dirname + '/_' + this.basename;
|
||||
} );
|
||||
|
||||
/**
|
||||
* Register the given template engine `exports`
|
||||
|
|
@ -204,7 +215,9 @@ View.prototype.__defineGetter__('prefixPath', function(){
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports.register = function(ext, exports) {
|
||||
if ('.' != ext[0]) ext = '.' + ext;
|
||||
cache[ext] = exports;
|
||||
exports.register = function ( ext, exports ) {
|
||||
if ( '.' != ext[0] ) {
|
||||
ext = '.' + ext;
|
||||
}
|
||||
cache[ext] = exports;
|
||||
};
|
||||
|
|
|
|||
3
example/node/node_modules/express/node_modules/connect/index.js
generated
vendored
3
example/node/node_modules/express/node_modules/connect/index.js
generated
vendored
|
|
@ -1,2 +1 @@
|
|||
|
||||
module.exports = require('./lib/connect');
|
||||
module.exports = require( './lib/connect' );
|
||||
41
example/node/node_modules/express/node_modules/connect/lib/cache.js
generated
vendored
41
example/node/node_modules/express/node_modules/connect/lib/cache.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - Cache
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
|
|
@ -18,10 +17,10 @@ module.exports = Cache;
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function Cache(limit) {
|
||||
this.store = {};
|
||||
this.keys = [];
|
||||
this.limit = limit;
|
||||
function Cache( limit ) {
|
||||
this.store = {};
|
||||
this.keys = [];
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -32,9 +31,9 @@ function Cache(limit) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.touch = function(key, i){
|
||||
this.keys.splice(i,1);
|
||||
this.keys.push(key);
|
||||
Cache.prototype.touch = function ( key, i ) {
|
||||
this.keys.splice( i, 1 );
|
||||
this.keys.push( key );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -44,8 +43,8 @@ Cache.prototype.touch = function(key, i){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.remove = function(key){
|
||||
delete this.store[key];
|
||||
Cache.prototype.remove = function ( key ) {
|
||||
delete this.store[key];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -56,8 +55,8 @@ Cache.prototype.remove = function(key){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.get = function(key){
|
||||
return this.store[key];
|
||||
Cache.prototype.get = function ( key ) {
|
||||
return this.store[key];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -68,14 +67,16 @@ Cache.prototype.get = function(key){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.add = function(key){
|
||||
// initialize store
|
||||
var len = this.keys.push(key);
|
||||
Cache.prototype.add = function ( key ) {
|
||||
// initialize store
|
||||
var len = this.keys.push( key );
|
||||
|
||||
// limit reached, invalid LRU
|
||||
if (len > this.limit) this.remove(this.keys.shift());
|
||||
// limit reached, invalid LRU
|
||||
if ( len > this.limit ) {
|
||||
this.remove( this.keys.shift() );
|
||||
}
|
||||
|
||||
var arr = this.store[key] = [];
|
||||
arr.createdAt = new Date;
|
||||
return arr;
|
||||
var arr = this.store[key] = [];
|
||||
arr.createdAt = new Date;
|
||||
return arr;
|
||||
};
|
||||
|
|
|
|||
42
example/node/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
42
example/node/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,13 +9,13 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var HTTPServer = require('./http').Server
|
||||
, HTTPSServer = require('./https').Server
|
||||
, fs = require('fs');
|
||||
var HTTPServer = require( './http' ).Server
|
||||
, HTTPSServer = require( './https' ).Server
|
||||
, fs = require( 'fs' );
|
||||
|
||||
// node patches
|
||||
|
||||
require('./patch');
|
||||
require( './patch' );
|
||||
|
||||
// expose createServer() as the module
|
||||
|
||||
|
|
@ -63,12 +62,13 @@ exports.version = '1.8.6';
|
|||
*/
|
||||
|
||||
function createServer() {
|
||||
if ('object' == typeof arguments[0]) {
|
||||
return new HTTPSServer(arguments[0], Array.prototype.slice.call(arguments, 1));
|
||||
} else {
|
||||
return new HTTPServer(Array.prototype.slice.call(arguments));
|
||||
}
|
||||
};
|
||||
if ( 'object' == typeof arguments[0] ) {
|
||||
return new HTTPSServer( arguments[0], Array.prototype.slice.call( arguments, 1 ) );
|
||||
} else {
|
||||
return new HTTPServer( Array.prototype.slice.call( arguments ) );
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
// support connect.createServer()
|
||||
|
||||
|
|
@ -82,22 +82,22 @@ exports.middleware = {};
|
|||
* Auto-load bundled middleware with getters.
|
||||
*/
|
||||
|
||||
fs.readdirSync(__dirname + '/middleware').forEach(function(filename){
|
||||
if (/\.js$/.test(filename)) {
|
||||
var name = filename.substr(0, filename.lastIndexOf('.'));
|
||||
exports.middleware.__defineGetter__(name, function(){
|
||||
return require('./middleware/' + name);
|
||||
});
|
||||
}
|
||||
});
|
||||
fs.readdirSync( __dirname + '/middleware' ).forEach( function ( filename ) {
|
||||
if ( /\.js$/.test( filename ) ) {
|
||||
var name = filename.substr( 0, filename.lastIndexOf( '.' ) );
|
||||
exports.middleware.__defineGetter__( name, function () {
|
||||
return require( './middleware/' + name );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
// expose utils
|
||||
|
||||
exports.utils = require('./utils');
|
||||
exports.utils = require( './utils' );
|
||||
|
||||
// expose getters as first-class exports
|
||||
|
||||
exports.utils.merge(exports, exports.middleware);
|
||||
exports.utils.merge( exports, exports.middleware );
|
||||
|
||||
// expose constructors
|
||||
|
||||
|
|
|
|||
236
example/node/node_modules/express/node_modules/connect/lib/http.js
generated
vendored
236
example/node/node_modules/express/node_modules/connect/lib/http.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - HTTPServer
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,9 +9,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, parse = require('url').parse
|
||||
, assert = require('assert');
|
||||
var http = require( 'http' )
|
||||
, parse = require( 'url' ).parse
|
||||
, assert = require( 'assert' );
|
||||
|
||||
// environment
|
||||
|
||||
|
|
@ -29,17 +28,17 @@ var env = process.env.NODE_ENV || 'development';
|
|||
* , connect.static(__dirname + '/public')
|
||||
* );
|
||||
*
|
||||
* @params {Array} middleware
|
||||
* @params {Array} middleware
|
||||
* @return {Server}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var Server = exports.Server = function HTTPServer(middleware) {
|
||||
this.stack = [];
|
||||
middleware.forEach(function(fn){
|
||||
this.use(fn);
|
||||
}, this);
|
||||
http.Server.call(this, this.handle);
|
||||
var Server = exports.Server = function HTTPServer( middleware ) {
|
||||
this.stack = [];
|
||||
middleware.forEach( function ( fn ) {
|
||||
this.use( fn );
|
||||
}, this );
|
||||
http.Server.call( this, this.handle );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -88,39 +87,39 @@ Server.prototype.__proto__ = http.Server.prototype;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
Server.prototype.use = function(route, handle){
|
||||
this.route = '/';
|
||||
Server.prototype.use = function ( route, handle ) {
|
||||
this.route = '/';
|
||||
|
||||
// default route to '/'
|
||||
if ('string' != typeof route) {
|
||||
handle = route;
|
||||
route = '/';
|
||||
}
|
||||
// default route to '/'
|
||||
if ( 'string' != typeof route ) {
|
||||
handle = route;
|
||||
route = '/';
|
||||
}
|
||||
|
||||
// wrap sub-apps
|
||||
if ('function' == typeof handle.handle) {
|
||||
var server = handle;
|
||||
server.route = route;
|
||||
handle = function(req, res, next) {
|
||||
server.handle(req, res, next);
|
||||
};
|
||||
}
|
||||
// wrap sub-apps
|
||||
if ( 'function' == typeof handle.handle ) {
|
||||
var server = handle;
|
||||
server.route = route;
|
||||
handle = function ( req, res, next ) {
|
||||
server.handle( req, res, next );
|
||||
};
|
||||
}
|
||||
|
||||
// wrap vanilla http.Servers
|
||||
if (handle instanceof http.Server) {
|
||||
handle = handle.listeners('request')[0];
|
||||
}
|
||||
// wrap vanilla http.Servers
|
||||
if ( handle instanceof http.Server ) {
|
||||
handle = handle.listeners( 'request' )[0];
|
||||
}
|
||||
|
||||
// normalize route to not trail with slash
|
||||
if ('/' == route[route.length - 1]) {
|
||||
route = route.substr(0, route.length - 1);
|
||||
}
|
||||
// normalize route to not trail with slash
|
||||
if ( '/' == route[route.length - 1] ) {
|
||||
route = route.substr( 0, route.length - 1 );
|
||||
}
|
||||
|
||||
// add the middleware
|
||||
this.stack.push({ route: route, handle: handle });
|
||||
// add the middleware
|
||||
this.stack.push( { route : route, handle : handle } );
|
||||
|
||||
// allow chaining
|
||||
return this;
|
||||
// allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -130,88 +129,107 @@ Server.prototype.use = function(route, handle){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
Server.prototype.handle = function(req, res, out) {
|
||||
var writeHead = res.writeHead
|
||||
, stack = this.stack
|
||||
, removed = ''
|
||||
, index = 0;
|
||||
Server.prototype.handle = function ( req, res, out ) {
|
||||
var writeHead = res.writeHead
|
||||
, stack = this.stack
|
||||
, removed = ''
|
||||
, index = 0;
|
||||
|
||||
function next(err) {
|
||||
var layer, path, c;
|
||||
req.url = removed + req.url;
|
||||
req.originalUrl = req.originalUrl || req.url;
|
||||
removed = '';
|
||||
function next( err ) {
|
||||
var layer, path, c;
|
||||
req.url = removed + req.url;
|
||||
req.originalUrl = req.originalUrl || req.url;
|
||||
removed = '';
|
||||
|
||||
layer = stack[index++];
|
||||
layer = stack[index++];
|
||||
|
||||
// all done
|
||||
if (!layer || res.headerSent) {
|
||||
// but wait! we have a parent
|
||||
if (out) return out(err);
|
||||
// all done
|
||||
if ( !layer || res.headerSent ) {
|
||||
// but wait! we have a parent
|
||||
if ( out ) {
|
||||
return out( err );
|
||||
}
|
||||
|
||||
// error
|
||||
if (err) {
|
||||
var msg = 'production' == env
|
||||
? 'Internal Server Error'
|
||||
: err.stack || err.toString();
|
||||
// error
|
||||
if ( err ) {
|
||||
var msg = 'production' == env
|
||||
? 'Internal Server Error'
|
||||
: err.stack || err.toString();
|
||||
|
||||
// output to stderr in a non-test env
|
||||
if ('test' != env) console.error(err.stack || err.toString());
|
||||
// output to stderr in a non-test env
|
||||
if ( 'test' != env ) {
|
||||
console.error( err.stack || err.toString() );
|
||||
}
|
||||
|
||||
// unable to respond
|
||||
if (res.headerSent) return req.socket.destroy();
|
||||
// unable to respond
|
||||
if ( res.headerSent ) {
|
||||
return req.socket.destroy();
|
||||
}
|
||||
|
||||
res.statusCode = 500;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
res.end(msg);
|
||||
} else {
|
||||
res.statusCode = 404;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
res.end('Cannot ' + req.method + ' ' + req.url);
|
||||
}
|
||||
return;
|
||||
}
|
||||
res.statusCode = 500;
|
||||
res.setHeader( 'Content-Type', 'text/plain' );
|
||||
if ( 'HEAD' == req.method ) {
|
||||
return res.end();
|
||||
}
|
||||
res.end( msg );
|
||||
} else {
|
||||
res.statusCode = 404;
|
||||
res.setHeader( 'Content-Type', 'text/plain' );
|
||||
if ( 'HEAD' == req.method ) {
|
||||
return res.end();
|
||||
}
|
||||
res.end( 'Cannot ' + req.method + ' ' + req.url );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
path = parse(req.url).pathname;
|
||||
if (undefined == path) path = '/';
|
||||
try {
|
||||
path = parse( req.url ).pathname;
|
||||
if ( undefined == path ) {
|
||||
path = '/';
|
||||
}
|
||||
|
||||
// skip this layer if the route doesn't match.
|
||||
if (0 != path.indexOf(layer.route)) return next(err);
|
||||
// skip this layer if the route doesn't match.
|
||||
if ( 0 != path.indexOf( layer.route ) ) {
|
||||
return next( err );
|
||||
}
|
||||
|
||||
c = path[layer.route.length];
|
||||
if (c && '/' != c && '.' != c) return next(err);
|
||||
c = path[layer.route.length];
|
||||
if ( c && '/' != c && '.' != c ) {
|
||||
return next( err );
|
||||
}
|
||||
|
||||
// Call the layer handler
|
||||
// Trim off the part of the url that matches the route
|
||||
removed = layer.route;
|
||||
req.url = req.url.substr(removed.length);
|
||||
// Call the layer handler
|
||||
// Trim off the part of the url that matches the route
|
||||
removed = layer.route;
|
||||
req.url = req.url.substr( removed.length );
|
||||
|
||||
// Ensure leading slash
|
||||
if ('/' != req.url[0]) req.url = '/' + req.url;
|
||||
// Ensure leading slash
|
||||
if ( '/' != req.url[0] ) {
|
||||
req.url = '/' + req.url;
|
||||
}
|
||||
|
||||
var arity = layer.handle.length;
|
||||
if (err) {
|
||||
if (arity === 4) {
|
||||
layer.handle(err, req, res, next);
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} else if (arity < 4) {
|
||||
layer.handle(req, res, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof assert.AssertionError) {
|
||||
console.error(e.stack + '\n');
|
||||
next(e);
|
||||
} else {
|
||||
next(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
next();
|
||||
var arity = layer.handle.length;
|
||||
if ( err ) {
|
||||
if ( arity === 4 ) {
|
||||
layer.handle( err, req, res, next );
|
||||
} else {
|
||||
next( err );
|
||||
}
|
||||
} else if ( arity < 4 ) {
|
||||
layer.handle( req, res, next );
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} catch ( e ) {
|
||||
if ( e instanceof assert.AssertionError ) {
|
||||
console.error( e.stack + '\n' );
|
||||
next( e );
|
||||
} else {
|
||||
next( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
23
example/node/node_modules/express/node_modules/connect/lib/https.js
generated
vendored
23
example/node/node_modules/express/node_modules/connect/lib/https.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - HTTPServer
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,8 +9,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var HTTPServer = require('./http').Server
|
||||
, https = require('https');
|
||||
var HTTPServer = require( './http' ).Server
|
||||
, https = require( 'https' );
|
||||
|
||||
/**
|
||||
* Initialize a new `Server` with the given
|
||||
|
|
@ -26,12 +25,12 @@ var HTTPServer = require('./http').Server
|
|||
* @api public
|
||||
*/
|
||||
|
||||
var Server = exports.Server = function HTTPSServer(options, middleware) {
|
||||
this.stack = [];
|
||||
middleware.forEach(function(fn){
|
||||
this.use(fn);
|
||||
}, this);
|
||||
https.Server.call(this, options, this.handle);
|
||||
var Server = exports.Server = function HTTPSServer( options, middleware ) {
|
||||
this.stack = [];
|
||||
middleware.forEach( function ( fn ) {
|
||||
this.use( fn );
|
||||
}, this );
|
||||
https.Server.call( this, options, this.handle );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -42,6 +41,6 @@ Server.prototype.__proto__ = https.Server.prototype;
|
|||
|
||||
// mixin HTTPServer methods
|
||||
|
||||
Object.keys(HTTPServer.prototype).forEach(function(method){
|
||||
Server.prototype[method] = HTTPServer.prototype[method];
|
||||
});
|
||||
Object.keys( HTTPServer.prototype ).forEach( function ( method ) {
|
||||
Server.prototype[method] = HTTPServer.prototype[method];
|
||||
} );
|
||||
5
example/node/node_modules/express/node_modules/connect/lib/index.js
generated
vendored
5
example/node/node_modules/express/node_modules/connect/lib/index.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/**
|
||||
* # Connect
|
||||
*
|
||||
|
|
@ -7,9 +6,9 @@
|
|||
* [3rd-party middleware](https://github.com/senchalabs/connect/wiki).
|
||||
*
|
||||
* Installation:
|
||||
*
|
||||
*
|
||||
* $ npm install connect
|
||||
*
|
||||
*
|
||||
* API:
|
||||
*
|
||||
* - [connect](connect.html) general
|
||||
|
|
|
|||
97
example/node/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
97
example/node/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - basicAuth
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,9 +9,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, unauthorized = utils.unauthorized
|
||||
, badRequest = utils.badRequest;
|
||||
var utils = require( '../utils' )
|
||||
, unauthorized = utils.unauthorized
|
||||
, badRequest = utils.badRequest;
|
||||
|
||||
/**
|
||||
* Enfore basic authentication by providing a `callback(user, pass)`,
|
||||
|
|
@ -42,52 +41,62 @@ var utils = require('../utils')
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function basicAuth(callback, realm) {
|
||||
var username, password;
|
||||
module.exports = function basicAuth( callback, realm ) {
|
||||
var username, password;
|
||||
|
||||
// user / pass strings
|
||||
if ('string' == typeof callback) {
|
||||
username = callback;
|
||||
password = realm;
|
||||
if ('string' != typeof password) throw new Error('password argument required');
|
||||
realm = arguments[2];
|
||||
callback = function(user, pass){
|
||||
return user == username && pass == password;
|
||||
}
|
||||
}
|
||||
// user / pass strings
|
||||
if ( 'string' == typeof callback ) {
|
||||
username = callback;
|
||||
password = realm;
|
||||
if ( 'string' != typeof password ) {
|
||||
throw new Error( 'password argument required' );
|
||||
}
|
||||
realm = arguments[2];
|
||||
callback = function ( user, pass ) {
|
||||
return user == username && pass == password;
|
||||
}
|
||||
}
|
||||
|
||||
realm = realm || 'Authorization Required';
|
||||
realm = realm || 'Authorization Required';
|
||||
|
||||
return function(req, res, next) {
|
||||
var authorization = req.headers.authorization;
|
||||
return function ( req, res, next ) {
|
||||
var authorization = req.headers.authorization;
|
||||
|
||||
if (req.remoteUser) return next();
|
||||
if (!authorization) return unauthorized(res, realm);
|
||||
if ( req.remoteUser ) {
|
||||
return next();
|
||||
}
|
||||
if ( !authorization ) {
|
||||
return unauthorized( res, realm );
|
||||
}
|
||||
|
||||
var parts = authorization.split(' ')
|
||||
, scheme = parts[0]
|
||||
, credentials = new Buffer(parts[1], 'base64').toString().split(':');
|
||||
var parts = authorization.split( ' ' )
|
||||
, scheme = parts[0]
|
||||
, credentials = new Buffer( parts[1], 'base64' ).toString().split( ':' );
|
||||
|
||||
if ('Basic' != scheme) return badRequest(res);
|
||||
if ( 'Basic' != scheme ) {
|
||||
return badRequest( res );
|
||||
}
|
||||
|
||||
// async
|
||||
if (callback.length >= 3) {
|
||||
var pause = utils.pause(req);
|
||||
callback(credentials[0], credentials[1], function(err, user){
|
||||
if (err || !user) return unauthorized(res, realm);
|
||||
req.remoteUser = user;
|
||||
next();
|
||||
pause.resume();
|
||||
});
|
||||
// sync
|
||||
} else {
|
||||
if (callback(credentials[0], credentials[1])) {
|
||||
req.remoteUser = credentials[0];
|
||||
next();
|
||||
} else {
|
||||
unauthorized(res, realm);
|
||||
}
|
||||
}
|
||||
}
|
||||
// async
|
||||
if ( callback.length >= 3 ) {
|
||||
var pause = utils.pause( req );
|
||||
callback( credentials[0], credentials[1], function ( err, user ) {
|
||||
if ( err || !user ) {
|
||||
return unauthorized( res, realm );
|
||||
}
|
||||
req.remoteUser = user;
|
||||
next();
|
||||
pause.resume();
|
||||
} );
|
||||
// sync
|
||||
} else {
|
||||
if ( callback( credentials[0], credentials[1] ) ) {
|
||||
req.remoteUser = credentials[0];
|
||||
next();
|
||||
} else {
|
||||
unauthorized( res, realm );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
181
example/node/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
181
example/node/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - bodyParser
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,8 +9,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var qs = require('qs')
|
||||
, formidable = require('formidable');
|
||||
var qs = require( 'qs' )
|
||||
, formidable = require( 'formidable' );
|
||||
|
||||
/**
|
||||
* Extract the mime type from the given request's
|
||||
|
|
@ -22,9 +21,9 @@ var qs = require('qs')
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function mime(req) {
|
||||
var str = req.headers['content-type'] || '';
|
||||
return str.split(';')[0];
|
||||
function mime( req ) {
|
||||
var str = req.headers['content-type'] || '';
|
||||
return str.split( ';' )[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +65,7 @@ function mime(req) {
|
|||
*
|
||||
* If you wish to use formidable directly within your app, and do not
|
||||
* desire this behaviour for multipart requests simply remove the
|
||||
* parser:
|
||||
* parser:
|
||||
*
|
||||
* delete connect.bodyParser.parse['multipart/form-data'];
|
||||
*
|
||||
|
|
@ -79,20 +78,24 @@ function mime(req) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function bodyParser(options){
|
||||
options = options || {};
|
||||
return function bodyParser(req, res, next) {
|
||||
if (req.body) return next();
|
||||
req.body = {};
|
||||
exports = module.exports = function bodyParser( options ) {
|
||||
options = options || {};
|
||||
return function bodyParser( req, res, next ) {
|
||||
if ( req.body ) {
|
||||
return next();
|
||||
}
|
||||
req.body = {};
|
||||
|
||||
if ('GET' == req.method || 'HEAD' == req.method) return next();
|
||||
var parser = exports.parse[mime(req)];
|
||||
if (parser) {
|
||||
parser(req, options, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
if ( 'GET' == req.method || 'HEAD' == req.method ) {
|
||||
return next();
|
||||
}
|
||||
var parser = exports.parse[mime( req )];
|
||||
if ( parser ) {
|
||||
parser( req, options, next );
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -105,40 +108,44 @@ exports.parse = {};
|
|||
* Parse application/x-www-form-urlencoded.
|
||||
*/
|
||||
|
||||
exports.parse['application/x-www-form-urlencoded'] = function(req, options, fn){
|
||||
var buf = '';
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', function(chunk){ buf += chunk });
|
||||
req.on('end', function(){
|
||||
try {
|
||||
req.body = buf.length
|
||||
? qs.parse(buf)
|
||||
: {};
|
||||
fn();
|
||||
} catch (err){
|
||||
fn(err);
|
||||
}
|
||||
});
|
||||
exports.parse['application/x-www-form-urlencoded'] = function ( req, options, fn ) {
|
||||
var buf = '';
|
||||
req.setEncoding( 'utf8' );
|
||||
req.on( 'data', function ( chunk ) {
|
||||
buf += chunk
|
||||
} );
|
||||
req.on( 'end', function () {
|
||||
try {
|
||||
req.body = buf.length
|
||||
? qs.parse( buf )
|
||||
: {};
|
||||
fn();
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse application/json.
|
||||
*/
|
||||
|
||||
exports.parse['application/json'] = function(req, options, fn){
|
||||
var buf = '';
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', function(chunk){ buf += chunk });
|
||||
req.on('end', function(){
|
||||
try {
|
||||
req.body = buf.length
|
||||
? JSON.parse(buf)
|
||||
: {};
|
||||
fn();
|
||||
} catch (err){
|
||||
fn(err);
|
||||
}
|
||||
});
|
||||
exports.parse['application/json'] = function ( req, options, fn ) {
|
||||
var buf = '';
|
||||
req.setEncoding( 'utf8' );
|
||||
req.on( 'data', function ( chunk ) {
|
||||
buf += chunk
|
||||
} );
|
||||
req.on( 'end', function () {
|
||||
try {
|
||||
req.body = buf.length
|
||||
? JSON.parse( buf )
|
||||
: {};
|
||||
fn();
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -148,49 +155,51 @@ exports.parse['application/json'] = function(req, options, fn){
|
|||
* TODO: revisit "error" flag if it's a formidable bug
|
||||
*/
|
||||
|
||||
exports.parse['multipart/form-data'] = function(req, options, fn){
|
||||
var form = new formidable.IncomingForm
|
||||
, data = {}
|
||||
, files = {}
|
||||
, done;
|
||||
exports.parse['multipart/form-data'] = function ( req, options, fn ) {
|
||||
var form = new formidable.IncomingForm
|
||||
, data = {}
|
||||
, files = {}
|
||||
, done;
|
||||
|
||||
Object.keys(options).forEach(function(key){
|
||||
form[key] = options[key];
|
||||
});
|
||||
Object.keys( options ).forEach( function ( key ) {
|
||||
form[key] = options[key];
|
||||
} );
|
||||
|
||||
function ondata(name, val, data){
|
||||
if (Array.isArray(data[name])) {
|
||||
data[name].push(val);
|
||||
} else if (data[name]) {
|
||||
data[name] = [data[name], val];
|
||||
} else {
|
||||
data[name] = val;
|
||||
}
|
||||
}
|
||||
function ondata( name, val, data ) {
|
||||
if ( Array.isArray( data[name] ) ) {
|
||||
data[name].push( val );
|
||||
} else if ( data[name] ) {
|
||||
data[name] = [data[name], val];
|
||||
} else {
|
||||
data[name] = val;
|
||||
}
|
||||
}
|
||||
|
||||
form.on('field', function(name, val){
|
||||
ondata(name, val, data);
|
||||
});
|
||||
form.on( 'field', function ( name, val ) {
|
||||
ondata( name, val, data );
|
||||
} );
|
||||
|
||||
form.on('file', function(name, val){
|
||||
ondata(name, val, files);
|
||||
});
|
||||
form.on( 'file', function ( name, val ) {
|
||||
ondata( name, val, files );
|
||||
} );
|
||||
|
||||
form.on('error', function(err){
|
||||
fn(err);
|
||||
done = true;
|
||||
});
|
||||
form.on( 'error', function ( err ) {
|
||||
fn( err );
|
||||
done = true;
|
||||
} );
|
||||
|
||||
form.on('end', function(){
|
||||
if (done) return;
|
||||
try {
|
||||
req.body = qs.parse(data);
|
||||
req.files = qs.parse(files);
|
||||
fn();
|
||||
} catch (err) {
|
||||
fn(err);
|
||||
}
|
||||
});
|
||||
form.on( 'end', function () {
|
||||
if ( done ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
req.body = qs.parse( data );
|
||||
req.files = qs.parse( files );
|
||||
fn();
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
} );
|
||||
|
||||
form.parse(req);
|
||||
form.parse( req );
|
||||
};
|
||||
220
example/node/node_modules/express/node_modules/connect/lib/middleware/compiler.js
generated
vendored
220
example/node/node_modules/express/node_modules/connect/lib/middleware/compiler.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - compiler
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,9 +9,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, path = require('path')
|
||||
, parse = require('url').parse;
|
||||
var fs = require( 'fs' )
|
||||
, path = require( 'path' )
|
||||
, parse = require( 'url' ).parse;
|
||||
|
||||
/**
|
||||
* Require cache.
|
||||
|
|
@ -39,80 +38,83 @@ var cache = {};
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function compiler(options){
|
||||
options = options || {};
|
||||
exports = module.exports = function compiler( options ) {
|
||||
options = options || {};
|
||||
|
||||
var srcDir = options.src || process.cwd()
|
||||
, destDir = options.dest || srcDir
|
||||
, enable = options.enable;
|
||||
var srcDir = options.src || process.cwd()
|
||||
, destDir = options.dest || srcDir
|
||||
, enable = options.enable;
|
||||
|
||||
if (!enable || enable.length === 0) {
|
||||
throw new Error('compiler\'s "enable" option is not set, nothing will be compiled.');
|
||||
}
|
||||
if ( !enable || enable.length === 0 ) {
|
||||
throw new Error( 'compiler\'s "enable" option is not set, nothing will be compiled.' );
|
||||
}
|
||||
|
||||
return function compiler(req, res, next){
|
||||
if ('GET' != req.method) return next();
|
||||
var pathname = parse(req.url).pathname;
|
||||
for (var i = 0, len = enable.length; i < len; ++i) {
|
||||
var name = enable[i]
|
||||
, compiler = compilers[name];
|
||||
if (compiler.match.test(pathname)) {
|
||||
var src = (srcDir + pathname).replace(compiler.match, compiler.ext)
|
||||
, dest = destDir + pathname;
|
||||
return function compiler( req, res, next ) {
|
||||
if ( 'GET' != req.method ) {
|
||||
return next();
|
||||
}
|
||||
var pathname = parse( req.url ).pathname;
|
||||
for ( var i = 0, len = enable.length; i < len; ++i ) {
|
||||
var name = enable[i]
|
||||
, compiler = compilers[name];
|
||||
if ( compiler.match.test( pathname ) ) {
|
||||
var src = (srcDir + pathname).replace( compiler.match, compiler.ext )
|
||||
, dest = destDir + pathname;
|
||||
|
||||
// Compare mtimes
|
||||
fs.stat(src, function(err, srcStats){
|
||||
if (err) {
|
||||
if ('ENOENT' == err.code) {
|
||||
next();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} else {
|
||||
fs.stat(dest, function(err, destStats){
|
||||
if (err) {
|
||||
// Oh snap! it does not exist, compile it
|
||||
if ('ENOENT' == err.code) {
|
||||
compile();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} else {
|
||||
// Source has changed, compile it
|
||||
if (srcStats.mtime > destStats.mtime) {
|
||||
compile();
|
||||
} else {
|
||||
// Defer file serving
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Compare mtimes
|
||||
fs.stat( src, function ( err, srcStats ) {
|
||||
if ( err ) {
|
||||
if ( 'ENOENT' == err.code ) {
|
||||
next();
|
||||
} else {
|
||||
next( err );
|
||||
}
|
||||
} else {
|
||||
fs.stat( dest, function ( err, destStats ) {
|
||||
if ( err ) {
|
||||
// Oh snap! it does not exist, compile it
|
||||
if ( 'ENOENT' == err.code ) {
|
||||
compile();
|
||||
} else {
|
||||
next( err );
|
||||
}
|
||||
} else {
|
||||
// Source has changed, compile it
|
||||
if ( srcStats.mtime > destStats.mtime ) {
|
||||
compile();
|
||||
} else {
|
||||
// Defer file serving
|
||||
next();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
// Compile to the destination
|
||||
function compile() {
|
||||
fs.readFile(src, 'utf8', function(err, str){
|
||||
if (err) {
|
||||
next(err);
|
||||
} else {
|
||||
compiler.compile(str, function(err, str){
|
||||
if (err) {
|
||||
next(err);
|
||||
} else {
|
||||
fs.writeFile(dest, str, 'utf8', function(err){
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
// Compile to the destination
|
||||
function compile() {
|
||||
fs.readFile( src, 'utf8', function ( err, str ) {
|
||||
if ( err ) {
|
||||
next( err );
|
||||
} else {
|
||||
compiler.compile( str, function ( err, str ) {
|
||||
if ( err ) {
|
||||
next( err );
|
||||
} else {
|
||||
fs.writeFile( dest, str, 'utf8', function ( err ) {
|
||||
next( err );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -124,40 +126,40 @@ exports = module.exports = function compiler(options){
|
|||
*/
|
||||
|
||||
var compilers = exports.compilers = {
|
||||
sass: {
|
||||
match: /\.css$/,
|
||||
ext: '.sass',
|
||||
compile: function(str, fn){
|
||||
var sass = cache.sass || (cache.sass = require('sass'));
|
||||
try {
|
||||
fn(null, sass.render(str));
|
||||
} catch (err) {
|
||||
fn(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
less: {
|
||||
match: /\.css$/,
|
||||
ext: '.less',
|
||||
compile: function(str, fn){
|
||||
var less = cache.less || (cache.less = require('less'));
|
||||
try {
|
||||
less.render(str, fn);
|
||||
} catch (err) {
|
||||
fn(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
coffeescript: {
|
||||
match: /\.js$/,
|
||||
ext: '.coffee',
|
||||
compile: function(str, fn){
|
||||
var coffee = cache.coffee || (cache.coffee = require('coffee-script'));
|
||||
try {
|
||||
fn(null, coffee.compile(str));
|
||||
} catch (err) {
|
||||
fn(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
sass : {
|
||||
match : /\.css$/,
|
||||
ext : '.sass',
|
||||
compile : function ( str, fn ) {
|
||||
var sass = cache.sass || (cache.sass = require( 'sass' ));
|
||||
try {
|
||||
fn( null, sass.render( str ) );
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
}
|
||||
},
|
||||
less : {
|
||||
match : /\.css$/,
|
||||
ext : '.less',
|
||||
compile : function ( str, fn ) {
|
||||
var less = cache.less || (cache.less = require( 'less' ));
|
||||
try {
|
||||
less.render( str, fn );
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
}
|
||||
},
|
||||
coffeescript : {
|
||||
match : /\.js$/,
|
||||
ext : '.coffee',
|
||||
compile : function ( str, fn ) {
|
||||
var coffee = cache.coffee || (cache.coffee = require( 'coffee-script' ));
|
||||
try {
|
||||
fn( null, coffee.compile( str ) );
|
||||
} catch ( err ) {
|
||||
fn( err );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
33
example/node/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
33
example/node/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - cookieParser
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,7 +9,7 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./../utils');
|
||||
var utils = require( './../utils' );
|
||||
|
||||
/**
|
||||
* Parse _Cookie_ header and populate `req.cookies`
|
||||
|
|
@ -29,18 +28,20 @@ var utils = require('./../utils');
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function cookieParser(){
|
||||
return function cookieParser(req, res, next) {
|
||||
var cookie = req.headers.cookie;
|
||||
if (req.cookies) return next();
|
||||
req.cookies = {};
|
||||
if (cookie) {
|
||||
try {
|
||||
req.cookies = utils.parseCookie(cookie);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
module.exports = function cookieParser() {
|
||||
return function cookieParser( req, res, next ) {
|
||||
var cookie = req.headers.cookie;
|
||||
if ( req.cookies ) {
|
||||
return next();
|
||||
}
|
||||
req.cookies = {};
|
||||
if ( cookie ) {
|
||||
try {
|
||||
req.cookies = utils.parseCookie( cookie );
|
||||
} catch ( err ) {
|
||||
return next( err );
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
||||
57
example/node/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
57
example/node/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - csrf
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
|
|
@ -9,8 +8,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, crypto = require('crypto');
|
||||
var utils = require( '../utils' )
|
||||
, crypto = require( 'crypto' );
|
||||
|
||||
/**
|
||||
* CRSF protection middleware.
|
||||
|
|
@ -37,20 +36,20 @@ var utils = require('../utils')
|
|||
* <input type="password" name="user[pass]" />\n\
|
||||
* <input type="submit" value="Login" />\n\
|
||||
* </form>\n\
|
||||
* ';
|
||||
*
|
||||
* ';
|
||||
*
|
||||
* connect(
|
||||
* connect.cookieParser()
|
||||
* , connect.session({ secret: 'keyboard cat' })
|
||||
* , connect.bodyParser()
|
||||
* , connect.csrf()
|
||||
*
|
||||
*
|
||||
* , function(req, res, next){
|
||||
* if ('POST' != req.method) return next();
|
||||
* req.session.user = req.body.user;
|
||||
* next();
|
||||
* }
|
||||
*
|
||||
*
|
||||
* , function(req, res){
|
||||
* res.setHeader('Content-Type', 'text/html');
|
||||
* var body = form
|
||||
|
|
@ -62,31 +61,35 @@ var utils = require('../utils')
|
|||
*
|
||||
* Options:
|
||||
*
|
||||
* - `value` a function accepting the request, returning the token
|
||||
* - `value` a function accepting the request, returning the token
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function csrf(options) {
|
||||
var options = options || {}
|
||||
, value = options.value || defaultValue;
|
||||
module.exports = function csrf( options ) {
|
||||
var options = options || {}
|
||||
, value = options.value || defaultValue;
|
||||
|
||||
return function(req, res, next){
|
||||
// generate CSRF token
|
||||
var token = req.session._csrf || (req.session._csrf = utils.uid(24));
|
||||
return function ( req, res, next ) {
|
||||
// generate CSRF token
|
||||
var token = req.session._csrf || (req.session._csrf = utils.uid( 24 ));
|
||||
|
||||
// ignore GET (for now)
|
||||
if ('GET' == req.method) return next();
|
||||
// ignore GET (for now)
|
||||
if ( 'GET' == req.method ) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// determine value
|
||||
var val = value(req);
|
||||
// determine value
|
||||
var val = value( req );
|
||||
|
||||
// check
|
||||
if (val != token) return utils.forbidden(res);
|
||||
|
||||
next();
|
||||
}
|
||||
// check
|
||||
if ( val != token ) {
|
||||
return utils.forbidden( res );
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -98,8 +101,8 @@ module.exports = function csrf(options) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function defaultValue(req) {
|
||||
return (req.body && req.body._csrf)
|
||||
|| (req.query && req.query._csrf)
|
||||
|| (req.headers['x-csrf-token']);
|
||||
function defaultValue( req ) {
|
||||
return (req.body && req.body._csrf)
|
||||
|| (req.query && req.query._csrf)
|
||||
|| (req.headers['x-csrf-token']);
|
||||
}
|
||||
248
example/node/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
248
example/node/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - directory
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
|
|
@ -14,13 +13,13 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, parse = require('url').parse
|
||||
, utils = require('../utils')
|
||||
, path = require('path')
|
||||
, normalize = path.normalize
|
||||
, extname = path.extname
|
||||
, join = path.join;
|
||||
var fs = require( 'fs' )
|
||||
, parse = require( 'url' ).parse
|
||||
, utils = require( '../utils' )
|
||||
, path = require( 'path' )
|
||||
, normalize = path.normalize
|
||||
, extname = path.extname
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
* Icon cache.
|
||||
|
|
@ -43,137 +42,161 @@ var cache = {};
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function directory(root, options){
|
||||
options = options || {};
|
||||
exports = module.exports = function directory( root, options ) {
|
||||
options = options || {};
|
||||
|
||||
// root required
|
||||
if (!root) throw new Error('directory() root path required');
|
||||
var hidden = options.hidden
|
||||
, icons = options.icons
|
||||
, filter = options.filter
|
||||
, root = normalize(root);
|
||||
// root required
|
||||
if ( !root ) {
|
||||
throw new Error( 'directory() root path required' );
|
||||
}
|
||||
var hidden = options.hidden
|
||||
, icons = options.icons
|
||||
, filter = options.filter
|
||||
, root = normalize( root );
|
||||
|
||||
return function directory(req, res, next) {
|
||||
var accept = req.headers.accept || 'text/plain'
|
||||
, url = parse(req.url)
|
||||
, dir = decodeURIComponent(url.pathname)
|
||||
, path = normalize(join(root, dir))
|
||||
, originalUrl = parse(req.originalUrl)
|
||||
, originalDir = decodeURIComponent(originalUrl.pathname)
|
||||
, showUp = path != root && path != root + '/';
|
||||
return function directory( req, res, next ) {
|
||||
var accept = req.headers.accept || 'text/plain'
|
||||
, url = parse( req.url )
|
||||
, dir = decodeURIComponent( url.pathname )
|
||||
, path = normalize( join( root, dir ) )
|
||||
, originalUrl = parse( req.originalUrl )
|
||||
, originalDir = decodeURIComponent( originalUrl.pathname )
|
||||
, showUp = path != root && path != root + '/';
|
||||
|
||||
// null byte(s)
|
||||
if (~path.indexOf('\0')) return utils.badRequest(res);
|
||||
// null byte(s)
|
||||
if ( ~path.indexOf( '\0' ) ) {
|
||||
return utils.badRequest( res );
|
||||
}
|
||||
|
||||
// malicious path
|
||||
if (0 != path.indexOf(root)) return utils.forbidden(res);
|
||||
// malicious path
|
||||
if ( 0 != path.indexOf( root ) ) {
|
||||
return utils.forbidden( res );
|
||||
}
|
||||
|
||||
// check if we have a directory
|
||||
fs.stat(path, function(err, stat){
|
||||
if (err) return 'ENOENT' == err.code
|
||||
? next()
|
||||
: next(err);
|
||||
// check if we have a directory
|
||||
fs.stat( path, function ( err, stat ) {
|
||||
if ( err ) {
|
||||
return 'ENOENT' == err.code
|
||||
? next()
|
||||
: next( err );
|
||||
}
|
||||
|
||||
if (!stat.isDirectory()) return next();
|
||||
if ( !stat.isDirectory() ) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// fetch files
|
||||
fs.readdir(path, function(err, files){
|
||||
if (err) return next(err);
|
||||
if (!hidden) files = removeHidden(files);
|
||||
if (filter) files = files.filter(filter);
|
||||
files.sort();
|
||||
// content-negotiation
|
||||
for (var key in exports) {
|
||||
if (~accept.indexOf(key) || ~accept.indexOf('*/*')) {
|
||||
exports[key](req, res, files, next, originalDir, showUp, icons);
|
||||
return;
|
||||
}
|
||||
}
|
||||
utils.notAcceptable(res);
|
||||
});
|
||||
});
|
||||
};
|
||||
// fetch files
|
||||
fs.readdir( path, function ( err, files ) {
|
||||
if ( err ) {
|
||||
return next( err );
|
||||
}
|
||||
if ( !hidden ) {
|
||||
files = removeHidden( files );
|
||||
}
|
||||
if ( filter ) {
|
||||
files = files.filter( filter );
|
||||
}
|
||||
files.sort();
|
||||
// content-negotiation
|
||||
for ( var key in exports ) {
|
||||
if ( ~accept.indexOf( key ) || ~accept.indexOf( '*/*' ) ) {
|
||||
exports[key]( req, res, files, next, originalDir, showUp, icons );
|
||||
return;
|
||||
}
|
||||
}
|
||||
utils.notAcceptable( res );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with text/html.
|
||||
*/
|
||||
|
||||
exports.html = function(req, res, files, next, dir, showUp, icons){
|
||||
fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){
|
||||
if (err) return next(err);
|
||||
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){
|
||||
if (err) return next(err);
|
||||
if (showUp) files.unshift('..');
|
||||
str = str
|
||||
.replace('{style}', style)
|
||||
.replace('{files}', html(files, dir, icons))
|
||||
.replace('{directory}', dir)
|
||||
.replace('{linked-path}', htmlPath(dir));
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader('Content-Length', str.length);
|
||||
res.end(str);
|
||||
});
|
||||
});
|
||||
exports.html = function ( req, res, files, next, dir, showUp, icons ) {
|
||||
fs.readFile( __dirname + '/../public/directory.html', 'utf8', function ( err, str ) {
|
||||
if ( err ) {
|
||||
return next( err );
|
||||
}
|
||||
fs.readFile( __dirname + '/../public/style.css', 'utf8', function ( err, style ) {
|
||||
if ( err ) {
|
||||
return next( err );
|
||||
}
|
||||
if ( showUp ) {
|
||||
files.unshift( '..' );
|
||||
}
|
||||
str = str
|
||||
.replace( '{style}', style )
|
||||
.replace( '{files}', html( files, dir, icons ) )
|
||||
.replace( '{directory}', dir )
|
||||
.replace( '{linked-path}', htmlPath( dir ) );
|
||||
res.setHeader( 'Content-Type', 'text/html' );
|
||||
res.setHeader( 'Content-Length', str.length );
|
||||
res.end( str );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with application/json.
|
||||
*/
|
||||
|
||||
exports.json = function(req, res, files){
|
||||
files = JSON.stringify(files);
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.setHeader('Content-Length', files.length);
|
||||
res.end(files);
|
||||
exports.json = function ( req, res, files ) {
|
||||
files = JSON.stringify( files );
|
||||
res.setHeader( 'Content-Type', 'application/json' );
|
||||
res.setHeader( 'Content-Length', files.length );
|
||||
res.end( files );
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with text/plain.
|
||||
*/
|
||||
|
||||
exports.plain = function(req, res, files){
|
||||
files = files.join('\n') + '\n';
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.setHeader('Content-Length', files.length);
|
||||
res.end(files);
|
||||
exports.plain = function ( req, res, files ) {
|
||||
files = files.join( '\n' ) + '\n';
|
||||
res.setHeader( 'Content-Type', 'text/plain' );
|
||||
res.setHeader( 'Content-Length', files.length );
|
||||
res.end( files );
|
||||
};
|
||||
|
||||
/**
|
||||
* Map html `dir`, returning a linked path.
|
||||
*/
|
||||
|
||||
function htmlPath(dir) {
|
||||
var curr = [];
|
||||
return dir.split('/').map(function(part){
|
||||
curr.push(part);
|
||||
return '<a href="' + curr.join('/') + '">' + part + '</a>';
|
||||
}).join(' / ');
|
||||
function htmlPath( dir ) {
|
||||
var curr = [];
|
||||
return dir.split( '/' ).map(
|
||||
function ( part ) {
|
||||
curr.push( part );
|
||||
return '<a href="' + curr.join( '/' ) + '">' + part + '</a>';
|
||||
} ).join( ' / ' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Map html `files`, returning an html unordered list.
|
||||
*/
|
||||
|
||||
function html(files, dir, useIcons) {
|
||||
return '<ul id="files">' + files.map(function(file){
|
||||
var icon = ''
|
||||
, classes = [];
|
||||
function html( files, dir, useIcons ) {
|
||||
return '<ul id="files">' + files.map(
|
||||
function ( file ) {
|
||||
var icon = ''
|
||||
, classes = [];
|
||||
|
||||
if (useIcons && '..' != file) {
|
||||
icon = icons[extname(file)] || icons.default;
|
||||
icon = '<img src="data:image/png;base64,' + load(icon) + '" />';
|
||||
classes.push('icon');
|
||||
}
|
||||
if ( useIcons && '..' != file ) {
|
||||
icon = icons[extname( file )] || icons.default;
|
||||
icon = '<img src="data:image/png;base64,' + load( icon ) + '" />';
|
||||
classes.push( 'icon' );
|
||||
}
|
||||
|
||||
return '<li><a href="'
|
||||
+ join(dir, file)
|
||||
+ '" class="'
|
||||
+ classes.join(' ') + '"'
|
||||
+ ' title="' + file + '">'
|
||||
+ icon + file + '</a></li>';
|
||||
return '<li><a href="'
|
||||
+ join( dir, file )
|
||||
+ '" class="'
|
||||
+ classes.join( ' ' ) + '"'
|
||||
+ ' title="' + file + '">'
|
||||
+ icon + file + '</a></li>';
|
||||
|
||||
}).join('\n') + '</ul>';
|
||||
} ).join( '\n' ) + '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -184,9 +207,11 @@ function html(files, dir, useIcons) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function load(icon) {
|
||||
if (cache[icon]) return cache[icon];
|
||||
return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64');
|
||||
function load( icon ) {
|
||||
if ( cache[icon] ) {
|
||||
return cache[icon];
|
||||
}
|
||||
return cache[icon] = fs.readFileSync( __dirname + '/../public/icons/' + icon, 'base64' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,10 +223,10 @@ function load(icon) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function removeHidden(files) {
|
||||
return files.filter(function(file){
|
||||
return '.' != file[0];
|
||||
});
|
||||
function removeHidden( files ) {
|
||||
return files.filter( function ( file ) {
|
||||
return '.' != file[0];
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,14 +234,5 @@ function removeHidden(files) {
|
|||
*/
|
||||
|
||||
var icons = {
|
||||
'.js': 'page_white_code_red.png'
|
||||
, '.c': 'page_white_c.png'
|
||||
, '.h': 'page_white_h.png'
|
||||
, '.cc': 'page_white_cplusplus.png'
|
||||
, '.php': 'page_white_php.png'
|
||||
, '.rb': 'page_white_ruby.png'
|
||||
, '.cpp': 'page_white_cplusplus.png'
|
||||
, '.swf': 'page_white_flash.png'
|
||||
, '.pdf': 'page_white_acrobat.png'
|
||||
, 'default': 'page_white.png'
|
||||
'.js' : 'page_white_code_red.png', '.c' : 'page_white_c.png', '.h' : 'page_white_h.png', '.cc' : 'page_white_cplusplus.png', '.php' : 'page_white_php.png', '.rb' : 'page_white_ruby.png', '.cpp' : 'page_white_cplusplus.png', '.swf' : 'page_white_flash.png', '.pdf' : 'page_white_acrobat.png', 'default' : 'page_white.png'
|
||||
};
|
||||
|
|
|
|||
105
example/node/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
105
example/node/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
|
|
@ -9,9 +9,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, url = require('url')
|
||||
, fs = require('fs');
|
||||
var utils = require( '../utils' )
|
||||
, url = require( 'url' )
|
||||
, fs = require( 'fs' );
|
||||
|
||||
/**
|
||||
* Flexible error handler, providing (_optional_) stack traces
|
||||
|
|
@ -32,7 +32,7 @@ var utils = require('../utils')
|
|||
* JSON:
|
||||
*
|
||||
* When _application/json_ is accepted, connect will respond with
|
||||
* an object in the form of `{ "error": error }`.
|
||||
* an object in the form of `{ "error": error }`.
|
||||
*
|
||||
* HTML:
|
||||
*
|
||||
|
|
@ -43,54 +43,59 @@ var utils = require('../utils')
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function errorHandler(options){
|
||||
options = options || {};
|
||||
exports = module.exports = function errorHandler( options ) {
|
||||
options = options || {};
|
||||
|
||||
// defaults
|
||||
var showStack = options.showStack || options.stack
|
||||
, showMessage = options.showMessage || options.message
|
||||
, dumpExceptions = options.dumpExceptions || options.dump
|
||||
, formatUrl = options.formatUrl;
|
||||
// defaults
|
||||
var showStack = options.showStack || options.stack
|
||||
, showMessage = options.showMessage || options.message
|
||||
, dumpExceptions = options.dumpExceptions || options.dump
|
||||
, formatUrl = options.formatUrl;
|
||||
|
||||
return function errorHandler(err, req, res, next){
|
||||
res.statusCode = 500;
|
||||
if (dumpExceptions) console.error(err.stack);
|
||||
if (showStack) {
|
||||
var accept = req.headers.accept || '';
|
||||
// html
|
||||
if (~accept.indexOf('html')) {
|
||||
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){
|
||||
fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){
|
||||
var stack = (err.stack || '')
|
||||
.split('\n').slice(1)
|
||||
.map(function(v){ return '<li>' + v + '</li>'; }).join('');
|
||||
html = html
|
||||
.replace('{style}', style)
|
||||
.replace('{stack}', stack)
|
||||
.replace('{title}', exports.title)
|
||||
.replace(/\{error\}/g, utils.escape(err.toString()));
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end(html);
|
||||
});
|
||||
});
|
||||
// json
|
||||
} else if (~accept.indexOf('json')) {
|
||||
var json = JSON.stringify({ error: err });
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(json);
|
||||
// plain text
|
||||
} else {
|
||||
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||
res.end(err.stack);
|
||||
}
|
||||
} else {
|
||||
var body = showMessage
|
||||
? err.toString()
|
||||
: 'Internal Server Error';
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.end(body);
|
||||
}
|
||||
};
|
||||
return function errorHandler( err, req, res, next ) {
|
||||
res.statusCode = 500;
|
||||
if ( dumpExceptions ) {
|
||||
console.error( err.stack );
|
||||
}
|
||||
if ( showStack ) {
|
||||
var accept = req.headers.accept || '';
|
||||
// html
|
||||
if ( ~accept.indexOf( 'html' ) ) {
|
||||
fs.readFile( __dirname + '/../public/style.css', 'utf8', function ( e, style ) {
|
||||
fs.readFile( __dirname + '/../public/error.html', 'utf8', function ( e, html ) {
|
||||
var stack = (err.stack || '')
|
||||
.split( '\n' ).slice( 1 )
|
||||
.map(
|
||||
function ( v ) {
|
||||
return '<li>' + v + '</li>';
|
||||
} ).join( '' );
|
||||
html = html
|
||||
.replace( '{style}', style )
|
||||
.replace( '{stack}', stack )
|
||||
.replace( '{title}', exports.title )
|
||||
.replace( /\{error\}/g, utils.escape( err.toString() ) );
|
||||
res.setHeader( 'Content-Type', 'text/html' );
|
||||
res.end( html );
|
||||
} );
|
||||
} );
|
||||
// json
|
||||
} else if ( ~accept.indexOf( 'json' ) ) {
|
||||
var json = JSON.stringify( { error : err } );
|
||||
res.setHeader( 'Content-Type', 'application/json' );
|
||||
res.end( json );
|
||||
// plain text
|
||||
} else {
|
||||
res.writeHead( 500, { 'Content-Type' : 'text/plain' } );
|
||||
res.end( err.stack );
|
||||
}
|
||||
} else {
|
||||
var body = showMessage
|
||||
? err.toString()
|
||||
: 'Internal Server Error';
|
||||
res.setHeader( 'Content-Type', 'text/plain' );
|
||||
res.end( body );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
66
example/node/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
66
example/node/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - favicon
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,8 +9,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, utils = require('../utils');
|
||||
var fs = require( 'fs' )
|
||||
, utils = require( '../utils' );
|
||||
|
||||
/**
|
||||
* Favicon cache.
|
||||
|
|
@ -30,11 +29,11 @@ var icon;
|
|||
* Examples:
|
||||
*
|
||||
* connect.createServer(
|
||||
* connect.favicon()
|
||||
* connect.favicon()
|
||||
* );
|
||||
*
|
||||
* connect.createServer(
|
||||
* connect.favicon(__dirname + '/public/favicon.ico')
|
||||
* connect.favicon(__dirname + '/public/favicon.ico')
|
||||
* );
|
||||
*
|
||||
* @param {String} path
|
||||
|
|
@ -43,34 +42,33 @@ var icon;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function favicon(path, options){
|
||||
var options = options || {}
|
||||
, path = path || __dirname + '/../public/favicon.ico'
|
||||
, maxAge = options.maxAge || 86400000;
|
||||
module.exports = function favicon( path, options ) {
|
||||
var options = options || {}
|
||||
, path = path || __dirname + '/../public/favicon.ico'
|
||||
, maxAge = options.maxAge || 86400000;
|
||||
|
||||
return function favicon(req, res, next){
|
||||
if ('/favicon.ico' == req.url) {
|
||||
if (icon) {
|
||||
res.writeHead(200, icon.headers);
|
||||
res.end(icon.body);
|
||||
} else {
|
||||
fs.readFile(path, function(err, buf){
|
||||
if (err) return next(err);
|
||||
icon = {
|
||||
headers: {
|
||||
'Content-Type': 'image/x-icon'
|
||||
, 'Content-Length': buf.length
|
||||
, 'ETag': '"' + utils.md5(buf) + '"'
|
||||
, 'Cache-Control': 'public, max-age=' + (maxAge / 1000)
|
||||
},
|
||||
body: buf
|
||||
};
|
||||
res.writeHead(200, icon.headers);
|
||||
res.end(icon.body);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
return function favicon( req, res, next ) {
|
||||
if ( '/favicon.ico' == req.url ) {
|
||||
if ( icon ) {
|
||||
res.writeHead( 200, icon.headers );
|
||||
res.end( icon.body );
|
||||
} else {
|
||||
fs.readFile( path, function ( err, buf ) {
|
||||
if ( err ) {
|
||||
return next( err );
|
||||
}
|
||||
icon = {
|
||||
headers : {
|
||||
'Content-Type' : 'image/x-icon', 'Content-Length' : buf.length, 'ETag' : '"' + utils.md5( buf ) + '"', 'Cache-Control' : 'public, max-age=' + (maxAge / 1000)
|
||||
},
|
||||
body : buf
|
||||
};
|
||||
res.writeHead( 200, icon.headers );
|
||||
res.end( icon.body );
|
||||
} );
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
};
|
||||
83
example/node/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
83
example/node/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - limit
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
|
|
@ -22,39 +21,47 @@
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function limit(bytes){
|
||||
if ('string' == typeof bytes) bytes = parse(bytes);
|
||||
if ('number' != typeof bytes) throw new Error('limit() bytes required');
|
||||
return function limit(req, res, next){
|
||||
var received = 0
|
||||
, len = req.headers['content-length']
|
||||
? parseInt(req.headers['content-length'], 10)
|
||||
: null;
|
||||
module.exports = function limit( bytes ) {
|
||||
if ( 'string' == typeof bytes ) {
|
||||
bytes = parse( bytes );
|
||||
}
|
||||
if ( 'number' != typeof bytes ) {
|
||||
throw new Error( 'limit() bytes required' );
|
||||
}
|
||||
return function limit( req, res, next ) {
|
||||
var received = 0
|
||||
, len = req.headers['content-length']
|
||||
? parseInt( req.headers['content-length'], 10 )
|
||||
: null;
|
||||
|
||||
// deny the request
|
||||
function deny() {
|
||||
req.destroy();
|
||||
}
|
||||
// deny the request
|
||||
function deny() {
|
||||
req.destroy();
|
||||
}
|
||||
|
||||
// self-awareness
|
||||
if (req._limit) return next();
|
||||
req._limit = true;
|
||||
// self-awareness
|
||||
if ( req._limit ) {
|
||||
return next();
|
||||
}
|
||||
req._limit = true;
|
||||
|
||||
// limit by content-length
|
||||
if (len && len > bytes) {
|
||||
res.statusCode = 413;
|
||||
res.end('Request Entity Too Large');
|
||||
return;
|
||||
}
|
||||
// limit by content-length
|
||||
if ( len && len > bytes ) {
|
||||
res.statusCode = 413;
|
||||
res.end( 'Request Entity Too Large' );
|
||||
return;
|
||||
}
|
||||
|
||||
// limit
|
||||
req.on('data', function(chunk){
|
||||
received += chunk.length;
|
||||
if (received > bytes) deny();
|
||||
});
|
||||
// limit
|
||||
req.on( 'data', function ( chunk ) {
|
||||
received += chunk.length;
|
||||
if ( received > bytes ) {
|
||||
deny();
|
||||
}
|
||||
} );
|
||||
|
||||
next();
|
||||
};
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -65,16 +72,14 @@ module.exports = function limit(bytes){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function parse(size) {
|
||||
var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/)
|
||||
, n = parseFloat(parts[1])
|
||||
, type = parts[2];
|
||||
function parse( size ) {
|
||||
var parts = size.match( /^(\d+(?:\.\d+)?) *(kb|mb|gb)$/ )
|
||||
, n = parseFloat( parts[1] )
|
||||
, type = parts[2];
|
||||
|
||||
var map = {
|
||||
kb: 1024
|
||||
, mb: 1024 * 1024
|
||||
, gb: 1024 * 1024 * 1024
|
||||
};
|
||||
var map = {
|
||||
kb : 1024, mb : 1024 * 1024, gb : 1024 * 1024 * 1024
|
||||
};
|
||||
|
||||
return map[type] * n;
|
||||
return map[type] * n;
|
||||
}
|
||||
262
example/node/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
262
example/node/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - logger
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -80,80 +79,88 @@ var defaultBufferDuration = 1000;
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function logger(options) {
|
||||
if ('object' == typeof options) {
|
||||
options = options || {};
|
||||
} else if (options) {
|
||||
options = { format: options };
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
exports = module.exports = function logger( options ) {
|
||||
if ( 'object' == typeof options ) {
|
||||
options = options || {};
|
||||
} else if ( options ) {
|
||||
options = { format : options };
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
// output on request instead of response
|
||||
var immediate = options.immediate;
|
||||
// output on request instead of response
|
||||
var immediate = options.immediate;
|
||||
|
||||
// format name
|
||||
var fmt = exports[options.format] || options.format || exports.default;
|
||||
// format name
|
||||
var fmt = exports[options.format] || options.format || exports.default;
|
||||
|
||||
// compile format
|
||||
if ('function' != typeof fmt) fmt = compile(fmt);
|
||||
// compile format
|
||||
if ( 'function' != typeof fmt ) {
|
||||
fmt = compile( fmt );
|
||||
}
|
||||
|
||||
// options
|
||||
var stream = options.stream || process.stdout
|
||||
, buffer = options.buffer;
|
||||
// options
|
||||
var stream = options.stream || process.stdout
|
||||
, buffer = options.buffer;
|
||||
|
||||
// buffering support
|
||||
if (buffer) {
|
||||
var realStream = stream
|
||||
, interval = 'number' == typeof buffer
|
||||
? buffer
|
||||
: defaultBufferDuration;
|
||||
// buffering support
|
||||
if ( buffer ) {
|
||||
var realStream = stream
|
||||
, interval = 'number' == typeof buffer
|
||||
? buffer
|
||||
: defaultBufferDuration;
|
||||
|
||||
// flush interval
|
||||
setInterval(function(){
|
||||
if (buf.length) {
|
||||
realStream.write(buf.join(''), 'ascii');
|
||||
buf.length = 0;
|
||||
}
|
||||
}, interval);
|
||||
// flush interval
|
||||
setInterval( function () {
|
||||
if ( buf.length ) {
|
||||
realStream.write( buf.join( '' ), 'ascii' );
|
||||
buf.length = 0;
|
||||
}
|
||||
}, interval );
|
||||
|
||||
// swap the stream
|
||||
stream = {
|
||||
write: function(str){
|
||||
buf.push(str);
|
||||
}
|
||||
};
|
||||
}
|
||||
// swap the stream
|
||||
stream = {
|
||||
write : function ( str ) {
|
||||
buf.push( str );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return function logger(req, res, next) {
|
||||
req._startTime = new Date;
|
||||
return function logger( req, res, next ) {
|
||||
req._startTime = new Date;
|
||||
|
||||
// mount safety
|
||||
if (req._logging) return next();
|
||||
// mount safety
|
||||
if ( req._logging ) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// flag as logging
|
||||
req._logging = true;
|
||||
// flag as logging
|
||||
req._logging = true;
|
||||
|
||||
// immediate
|
||||
if (immediate) {
|
||||
var line = fmt(exports, req, res);
|
||||
if (null == line) return;
|
||||
stream.write(line + '\n', 'ascii');
|
||||
} else {
|
||||
// proxy end to output loggging
|
||||
var end = res.end;
|
||||
res.end = function(chunk, encoding){
|
||||
res.end = end;
|
||||
res.end(chunk, encoding);
|
||||
var line = fmt(exports, req, res);
|
||||
if (null == line) return;
|
||||
stream.write(line + '\n', 'ascii');
|
||||
};
|
||||
}
|
||||
// immediate
|
||||
if ( immediate ) {
|
||||
var line = fmt( exports, req, res );
|
||||
if ( null == line ) {
|
||||
return;
|
||||
}
|
||||
stream.write( line + '\n', 'ascii' );
|
||||
} else {
|
||||
// proxy end to output loggging
|
||||
var end = res.end;
|
||||
res.end = function ( chunk, encoding ) {
|
||||
res.end = end;
|
||||
res.end( chunk, encoding );
|
||||
var line = fmt( exports, req, res );
|
||||
if ( null == line ) {
|
||||
return;
|
||||
}
|
||||
stream.write( line + '\n', 'ascii' );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
next();
|
||||
};
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -164,13 +171,14 @@ exports = module.exports = function logger(options) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function compile(fmt) {
|
||||
fmt = fmt.replace(/"/g, '\\"');
|
||||
var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){
|
||||
return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "';
|
||||
}) + '";'
|
||||
return new Function('tokens, req, res', js);
|
||||
};
|
||||
function compile( fmt ) {
|
||||
fmt = fmt.replace( /"/g, '\\"' );
|
||||
var js = ' return "' + fmt.replace( /:([-\w]{2,})(?:\[([^\]]+)\])?/g, function ( _, name, arg ) {
|
||||
return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "';
|
||||
} ) + '";'
|
||||
return new Function( 'tokens, req, res', js );
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Define a token function with the given `name`,
|
||||
|
|
@ -182,9 +190,9 @@ function compile(fmt) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports.token = function(name, fn) {
|
||||
exports[name] = fn;
|
||||
return this;
|
||||
exports.token = function ( name, fn ) {
|
||||
exports[name] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -196,104 +204,110 @@ exports.token = function(name, fn) {
|
|||
* @api public
|
||||
*/
|
||||
|
||||
exports.format = function(name, str){
|
||||
exports[name] = str;
|
||||
return this;
|
||||
exports.format = function ( name, str ) {
|
||||
exports[name] = str;
|
||||
return this;
|
||||
};
|
||||
|
||||
// default format
|
||||
|
||||
exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"');
|
||||
exports.format( 'default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' );
|
||||
|
||||
// short format
|
||||
|
||||
exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms');
|
||||
exports.format( 'short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' );
|
||||
|
||||
// tiny format
|
||||
|
||||
exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms');
|
||||
exports.format( 'tiny', ':method :url :status :res[content-length] - :response-time ms' );
|
||||
|
||||
// dev (colored)
|
||||
|
||||
exports.format('dev', function(tokens, req, res){
|
||||
var status = res.statusCode
|
||||
, color = 32;
|
||||
exports.format( 'dev', function ( tokens, req, res ) {
|
||||
var status = res.statusCode
|
||||
, color = 32;
|
||||
|
||||
if (status >= 500) color = 31
|
||||
else if (status >= 400) color = 33
|
||||
else if (status >= 300) color = 36;
|
||||
if ( status >= 500 ) {
|
||||
color = 31
|
||||
}
|
||||
else if ( status >= 400 ) {
|
||||
color = 33
|
||||
}
|
||||
else if ( status >= 300 ) {
|
||||
color = 36;
|
||||
}
|
||||
|
||||
return '\033[90m' + req.method
|
||||
+ ' ' + req.originalUrl + ' '
|
||||
+ '\033[' + color + 'm' + res.statusCode
|
||||
+ ' \033[90m'
|
||||
+ (new Date - req._startTime)
|
||||
+ 'ms\033[0m';
|
||||
});
|
||||
return '\033[90m' + req.method
|
||||
+ ' ' + req.originalUrl + ' '
|
||||
+ '\033[' + color + 'm' + res.statusCode
|
||||
+ ' \033[90m'
|
||||
+ (new Date - req._startTime)
|
||||
+ 'ms\033[0m';
|
||||
} );
|
||||
|
||||
// request url
|
||||
|
||||
exports.token('url', function(req){
|
||||
return req.originalUrl;
|
||||
});
|
||||
exports.token( 'url', function ( req ) {
|
||||
return req.originalUrl;
|
||||
} );
|
||||
|
||||
// request method
|
||||
|
||||
exports.token('method', function(req){
|
||||
return req.method;
|
||||
});
|
||||
exports.token( 'method', function ( req ) {
|
||||
return req.method;
|
||||
} );
|
||||
|
||||
// response time in milliseconds
|
||||
|
||||
exports.token('response-time', function(req){
|
||||
return new Date - req._startTime;
|
||||
});
|
||||
exports.token( 'response-time', function ( req ) {
|
||||
return new Date - req._startTime;
|
||||
} );
|
||||
|
||||
// UTC date
|
||||
|
||||
exports.token('date', function(){
|
||||
return new Date().toUTCString();
|
||||
});
|
||||
exports.token( 'date', function () {
|
||||
return new Date().toUTCString();
|
||||
} );
|
||||
|
||||
// response status code
|
||||
|
||||
exports.token('status', function(req, res){
|
||||
return res.statusCode;
|
||||
});
|
||||
exports.token( 'status', function ( req, res ) {
|
||||
return res.statusCode;
|
||||
} );
|
||||
|
||||
// normalized referrer
|
||||
|
||||
exports.token('referrer', function(req){
|
||||
return req.headers['referer'] || req.headers['referrer'];
|
||||
});
|
||||
exports.token( 'referrer', function ( req ) {
|
||||
return req.headers['referer'] || req.headers['referrer'];
|
||||
} );
|
||||
|
||||
// remote address
|
||||
|
||||
exports.token('remote-addr', function(req){
|
||||
return req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress));
|
||||
});
|
||||
exports.token( 'remote-addr', function ( req ) {
|
||||
return req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress));
|
||||
} );
|
||||
|
||||
// HTTP version
|
||||
|
||||
exports.token('http-version', function(req){
|
||||
return req.httpVersionMajor + '.' + req.httpVersionMinor;
|
||||
});
|
||||
exports.token( 'http-version', function ( req ) {
|
||||
return req.httpVersionMajor + '.' + req.httpVersionMinor;
|
||||
} );
|
||||
|
||||
// UA string
|
||||
|
||||
exports.token('user-agent', function(req){
|
||||
return req.headers['user-agent'];
|
||||
});
|
||||
exports.token( 'user-agent', function ( req ) {
|
||||
return req.headers['user-agent'];
|
||||
} );
|
||||
|
||||
// request header
|
||||
|
||||
exports.token('req', function(req, res, field){
|
||||
return req.headers[field.toLowerCase()];
|
||||
});
|
||||
exports.token( 'req', function ( req, res, field ) {
|
||||
return req.headers[field.toLowerCase()];
|
||||
} );
|
||||
|
||||
// response header
|
||||
|
||||
exports.token('res', function(req, res, field){
|
||||
return (res._headers || {})[field.toLowerCase()];
|
||||
});
|
||||
exports.token( 'res', function ( req, res, field ) {
|
||||
return (res._headers || {})[field.toLowerCase()];
|
||||
} );
|
||||
|
||||
|
|
|
|||
33
example/node/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
33
example/node/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - methodOverride
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -8,7 +7,7 @@
|
|||
|
||||
/**
|
||||
* Provides faux HTTP method support.
|
||||
*
|
||||
*
|
||||
* Pass an optional `key` to use when checking for
|
||||
* a method override, othewise defaults to _\_method_.
|
||||
* The original method is available via `req.originalMethod`.
|
||||
|
|
@ -18,21 +17,21 @@
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function methodOverride(key){
|
||||
key = key || "_method";
|
||||
return function methodOverride(req, res, next) {
|
||||
req.originalMethod = req.originalMethod || req.method;
|
||||
module.exports = function methodOverride( key ) {
|
||||
key = key || "_method";
|
||||
return function methodOverride( req, res, next ) {
|
||||
req.originalMethod = req.originalMethod || req.method;
|
||||
|
||||
// req.body
|
||||
if (req.body && key in req.body) {
|
||||
req.method = req.body[key].toUpperCase();
|
||||
delete req.body[key];
|
||||
// check X-HTTP-Method-Override
|
||||
} else if (req.headers['x-http-method-override']) {
|
||||
req.method = req.headers['x-http-method-override'].toUpperCase();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
// req.body
|
||||
if ( req.body && key in req.body ) {
|
||||
req.method = req.body[key].toUpperCase();
|
||||
delete req.body[key];
|
||||
// check X-HTTP-Method-Override
|
||||
} else if ( req.headers['x-http-method-override'] ) {
|
||||
req.method = req.headers['x-http-method-override'].toUpperCase();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
85
example/node/node_modules/express/node_modules/connect/lib/middleware/profiler.js
generated
vendored
85
example/node/node_modules/express/node_modules/connect/lib/middleware/profiler.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - profiler
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
|
|
@ -25,28 +24,27 @@
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function profiler(){
|
||||
return function(req, res, next){
|
||||
var end = res.end
|
||||
, start = snapshot();
|
||||
module.exports = function profiler() {
|
||||
return function ( req, res, next ) {
|
||||
var end = res.end
|
||||
, start = snapshot();
|
||||
|
||||
// state snapshot
|
||||
function snapshot() {
|
||||
return {
|
||||
mem: process.memoryUsage()
|
||||
, time: new Date
|
||||
};
|
||||
}
|
||||
// state snapshot
|
||||
function snapshot() {
|
||||
return {
|
||||
mem : process.memoryUsage(), time : new Date
|
||||
};
|
||||
}
|
||||
|
||||
// proxy res.end()
|
||||
res.end = function(data, encoding){
|
||||
res.end = end;
|
||||
res.end(data, encoding);
|
||||
compare(req, start, snapshot())
|
||||
};
|
||||
// proxy res.end()
|
||||
res.end = function ( data, encoding ) {
|
||||
res.end = end;
|
||||
res.end( data, encoding );
|
||||
compare( req, start, snapshot() )
|
||||
};
|
||||
|
||||
next();
|
||||
}
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -58,15 +56,15 @@ module.exports = function profiler(){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function compare(req, start, end) {
|
||||
console.log();
|
||||
row(req.method, req.url);
|
||||
row('response time:', (end.time - start.time) + 'ms');
|
||||
row('memory rss:', formatBytes(end.mem.rss - start.mem.rss));
|
||||
row('memory vsize:', formatBytes(end.mem.vsize - start.mem.vsize));
|
||||
row('heap before:', formatBytes(start.mem.heapUsed) + ' / ' + formatBytes(start.mem.heapTotal));
|
||||
row('heap after:', formatBytes(end.mem.heapUsed) + ' / ' + formatBytes(end.mem.heapTotal));
|
||||
console.log();
|
||||
function compare( req, start, end ) {
|
||||
console.log();
|
||||
row( req.method, req.url );
|
||||
row( 'response time:', (end.time - start.time) + 'ms' );
|
||||
row( 'memory rss:', formatBytes( end.mem.rss - start.mem.rss ) );
|
||||
row( 'memory vsize:', formatBytes( end.mem.vsize - start.mem.vsize ) );
|
||||
row( 'heap before:', formatBytes( start.mem.heapUsed ) + ' / ' + formatBytes( start.mem.heapTotal ) );
|
||||
row( 'heap after:', formatBytes( end.mem.heapUsed ) + ' / ' + formatBytes( end.mem.heapTotal ) );
|
||||
console.log();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,8 +75,8 @@ function compare(req, start, end) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function row(key, val) {
|
||||
console.log(' \033[90m%s\033[0m \033[36m%s\033[0m', key, val);
|
||||
function row( key, val ) {
|
||||
console.log( ' \033[90m%s\033[0m \033[36m%s\033[0m', key, val );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -89,12 +87,19 @@ function row(key, val) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function formatBytes(bytes) {
|
||||
var kb = 1024
|
||||
, mb = 1024 * kb
|
||||
, gb = 1024 * mb;
|
||||
if (bytes < kb) return bytes + 'b';
|
||||
if (bytes < mb) return (bytes / kb).toFixed(2) + 'kb';
|
||||
if (bytes < gb) return (bytes / mb).toFixed(2) + 'mb';
|
||||
return (bytes / gb).toFixed(2) + 'gb';
|
||||
};
|
||||
function formatBytes( bytes ) {
|
||||
var kb = 1024
|
||||
, mb = 1024 * kb
|
||||
, gb = 1024 * mb;
|
||||
if ( bytes < kb ) {
|
||||
return bytes + 'b';
|
||||
}
|
||||
if ( bytes < mb ) {
|
||||
return (bytes / kb).toFixed( 2 ) + 'kb';
|
||||
}
|
||||
if ( bytes < gb ) {
|
||||
return (bytes / mb).toFixed( 2 ) + 'mb';
|
||||
}
|
||||
return (bytes / gb).toFixed( 2 ) + 'gb';
|
||||
}
|
||||
;
|
||||
|
|
|
|||
19
example/node/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
19
example/node/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - query
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
|
|
@ -10,8 +9,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var qs = require('qs')
|
||||
, parse = require('url').parse;
|
||||
var qs = require( 'qs' )
|
||||
, parse = require( 'url' ).parse;
|
||||
|
||||
/**
|
||||
* Automatically parse the query-string when available,
|
||||
|
|
@ -30,11 +29,11 @@ var qs = require('qs')
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function query(){
|
||||
return function query(req, res, next){
|
||||
req.query = ~req.url.indexOf('?')
|
||||
? qs.parse(parse(req.url).query)
|
||||
: {};
|
||||
next();
|
||||
};
|
||||
module.exports = function query() {
|
||||
return function query( req, res, next ) {
|
||||
req.query = ~req.url.indexOf( '?' )
|
||||
? qs.parse( parse( req.url ).query )
|
||||
: {};
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
33
example/node/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
33
example/node/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - responseTime
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
|
|
@ -13,22 +12,24 @@
|
|||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function responseTime(){
|
||||
return function(req, res, next){
|
||||
var writeHead = res.writeHead
|
||||
, start = new Date;
|
||||
module.exports = function responseTime() {
|
||||
return function ( req, res, next ) {
|
||||
var writeHead = res.writeHead
|
||||
, start = new Date;
|
||||
|
||||
if (res._responseTime) return next();
|
||||
res._responseTime = true;
|
||||
if ( res._responseTime ) {
|
||||
return next();
|
||||
}
|
||||
res._responseTime = true;
|
||||
|
||||
// proxy writeHead to calculate duration
|
||||
res.writeHead = function(status, headers){
|
||||
var duration = new Date - start;
|
||||
res.setHeader('X-Response-Time', duration + 'ms');
|
||||
res.writeHead = writeHead;
|
||||
res.writeHead(status, headers);
|
||||
};
|
||||
// proxy writeHead to calculate duration
|
||||
res.writeHead = function ( status, headers ) {
|
||||
var duration = new Date - start;
|
||||
res.setHeader( 'X-Response-Time', duration + 'ms' );
|
||||
res.writeHead = writeHead;
|
||||
res.writeHead( status, headers );
|
||||
};
|
||||
|
||||
next();
|
||||
};
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
527
example/node/node_modules/express/node_modules/connect/lib/middleware/router.js
generated
vendored
527
example/node/node_modules/express/node_modules/connect/lib/middleware/router.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - router
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,8 +9,8 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, parse = require('url').parse;
|
||||
var utils = require( '../utils' )
|
||||
, parse = require( 'url' ).parse;
|
||||
|
||||
/**
|
||||
* Expose router.
|
||||
|
|
@ -24,24 +23,24 @@ exports = module.exports = router;
|
|||
*/
|
||||
|
||||
var _methods = exports.methods = [
|
||||
'get'
|
||||
, 'post'
|
||||
, 'put'
|
||||
, 'delete'
|
||||
, 'connect'
|
||||
, 'options'
|
||||
, 'trace'
|
||||
, 'copy'
|
||||
, 'lock'
|
||||
, 'mkcol'
|
||||
, 'move'
|
||||
, 'propfind'
|
||||
, 'proppatch'
|
||||
, 'unlock'
|
||||
, 'report'
|
||||
, 'mkactivity'
|
||||
, 'checkout'
|
||||
, 'merge'
|
||||
'get'
|
||||
, 'post'
|
||||
, 'put'
|
||||
, 'delete'
|
||||
, 'connect'
|
||||
, 'options'
|
||||
, 'trace'
|
||||
, 'copy'
|
||||
, 'lock'
|
||||
, 'mkcol'
|
||||
, 'move'
|
||||
, 'propfind'
|
||||
, 'proppatch'
|
||||
, 'unlock'
|
||||
, 'report'
|
||||
, 'mkactivity'
|
||||
, 'checkout'
|
||||
, 'merge'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -63,201 +62,205 @@ var _methods = exports.methods = [
|
|||
* @api public
|
||||
*/
|
||||
|
||||
function router(fn){
|
||||
var self = this
|
||||
, methods = {}
|
||||
, routes = {}
|
||||
, params = {};
|
||||
function router( fn ) {
|
||||
var self = this
|
||||
, methods = {}
|
||||
, routes = {}
|
||||
, params = {};
|
||||
|
||||
if (!fn) throw new Error('router provider requires a callback function');
|
||||
if ( !fn ) {
|
||||
throw new Error( 'router provider requires a callback function' );
|
||||
}
|
||||
|
||||
// Generate method functions
|
||||
_methods.forEach(function(method){
|
||||
methods[method] = generateMethodFunction(method.toUpperCase());
|
||||
});
|
||||
// Generate method functions
|
||||
_methods.forEach( function ( method ) {
|
||||
methods[method] = generateMethodFunction( method.toUpperCase() );
|
||||
} );
|
||||
|
||||
// Alias del -> delete
|
||||
methods.del = methods.delete;
|
||||
// Alias del -> delete
|
||||
methods.del = methods.delete;
|
||||
|
||||
// Apply callback to all methods
|
||||
methods.all = function(){
|
||||
var args = arguments;
|
||||
_methods.forEach(function(name){
|
||||
methods[name].apply(this, args);
|
||||
});
|
||||
return self;
|
||||
};
|
||||
// Apply callback to all methods
|
||||
methods.all = function () {
|
||||
var args = arguments;
|
||||
_methods.forEach( function ( name ) {
|
||||
methods[name].apply( this, args );
|
||||
} );
|
||||
return self;
|
||||
};
|
||||
|
||||
// Register param callback
|
||||
methods.param = function(name, fn){
|
||||
params[name] = fn;
|
||||
};
|
||||
|
||||
fn.call(this, methods);
|
||||
// Register param callback
|
||||
methods.param = function ( name, fn ) {
|
||||
params[name] = fn;
|
||||
};
|
||||
|
||||
function generateMethodFunction(name) {
|
||||
var localRoutes = routes[name] = routes[name] || [];
|
||||
return function(path, fn){
|
||||
var keys = []
|
||||
, middleware = [];
|
||||
fn.call( this, methods );
|
||||
|
||||
// slice middleware
|
||||
if (arguments.length > 2) {
|
||||
middleware = Array.prototype.slice.call(arguments, 1, arguments.length);
|
||||
fn = middleware.pop();
|
||||
middleware = utils.flatten(middleware);
|
||||
}
|
||||
function generateMethodFunction( name ) {
|
||||
var localRoutes = routes[name] = routes[name] || [];
|
||||
return function ( path, fn ) {
|
||||
var keys = []
|
||||
, middleware = [];
|
||||
|
||||
fn.middleware = middleware;
|
||||
// slice middleware
|
||||
if ( arguments.length > 2 ) {
|
||||
middleware = Array.prototype.slice.call( arguments, 1, arguments.length );
|
||||
fn = middleware.pop();
|
||||
middleware = utils.flatten( middleware );
|
||||
}
|
||||
|
||||
if (!path) throw new Error(name + ' route requires a path');
|
||||
if (!fn) throw new Error(name + ' route ' + path + ' requires a callback');
|
||||
var regexp = path instanceof RegExp
|
||||
? path
|
||||
: normalizePath(path, keys);
|
||||
localRoutes.push({
|
||||
fn: fn
|
||||
, path: regexp
|
||||
, keys: keys
|
||||
, orig: path
|
||||
, method: name
|
||||
});
|
||||
return self;
|
||||
};
|
||||
}
|
||||
fn.middleware = middleware;
|
||||
|
||||
function router(req, res, next){
|
||||
var route
|
||||
, self = this;
|
||||
if ( !path ) {
|
||||
throw new Error( name + ' route requires a path' );
|
||||
}
|
||||
if ( !fn ) {
|
||||
throw new Error( name + ' route ' + path + ' requires a callback' );
|
||||
}
|
||||
var regexp = path instanceof RegExp
|
||||
? path
|
||||
: normalizePath( path, keys );
|
||||
localRoutes.push( {
|
||||
fn : fn, path : regexp, keys : keys, orig : path, method : name
|
||||
} );
|
||||
return self;
|
||||
};
|
||||
}
|
||||
|
||||
(function pass(i){
|
||||
if (route = match(req, routes, i)) {
|
||||
var i = 0
|
||||
, keys = route.keys;
|
||||
function router( req, res, next ) {
|
||||
var route
|
||||
, self = this;
|
||||
|
||||
req.params = route.params;
|
||||
(function pass( i ) {
|
||||
if ( route = match( req, routes, i ) ) {
|
||||
var i = 0
|
||||
, keys = route.keys;
|
||||
|
||||
// Param preconditions
|
||||
(function param(err) {
|
||||
try {
|
||||
var key = keys[i++]
|
||||
, val = req.params[key]
|
||||
, fn = params[key];
|
||||
req.params = route.params;
|
||||
|
||||
if ('route' == err) {
|
||||
pass(req._route_index + 1);
|
||||
// Error
|
||||
} else if (err) {
|
||||
next(err);
|
||||
// Param has callback
|
||||
} else if (fn) {
|
||||
// Return style
|
||||
if (1 == fn.length) {
|
||||
req.params[key] = fn(val);
|
||||
param();
|
||||
// Middleware style
|
||||
} else {
|
||||
fn(req, res, param, val);
|
||||
}
|
||||
// Finished processing params
|
||||
} else if (!key) {
|
||||
// route middleware
|
||||
i = 0;
|
||||
(function nextMiddleware(err){
|
||||
var fn = route.middleware[i++];
|
||||
if ('route' == err) {
|
||||
pass(req._route_index + 1);
|
||||
} else if (err) {
|
||||
next(err);
|
||||
} else if (fn) {
|
||||
fn(req, res, nextMiddleware);
|
||||
} else {
|
||||
route.call(self, req, res, function(err){
|
||||
if (err) {
|
||||
next(err);
|
||||
} else {
|
||||
pass(req._route_index + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
// More params
|
||||
} else {
|
||||
param();
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
})();
|
||||
} else if ('OPTIONS' == req.method) {
|
||||
options(req, res, routes);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})();
|
||||
};
|
||||
// Param preconditions
|
||||
(function param( err ) {
|
||||
try {
|
||||
var key = keys[i++]
|
||||
, val = req.params[key]
|
||||
, fn = params[key];
|
||||
|
||||
router.remove = function(path, method){
|
||||
var fns = router.lookup(path, method);
|
||||
fns.forEach(function(fn){
|
||||
routes[fn.method].splice(fn.index, 1);
|
||||
});
|
||||
};
|
||||
if ( 'route' == err ) {
|
||||
pass( req._route_index + 1 );
|
||||
// Error
|
||||
} else if ( err ) {
|
||||
next( err );
|
||||
// Param has callback
|
||||
} else if ( fn ) {
|
||||
// Return style
|
||||
if ( 1 == fn.length ) {
|
||||
req.params[key] = fn( val );
|
||||
param();
|
||||
// Middleware style
|
||||
} else {
|
||||
fn( req, res, param, val );
|
||||
}
|
||||
// Finished processing params
|
||||
} else if ( !key ) {
|
||||
// route middleware
|
||||
i = 0;
|
||||
(function nextMiddleware( err ) {
|
||||
var fn = route.middleware[i++];
|
||||
if ( 'route' == err ) {
|
||||
pass( req._route_index + 1 );
|
||||
} else if ( err ) {
|
||||
next( err );
|
||||
} else if ( fn ) {
|
||||
fn( req, res, nextMiddleware );
|
||||
} else {
|
||||
route.call( self, req, res, function ( err ) {
|
||||
if ( err ) {
|
||||
next( err );
|
||||
} else {
|
||||
pass( req._route_index + 1 );
|
||||
}
|
||||
} );
|
||||
}
|
||||
})();
|
||||
// More params
|
||||
} else {
|
||||
param();
|
||||
}
|
||||
} catch ( err ) {
|
||||
next( err );
|
||||
}
|
||||
})();
|
||||
} else if ( 'OPTIONS' == req.method ) {
|
||||
options( req, res, routes );
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
router.lookup = function(path, method, ret){
|
||||
ret = ret || [];
|
||||
;
|
||||
|
||||
// method specific lookup
|
||||
if (method) {
|
||||
method = method.toUpperCase();
|
||||
if (routes[method]) {
|
||||
routes[method].forEach(function(route, i){
|
||||
if (path == route.orig) {
|
||||
var fn = route.fn;
|
||||
fn.regexp = route.path;
|
||||
fn.keys = route.keys;
|
||||
fn.path = route.orig;
|
||||
fn.method = route.method;
|
||||
fn.index = i;
|
||||
ret.push(fn);
|
||||
}
|
||||
});
|
||||
}
|
||||
// global lookup
|
||||
} else {
|
||||
_methods.forEach(function(method){
|
||||
router.lookup(path, method, ret);
|
||||
});
|
||||
}
|
||||
router.remove = function ( path, method ) {
|
||||
var fns = router.lookup( path, method );
|
||||
fns.forEach( function ( fn ) {
|
||||
routes[fn.method].splice( fn.index, 1 );
|
||||
} );
|
||||
};
|
||||
|
||||
return ret;
|
||||
};
|
||||
router.lookup = function ( path, method, ret ) {
|
||||
ret = ret || [];
|
||||
|
||||
router.match = function(url, method, ret){
|
||||
var ret = ret || []
|
||||
, i = 0
|
||||
, fn
|
||||
, req;
|
||||
// method specific lookup
|
||||
if ( method ) {
|
||||
method = method.toUpperCase();
|
||||
if ( routes[method] ) {
|
||||
routes[method].forEach( function ( route, i ) {
|
||||
if ( path == route.orig ) {
|
||||
var fn = route.fn;
|
||||
fn.regexp = route.path;
|
||||
fn.keys = route.keys;
|
||||
fn.path = route.orig;
|
||||
fn.method = route.method;
|
||||
fn.index = i;
|
||||
ret.push( fn );
|
||||
}
|
||||
} );
|
||||
}
|
||||
// global lookup
|
||||
} else {
|
||||
_methods.forEach( function ( method ) {
|
||||
router.lookup( path, method, ret );
|
||||
} );
|
||||
}
|
||||
|
||||
// method specific matches
|
||||
if (method) {
|
||||
method = method.toUpperCase();
|
||||
req = { url: url, method: method };
|
||||
while (fn = match(req, routes, i)) {
|
||||
i = req._route_index + 1;
|
||||
ret.push(fn);
|
||||
}
|
||||
// global matches
|
||||
} else {
|
||||
_methods.forEach(function(method){
|
||||
router.match(url, method, ret);
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
return ret;
|
||||
};
|
||||
router.match = function ( url, method, ret ) {
|
||||
var ret = ret || []
|
||||
, i = 0
|
||||
, fn
|
||||
, req;
|
||||
|
||||
return router;
|
||||
// method specific matches
|
||||
if ( method ) {
|
||||
method = method.toUpperCase();
|
||||
req = { url : url, method : method };
|
||||
while ( fn = match( req, routes, i ) ) {
|
||||
i = req._route_index + 1;
|
||||
ret.push( fn );
|
||||
}
|
||||
// global matches
|
||||
} else {
|
||||
_methods.forEach( function ( method ) {
|
||||
router.match( url, method, ret );
|
||||
} );
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -269,14 +272,13 @@ function router(fn){
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function options(req, res, routes) {
|
||||
var pathname = parse(req.url).pathname
|
||||
, body = optionsFor(pathname, routes).join(',');
|
||||
res.writeHead(200, {
|
||||
'Content-Length': body.length
|
||||
, 'Allow': body
|
||||
});
|
||||
res.end(body);
|
||||
function options( req, res, routes ) {
|
||||
var pathname = parse( req.url ).pathname
|
||||
, body = optionsFor( pathname, routes ).join( ',' );
|
||||
res.writeHead( 200, {
|
||||
'Content-Length' : body.length, 'Allow' : body
|
||||
} );
|
||||
res.end( body );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -288,15 +290,18 @@ function options(req, res, routes) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function optionsFor(path, routes) {
|
||||
return _methods.filter(function(method){
|
||||
var arr = routes[method.toUpperCase()];
|
||||
for (var i = 0, len = arr.length; i < len; ++i) {
|
||||
if (arr[i].path.test(path)) return true;
|
||||
}
|
||||
}).map(function(method){
|
||||
return method.toUpperCase();
|
||||
});
|
||||
function optionsFor( path, routes ) {
|
||||
return _methods.filter(
|
||||
function ( method ) {
|
||||
var arr = routes[method.toUpperCase()];
|
||||
for ( var i = 0, len = arr.length; i < len; ++i ) {
|
||||
if ( arr[i].path.test( path ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} ).map( function ( method ) {
|
||||
return method.toUpperCase();
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -314,23 +319,23 @@ function optionsFor(path, routes) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function normalizePath(path, keys) {
|
||||
path = path
|
||||
.concat('/?')
|
||||
.replace(/\/\(/g, '(?:/')
|
||||
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
||||
keys.push(key);
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (format || '') + (capture || '([^/]+?)') + ')'
|
||||
+ (optional || '');
|
||||
})
|
||||
.replace(/([\/.])/g, '\\$1')
|
||||
.replace(/\*/g, '(.+)');
|
||||
return new RegExp('^' + path + '$', 'i');
|
||||
function normalizePath( path, keys ) {
|
||||
path = path
|
||||
.concat( '/?' )
|
||||
.replace( /\/\(/g, '(?:/' )
|
||||
.replace( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function ( _, slash, format, key, capture, optional ) {
|
||||
keys.push( key );
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (format || '') + (capture || '([^/]+?)') + ')'
|
||||
+ (optional || '');
|
||||
} )
|
||||
.replace( /([\/.])/g, '\\$1' )
|
||||
.replace( /\*/g, '(.+)' );
|
||||
return new RegExp( '^' + path + '$', 'i' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -344,36 +349,38 @@ function normalizePath(path, keys) {
|
|||
* @api private
|
||||
*/
|
||||
|
||||
function match(req, routes, i) {
|
||||
var captures
|
||||
, method = req.method
|
||||
, i = i || 0;
|
||||
if ('HEAD' == method) method = 'GET';
|
||||
if (routes = routes[method]) {
|
||||
var url = parse(req.url)
|
||||
, pathname = url.pathname;
|
||||
for (var len = routes.length; i < len; ++i) {
|
||||
var route = routes[i]
|
||||
, fn = route.fn
|
||||
, path = route.path
|
||||
, keys = fn.keys = route.keys;
|
||||
if (captures = path.exec(pathname)) {
|
||||
fn.method = method;
|
||||
fn.params = [];
|
||||
for (var j = 1, len = captures.length; j < len; ++j) {
|
||||
var key = keys[j-1],
|
||||
val = typeof captures[j] === 'string'
|
||||
? decodeURIComponent(captures[j])
|
||||
: captures[j];
|
||||
if (key) {
|
||||
fn.params[key] = val;
|
||||
} else {
|
||||
fn.params.push(val);
|
||||
}
|
||||
}
|
||||
req._route_index = i;
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
}
|
||||
function match( req, routes, i ) {
|
||||
var captures
|
||||
, method = req.method
|
||||
, i = i || 0;
|
||||
if ( 'HEAD' == method ) {
|
||||
method = 'GET';
|
||||
}
|
||||
if ( routes = routes[method] ) {
|
||||
var url = parse( req.url )
|
||||
, pathname = url.pathname;
|
||||
for ( var len = routes.length; i < len; ++i ) {
|
||||
var route = routes[i]
|
||||
, fn = route.fn
|
||||
, path = route.path
|
||||
, keys = fn.keys = route.keys;
|
||||
if ( captures = path.exec( pathname ) ) {
|
||||
fn.method = method;
|
||||
fn.params = [];
|
||||
for ( var j = 1, len = captures.length; j < len; ++j ) {
|
||||
var key = keys[j - 1],
|
||||
val = typeof captures[j] === 'string'
|
||||
? decodeURIComponent( captures[j] )
|
||||
: captures[j];
|
||||
if ( key ) {
|
||||
fn.params[key] = val;
|
||||
} else {
|
||||
fn.params.push( val );
|
||||
}
|
||||
}
|
||||
req._route_index = i;
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
289
example/node/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
289
example/node/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - session
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,13 +9,13 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Session = require('./session/session')
|
||||
, MemoryStore = require('./session/memory')
|
||||
, Cookie = require('./session/cookie')
|
||||
, Store = require('./session/store')
|
||||
, utils = require('./../utils')
|
||||
, parse = require('url').parse
|
||||
, crypto = require('crypto');
|
||||
var Session = require( './session/session' )
|
||||
, MemoryStore = require( './session/memory' )
|
||||
, Cookie = require( './session/cookie' )
|
||||
, Store = require( './session/store' )
|
||||
, utils = require( './../utils' )
|
||||
, parse = require( 'url' ).parse
|
||||
, crypto = require( 'crypto' );
|
||||
|
||||
// environment
|
||||
|
||||
|
|
@ -42,16 +41,17 @@ exports.MemoryStore = MemoryStore;
|
|||
*/
|
||||
|
||||
var warning = 'Warning: connection.session() MemoryStore is not\n'
|
||||
+ 'designed for a production environment, as it will leak\n'
|
||||
+ 'memory, and obviously only work within a single process.';
|
||||
+ 'designed for a production environment, as it will leak\n'
|
||||
+ 'memory, and obviously only work within a single process.';
|
||||
|
||||
/**
|
||||
* Default finger-printing function.
|
||||
*/
|
||||
|
||||
function defaultFingerprint(req) {
|
||||
return '';
|
||||
};
|
||||
function defaultFingerprint( req ) {
|
||||
return '';
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Paths to ignore.
|
||||
|
|
@ -93,7 +93,7 @@ exports.ignore = [];
|
|||
* ## req.session
|
||||
*
|
||||
* To store or access session data, simply use the request property `req.session`,
|
||||
* which is (generally) serialized as JSON by the store, so nested objects
|
||||
* which is (generally) serialized as JSON by the store, so nested objects
|
||||
* are typically fine. For example below is a user-specific view counter:
|
||||
*
|
||||
* connect(
|
||||
|
|
@ -131,7 +131,7 @@ exports.ignore = [];
|
|||
* req.session.destroy(function(err){
|
||||
* // cannot access session here
|
||||
* });
|
||||
*
|
||||
*
|
||||
* ## Session#reload()
|
||||
*
|
||||
* Reloads the session data.
|
||||
|
|
@ -199,147 +199,154 @@ exports.ignore = [];
|
|||
* @api public
|
||||
*/
|
||||
|
||||
function session(options){
|
||||
var options = options || {}
|
||||
, key = options.key || 'connect.sid'
|
||||
, secret = options.secret
|
||||
, store = options.store || new MemoryStore
|
||||
, fingerprint = options.fingerprint || defaultFingerprint
|
||||
, cookie = options.cookie;
|
||||
function session( options ) {
|
||||
var options = options || {}
|
||||
, key = options.key || 'connect.sid'
|
||||
, secret = options.secret
|
||||
, store = options.store || new MemoryStore
|
||||
, fingerprint = options.fingerprint || defaultFingerprint
|
||||
, cookie = options.cookie;
|
||||
|
||||
// notify user that this store is not
|
||||
// meant for a production environment
|
||||
if ('production' == env && store instanceof MemoryStore) {
|
||||
console.warn(warning);
|
||||
}
|
||||
// notify user that this store is not
|
||||
// meant for a production environment
|
||||
if ( 'production' == env && store instanceof MemoryStore ) {
|
||||
console.warn( warning );
|
||||
}
|
||||
|
||||
// ensure secret is present
|
||||
if (!secret) {
|
||||
throw new Error('connect.session({ secret: "string" }) required for security');
|
||||
}
|
||||
// ensure secret is present
|
||||
if ( !secret ) {
|
||||
throw new Error( 'connect.session({ secret: "string" }) required for security' );
|
||||
}
|
||||
|
||||
// session hashing function
|
||||
store.hash = function(req, base) {
|
||||
return crypto
|
||||
.createHmac('sha256', secret)
|
||||
.update(base + fingerprint(req))
|
||||
.digest('base64')
|
||||
.replace(/=*$/, '');
|
||||
};
|
||||
// session hashing function
|
||||
store.hash = function ( req, base ) {
|
||||
return crypto
|
||||
.createHmac( 'sha256', secret )
|
||||
.update( base + fingerprint( req ) )
|
||||
.digest( 'base64' )
|
||||
.replace( /=*$/, '' );
|
||||
};
|
||||
|
||||
// generates the new session
|
||||
store.generate = function(req){
|
||||
var base = utils.uid(24);
|
||||
var sessionID = base + '.' + store.hash(req, base);
|
||||
req.sessionID = sessionID;
|
||||
req.session = new Session(req);
|
||||
req.session.cookie = new Cookie(cookie);
|
||||
};
|
||||
// generates the new session
|
||||
store.generate = function ( req ) {
|
||||
var base = utils.uid( 24 );
|
||||
var sessionID = base + '.' + store.hash( req, base );
|
||||
req.sessionID = sessionID;
|
||||
req.session = new Session( req );
|
||||
req.session.cookie = new Cookie( cookie );
|
||||
};
|
||||
|
||||
return function session(req, res, next) {
|
||||
// self-awareness
|
||||
if (req.session) return next();
|
||||
return function session( req, res, next ) {
|
||||
// self-awareness
|
||||
if ( req.session ) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// parse url
|
||||
var url = parse(req.url)
|
||||
, path = url.pathname;
|
||||
// parse url
|
||||
var url = parse( req.url )
|
||||
, path = url.pathname;
|
||||
|
||||
// ignorable paths
|
||||
if (~exports.ignore.indexOf(path)) return next();
|
||||
// ignorable paths
|
||||
if ( ~exports.ignore.indexOf( path ) ) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// expose store
|
||||
req.sessionStore = store;
|
||||
// expose store
|
||||
req.sessionStore = store;
|
||||
|
||||
// proxy writeHead() to Set-Cookie
|
||||
var writeHead = res.writeHead;
|
||||
res.writeHead = function(status, headers){
|
||||
if (req.session) {
|
||||
var cookie = req.session.cookie;
|
||||
// only send secure session cookies when there is a secure connection.
|
||||
// proxySecure is a custom attribute to allow for a reverse proxy
|
||||
// to handle SSL connections and to communicate to connect over HTTP that
|
||||
// the incoming connection is secure.
|
||||
var secured = cookie.secure && (req.connection.encrypted || req.connection.proxySecure);
|
||||
if (secured || !cookie.secure) {
|
||||
res.setHeader('Set-Cookie', cookie.serialize(key, req.sessionID));
|
||||
}
|
||||
}
|
||||
// proxy writeHead() to Set-Cookie
|
||||
var writeHead = res.writeHead;
|
||||
res.writeHead = function ( status, headers ) {
|
||||
if ( req.session ) {
|
||||
var cookie = req.session.cookie;
|
||||
// only send secure session cookies when there is a secure connection.
|
||||
// proxySecure is a custom attribute to allow for a reverse proxy
|
||||
// to handle SSL connections and to communicate to connect over HTTP that
|
||||
// the incoming connection is secure.
|
||||
var secured = cookie.secure && (req.connection.encrypted || req.connection.proxySecure);
|
||||
if ( secured || !cookie.secure ) {
|
||||
res.setHeader( 'Set-Cookie', cookie.serialize( key, req.sessionID ) );
|
||||
}
|
||||
}
|
||||
|
||||
res.writeHead = writeHead;
|
||||
return res.writeHead(status, headers);
|
||||
};
|
||||
res.writeHead = writeHead;
|
||||
return res.writeHead( status, headers );
|
||||
};
|
||||
|
||||
// proxy end() to commit the session
|
||||
var end = res.end;
|
||||
res.end = function(data, encoding){
|
||||
res.end = end;
|
||||
if (req.session) {
|
||||
// HACK: ensure Set-Cookie for implicit writeHead()
|
||||
if (!res._header) res._implicitHeader();
|
||||
req.session.resetMaxAge();
|
||||
req.session.save(function(){
|
||||
res.end(data, encoding);
|
||||
});
|
||||
} else {
|
||||
res.end(data, encoding);
|
||||
}
|
||||
};
|
||||
// proxy end() to commit the session
|
||||
var end = res.end;
|
||||
res.end = function ( data, encoding ) {
|
||||
res.end = end;
|
||||
if ( req.session ) {
|
||||
// HACK: ensure Set-Cookie for implicit writeHead()
|
||||
if ( !res._header ) {
|
||||
res._implicitHeader();
|
||||
}
|
||||
req.session.resetMaxAge();
|
||||
req.session.save( function () {
|
||||
res.end( data, encoding );
|
||||
} );
|
||||
} else {
|
||||
res.end( data, encoding );
|
||||
}
|
||||
};
|
||||
|
||||
// session hashing
|
||||
function hash(base) {
|
||||
return store.hash(req, base);
|
||||
}
|
||||
// session hashing
|
||||
function hash( base ) {
|
||||
return store.hash( req, base );
|
||||
}
|
||||
|
||||
// generate the session
|
||||
function generate() {
|
||||
store.generate(req);
|
||||
}
|
||||
// generate the session
|
||||
function generate() {
|
||||
store.generate( req );
|
||||
}
|
||||
|
||||
// get the sessionID from the cookie
|
||||
req.sessionID = req.cookies[key];
|
||||
// get the sessionID from the cookie
|
||||
req.sessionID = req.cookies[key];
|
||||
|
||||
// make a new session if the browser doesn't send a sessionID
|
||||
if (!req.sessionID) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// make a new session if the browser doesn't send a sessionID
|
||||
if ( !req.sessionID ) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// check the fingerprint
|
||||
var parts = req.sessionID.split('.');
|
||||
if (parts[1] != hash(parts[0])) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// check the fingerprint
|
||||
var parts = req.sessionID.split( '.' );
|
||||
if ( parts[1] != hash( parts[0] ) ) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate the session object
|
||||
var pause = utils.pause(req);
|
||||
store.get(req.sessionID, function(err, sess){
|
||||
// proxy to resume() events
|
||||
var _next = next;
|
||||
next = function(err){
|
||||
_next(err);
|
||||
pause.resume();
|
||||
}
|
||||
// generate the session object
|
||||
var pause = utils.pause( req );
|
||||
store.get( req.sessionID, function ( err, sess ) {
|
||||
// proxy to resume() events
|
||||
var _next = next;
|
||||
next = function ( err ) {
|
||||
_next( err );
|
||||
pause.resume();
|
||||
}
|
||||
|
||||
// error handling
|
||||
if (err) {
|
||||
if ('ENOENT' == err.code) {
|
||||
generate();
|
||||
next();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
// no session
|
||||
} else if (!sess) {
|
||||
generate();
|
||||
next();
|
||||
// populate req.session
|
||||
} else {
|
||||
store.createSession(req, sess);
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
// error handling
|
||||
if ( err ) {
|
||||
if ( 'ENOENT' == err.code ) {
|
||||
generate();
|
||||
next();
|
||||
} else {
|
||||
next( err );
|
||||
}
|
||||
// no session
|
||||
} else if ( !sess ) {
|
||||
generate();
|
||||
next();
|
||||
// populate req.session
|
||||
} else {
|
||||
store.createSession( req, sess );
|
||||
next();
|
||||
}
|
||||
} );
|
||||
};
|
||||
}
|
||||
;
|
||||
|
|
|
|||
174
example/node/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
174
example/node/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*!
|
||||
* Connect - session - Cookie
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
|
|
@ -10,7 +9,7 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../../utils');
|
||||
var utils = require( '../../utils' );
|
||||
|
||||
/**
|
||||
* Initialize a new `Cookie` with the given `options`.
|
||||
|
|
@ -19,14 +18,16 @@ var utils = require('../../utils');
|
|||
* @api private
|
||||
*/
|
||||
|
||||
var Cookie = module.exports = function Cookie(options) {
|
||||
this.path = '/';
|
||||
this.httpOnly = true;
|
||||
this.maxAge = 14400000;
|
||||
if (options) utils.merge(this, options);
|
||||
this.originalMaxAge = undefined == this.originalMaxAge
|
||||
? this.maxAge
|
||||
: this.originalMaxAge;
|
||||
var Cookie = module.exports = function Cookie( options ) {
|
||||
this.path = '/';
|
||||
this.httpOnly = true;
|
||||
this.maxAge = 14400000;
|
||||
if ( options ) {
|
||||
utils.merge( this, options );
|
||||
}
|
||||
this.originalMaxAge = undefined == this.originalMaxAge
|
||||
? this.maxAge
|
||||
: this.originalMaxAge;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -35,92 +36,87 @@ var Cookie = module.exports = function Cookie(options) {
|
|||
|
||||
Cookie.prototype = {
|
||||
|
||||
/**
|
||||
* Set expires `date`.
|
||||
*
|
||||
* @param {Date} date
|
||||
* @api public
|
||||
*/
|
||||
|
||||
set expires(date) {
|
||||
this._expires = date;
|
||||
this.originalMaxAge = this.maxAge;
|
||||
},
|
||||
/**
|
||||
* Set expires `date`.
|
||||
*
|
||||
* @param {Date} date
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get expires `date`.
|
||||
*
|
||||
* @return {Date}
|
||||
* @api public
|
||||
*/
|
||||
set expires( date ) {
|
||||
this._expires = date;
|
||||
this.originalMaxAge = this.maxAge;
|
||||
},
|
||||
|
||||
get expires() {
|
||||
return this._expires;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set expires via max-age in `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @api public
|
||||
*/
|
||||
|
||||
set maxAge(ms) {
|
||||
this.expires = 'number' == typeof ms
|
||||
? new Date(Date.now() + ms)
|
||||
: ms;
|
||||
},
|
||||
/**
|
||||
* Get expires `date`.
|
||||
*
|
||||
* @return {Date}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get expires max-age in `ms`.
|
||||
*
|
||||
* @return {Number}
|
||||
* @api public
|
||||
*/
|
||||
get expires() {
|
||||
return this._expires;
|
||||
},
|
||||
|
||||
get maxAge() {
|
||||
return this.expires instanceof Date
|
||||
? this.expires.valueOf() - Date.now()
|
||||
: this.expires;
|
||||
},
|
||||
/**
|
||||
* Set expires via max-age in `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return cookie data object.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
set maxAge( ms ) {
|
||||
this.expires = 'number' == typeof ms
|
||||
? new Date( Date.now() + ms )
|
||||
: ms;
|
||||
},
|
||||
|
||||
get data() {
|
||||
return {
|
||||
originalMaxAge: this.originalMaxAge
|
||||
, expires: this._expires
|
||||
, secure: this.secure
|
||||
, httpOnly: this.httpOnly
|
||||
, domain: this.domain
|
||||
, path: this.path
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Get expires max-age in `ms`.
|
||||
*
|
||||
* @return {Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return a serialized cookie string.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
get maxAge() {
|
||||
return this.expires instanceof Date
|
||||
? this.expires.valueOf() - Date.now()
|
||||
: this.expires;
|
||||
},
|
||||
|
||||
serialize: function(name, val){
|
||||
return utils.serializeCookie(name, val, this.data);
|
||||
},
|
||||
/**
|
||||
* Return cookie data object.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return JSON representation of this cookie.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
toJSON: function(){
|
||||
return this.data;
|
||||
}
|
||||
get data() {
|
||||
return {
|
||||
originalMaxAge : this.originalMaxAge, expires : this._expires, secure : this.secure, httpOnly : this.httpOnly, domain : this.domain, path : this.path
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a serialized cookie string.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
serialize : function ( name, val ) {
|
||||
return utils.serializeCookie( name, val, this.data );
|
||||
},
|
||||
|
||||
/**
|
||||
* Return JSON representation of this cookie.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
toJSON : function () {
|
||||
return this.data;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue