webrtc_rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/webrtc_rails/application.js +16 -0
- data/app/assets/javascripts/webrtc_rails/rooms.js +141 -0
- data/app/assets/stylesheets/webrtc_rails/application.css +13 -0
- data/app/assets/stylesheets/webrtc_rails/rooms.css +4 -0
- data/app/controllers/webrtc_rails/application_controller.rb +2 -0
- data/app/controllers/webrtc_rails/rooms_controller.rb +31 -0
- data/app/helpers/webrtc_rails/application_helper.rb +4 -0
- data/app/helpers/webrtc_rails/videoconfs_helper.rb +4 -0
- data/app/models/uri_string.rb +0 -0
- data/app/views/layouts/webrtc_rails/application.html.erb +17 -0
- data/app/views/webrtc_rails/rooms/new.html.erb +15 -0
- data/app/views/webrtc_rails/rooms/show.html.erb +19 -0
- data/config/locales/en.yml +4 -0
- data/config/locales/es.yml +4 -0
- data/config/routes.rb +3 -0
- data/lib/tasks/webrtc_rails_tasks.rake +4 -0
- data/lib/webrtc_rails.rb +8 -0
- data/lib/webrtc_rails/engine.rb +5 -0
- data/lib/webrtc_rails/parameterizable_validator.rb +7 -0
- data/lib/webrtc_rails/room.rb +20 -0
- data/lib/webrtc_rails/version.rb +3 -0
- data/test/controllers/webrtc_rails/videoconfs_controller_test.rb +9 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +6 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/helpers/webrtc_rails/videoconfs_helper_test.rb +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/webrtc_rails_test.rb +7 -0
- data/vendor/assets/javascripts/webrtc_rails/getusermedia.js +68 -0
- data/vendor/assets/javascripts/webrtc_rails/hark.js +256 -0
- data/vendor/assets/javascripts/webrtc_rails/simplewebrtc.js +5 -0
- metadata +212 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/404.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
54
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/422.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The change you wanted was rejected.</h1>
|
54
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/500.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>We're sorry, but something went wrong.</h1>
|
54
|
+
</div>
|
55
|
+
<p>If you are the application owner check the logs for more information.</p>
|
56
|
+
</body>
|
57
|
+
</html>
|
File without changes
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
+
require "rails/test_help"
|
6
|
+
|
7
|
+
Rails.backtrace_cleaner.remove_silencers!
|
8
|
+
|
9
|
+
# Load support files
|
10
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
11
|
+
|
12
|
+
# Load fixtures from the engine
|
13
|
+
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
14
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
15
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.getUserMedia=e():"undefined"!=typeof global?global.getUserMedia=e():"undefined"!=typeof self&&(self.getUserMedia=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
2
|
+
// getUserMedia helper by @HenrikJoreteg
|
3
|
+
var func = (window.navigator.getUserMedia ||
|
4
|
+
window.navigator.webkitGetUserMedia ||
|
5
|
+
window.navigator.mozGetUserMedia ||
|
6
|
+
window.navigator.msGetUserMedia);
|
7
|
+
|
8
|
+
|
9
|
+
module.exports = function (constraints, cb) {
|
10
|
+
var options;
|
11
|
+
var haveOpts = arguments.length === 2;
|
12
|
+
var defaultOpts = {video: true, audio: true};
|
13
|
+
var error;
|
14
|
+
var denied = 'PERMISSION_DENIED';
|
15
|
+
var notSatified = 'CONSTRAINT_NOT_SATISFIED';
|
16
|
+
|
17
|
+
// make constraints optional
|
18
|
+
if (!haveOpts) {
|
19
|
+
cb = constraints;
|
20
|
+
constraints = defaultOpts;
|
21
|
+
}
|
22
|
+
|
23
|
+
// treat lack of browser support like an error
|
24
|
+
if (!func) {
|
25
|
+
// throw proper error per spec
|
26
|
+
error = new Error('NavigatorUserMediaError');
|
27
|
+
error.name = 'NOT_SUPPORTED_ERROR';
|
28
|
+
return cb(error);
|
29
|
+
}
|
30
|
+
|
31
|
+
func.call(window.navigator, constraints, function (stream) {
|
32
|
+
cb(null, stream);
|
33
|
+
}, function (err) {
|
34
|
+
var error;
|
35
|
+
// coerce into an error object since FF gives us a string
|
36
|
+
// there are only two valid names according to the spec
|
37
|
+
// we coerce all non-denied to "constraint not satisfied".
|
38
|
+
if (typeof err === 'string') {
|
39
|
+
error = new Error('NavigatorUserMediaError');
|
40
|
+
if (err === denied) {
|
41
|
+
error.name = denied;
|
42
|
+
} else {
|
43
|
+
error.name = notSatified;
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
// if we get an error object make sure '.name' property is set
|
47
|
+
// according to spec: http://dev.w3.org/2011/webrtc/editor/getusermedia.html#navigatorusermediaerror-and-navigatorusermediaerrorcallback
|
48
|
+
error = err;
|
49
|
+
if (!error.name) {
|
50
|
+
// this is likely chrome which
|
51
|
+
// sets a property called "ERROR_DENIED" on the error object
|
52
|
+
// if so we make sure to set a name
|
53
|
+
if (error[denied]) {
|
54
|
+
err.name = denied;
|
55
|
+
} else {
|
56
|
+
err.name = notSatified;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
cb(error);
|
62
|
+
});
|
63
|
+
};
|
64
|
+
|
65
|
+
},{}]},{},[1])
|
66
|
+
(1)
|
67
|
+
});
|
68
|
+
;
|
@@ -0,0 +1,256 @@
|
|
1
|
+
(function(e){if("function"==typeof bootstrap)bootstrap("hark",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeHark=e}else"undefined"!=typeof window?window.hark=e():global.hark=e()})(function(){var define,ses,bootstrap,module,exports;
|
2
|
+
return (function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
|
3
|
+
var WildEmitter = require('wildemitter');
|
4
|
+
|
5
|
+
function getMaxVolume (analyser, fftBins) {
|
6
|
+
var maxVolume = -Infinity;
|
7
|
+
analyser.getFloatFrequencyData(fftBins);
|
8
|
+
|
9
|
+
for(var i=0, ii=fftBins.length; i < ii; i++) {
|
10
|
+
if (fftBins[i] > maxVolume && fftBins[i] < 0) {
|
11
|
+
maxVolume = fftBins[i];
|
12
|
+
}
|
13
|
+
};
|
14
|
+
|
15
|
+
return maxVolume;
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
var audioContextType = window.webkitAudioContext || window.AudioContext;
|
20
|
+
// use a single audio context due to hardware limits
|
21
|
+
var audioContext = null;
|
22
|
+
module.exports = function(stream, options) {
|
23
|
+
var harker = new WildEmitter();
|
24
|
+
|
25
|
+
|
26
|
+
// make it not break in non-supported browsers
|
27
|
+
if (!audioContextType) return harker;
|
28
|
+
|
29
|
+
//Config
|
30
|
+
var options = options || {},
|
31
|
+
smoothing = (options.smoothing || 0.5),
|
32
|
+
interval = (options.interval || 100),
|
33
|
+
threshold = options.threshold,
|
34
|
+
play = options.play,
|
35
|
+
running = true;
|
36
|
+
|
37
|
+
//Setup Audio Context
|
38
|
+
if (!audioContext) {
|
39
|
+
audioContext = new audioContextType();
|
40
|
+
}
|
41
|
+
var sourceNode, fftBins, analyser;
|
42
|
+
|
43
|
+
analyser = audioContext.createAnalyser();
|
44
|
+
analyser.fftSize = 512;
|
45
|
+
analyser.smoothingTimeConstant = smoothing;
|
46
|
+
fftBins = new Float32Array(analyser.fftSize);
|
47
|
+
|
48
|
+
if (stream.jquery) stream = stream[0];
|
49
|
+
if (stream instanceof HTMLAudioElement) {
|
50
|
+
//Audio Tag
|
51
|
+
sourceNode = audioContext.createMediaElementSource(stream);
|
52
|
+
if (typeof play === 'undefined') play = true;
|
53
|
+
threshold = threshold || -65;
|
54
|
+
} else {
|
55
|
+
//WebRTC Stream
|
56
|
+
sourceNode = audioContext.createMediaStreamSource(stream);
|
57
|
+
threshold = threshold || -45;
|
58
|
+
}
|
59
|
+
|
60
|
+
sourceNode.connect(analyser);
|
61
|
+
if (play) analyser.connect(audioContext.destination);
|
62
|
+
|
63
|
+
harker.speaking = false;
|
64
|
+
|
65
|
+
harker.setThreshold = function(t) {
|
66
|
+
threshold = t;
|
67
|
+
};
|
68
|
+
|
69
|
+
harker.setInterval = function(i) {
|
70
|
+
interval = i;
|
71
|
+
};
|
72
|
+
|
73
|
+
harker.stop = function() {
|
74
|
+
running = false;
|
75
|
+
harker.emit('volume_change', -100, threshold);
|
76
|
+
if (harker.speaking) {
|
77
|
+
harker.speaking = false;
|
78
|
+
harker.emit('stopped_speaking');
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
// Poll the analyser node to determine if speaking
|
83
|
+
// and emit events if changed
|
84
|
+
var looper = function() {
|
85
|
+
setTimeout(function() {
|
86
|
+
|
87
|
+
//check if stop has been called
|
88
|
+
if(!running) {
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
|
92
|
+
var currentVolume = getMaxVolume(analyser, fftBins);
|
93
|
+
|
94
|
+
harker.emit('volume_change', currentVolume, threshold);
|
95
|
+
|
96
|
+
if (currentVolume > threshold) {
|
97
|
+
if (!harker.speaking) {
|
98
|
+
harker.speaking = true;
|
99
|
+
harker.emit('speaking');
|
100
|
+
}
|
101
|
+
} else {
|
102
|
+
if (harker.speaking) {
|
103
|
+
harker.speaking = false;
|
104
|
+
harker.emit('stopped_speaking');
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
looper();
|
109
|
+
}, interval);
|
110
|
+
};
|
111
|
+
looper();
|
112
|
+
|
113
|
+
|
114
|
+
return harker;
|
115
|
+
}
|
116
|
+
|
117
|
+
},{"wildemitter":2}],2:[function(require,module,exports){
|
118
|
+
/*
|
119
|
+
WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based
|
120
|
+
on @visionmedia's Emitter from UI Kit.
|
121
|
+
|
122
|
+
Why? I wanted it standalone.
|
123
|
+
|
124
|
+
I also wanted support for wildcard emitters like this:
|
125
|
+
|
126
|
+
emitter.on('*', function (eventName, other, event, payloads) {
|
127
|
+
|
128
|
+
});
|
129
|
+
|
130
|
+
emitter.on('somenamespace*', function (eventName, payloads) {
|
131
|
+
|
132
|
+
});
|
133
|
+
|
134
|
+
Please note that callbacks triggered by wildcard registered events also get
|
135
|
+
the event name as the first argument.
|
136
|
+
*/
|
137
|
+
module.exports = WildEmitter;
|
138
|
+
|
139
|
+
function WildEmitter() {
|
140
|
+
this.callbacks = {};
|
141
|
+
}
|
142
|
+
|
143
|
+
// Listen on the given `event` with `fn`. Store a group name if present.
|
144
|
+
WildEmitter.prototype.on = function (event, groupName, fn) {
|
145
|
+
var hasGroup = (arguments.length === 3),
|
146
|
+
group = hasGroup ? arguments[1] : undefined,
|
147
|
+
func = hasGroup ? arguments[2] : arguments[1];
|
148
|
+
func._groupName = group;
|
149
|
+
(this.callbacks[event] = this.callbacks[event] || []).push(func);
|
150
|
+
return this;
|
151
|
+
};
|
152
|
+
|
153
|
+
// Adds an `event` listener that will be invoked a single
|
154
|
+
// time then automatically removed.
|
155
|
+
WildEmitter.prototype.once = function (event, groupName, fn) {
|
156
|
+
var self = this,
|
157
|
+
hasGroup = (arguments.length === 3),
|
158
|
+
group = hasGroup ? arguments[1] : undefined,
|
159
|
+
func = hasGroup ? arguments[2] : arguments[1];
|
160
|
+
function on() {
|
161
|
+
self.off(event, on);
|
162
|
+
func.apply(this, arguments);
|
163
|
+
}
|
164
|
+
this.on(event, group, on);
|
165
|
+
return this;
|
166
|
+
};
|
167
|
+
|
168
|
+
// Unbinds an entire group
|
169
|
+
WildEmitter.prototype.releaseGroup = function (groupName) {
|
170
|
+
var item, i, len, handlers;
|
171
|
+
for (item in this.callbacks) {
|
172
|
+
handlers = this.callbacks[item];
|
173
|
+
for (i = 0, len = handlers.length; i < len; i++) {
|
174
|
+
if (handlers[i]._groupName === groupName) {
|
175
|
+
//console.log('removing');
|
176
|
+
// remove it and shorten the array we're looping through
|
177
|
+
handlers.splice(i, 1);
|
178
|
+
i--;
|
179
|
+
len--;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
return this;
|
184
|
+
};
|
185
|
+
|
186
|
+
// Remove the given callback for `event` or all
|
187
|
+
// registered callbacks.
|
188
|
+
WildEmitter.prototype.off = function (event, fn) {
|
189
|
+
var callbacks = this.callbacks[event],
|
190
|
+
i;
|
191
|
+
|
192
|
+
if (!callbacks) return this;
|
193
|
+
|
194
|
+
// remove all handlers
|
195
|
+
if (arguments.length === 1) {
|
196
|
+
delete this.callbacks[event];
|
197
|
+
return this;
|
198
|
+
}
|
199
|
+
|
200
|
+
// remove specific handler
|
201
|
+
i = callbacks.indexOf(fn);
|
202
|
+
callbacks.splice(i, 1);
|
203
|
+
return this;
|
204
|
+
};
|
205
|
+
|
206
|
+
// Emit `event` with the given args.
|
207
|
+
// also calls any `*` handlers
|
208
|
+
WildEmitter.prototype.emit = function (event) {
|
209
|
+
var args = [].slice.call(arguments, 1),
|
210
|
+
callbacks = this.callbacks[event],
|
211
|
+
specialCallbacks = this.getWildcardCallbacks(event),
|
212
|
+
i,
|
213
|
+
len,
|
214
|
+
item;
|
215
|
+
|
216
|
+
if (callbacks) {
|
217
|
+
for (i = 0, len = callbacks.length; i < len; ++i) {
|
218
|
+
if (callbacks[i]) {
|
219
|
+
callbacks[i].apply(this, args);
|
220
|
+
} else {
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
if (specialCallbacks) {
|
227
|
+
for (i = 0, len = specialCallbacks.length; i < len; ++i) {
|
228
|
+
if (specialCallbacks[i]) {
|
229
|
+
specialCallbacks[i].apply(this, [event].concat(args));
|
230
|
+
} else {
|
231
|
+
break;
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
return this;
|
237
|
+
};
|
238
|
+
|
239
|
+
// Helper for for finding special wildcard event handlers that match the event
|
240
|
+
WildEmitter.prototype.getWildcardCallbacks = function (eventName) {
|
241
|
+
var item,
|
242
|
+
split,
|
243
|
+
result = [];
|
244
|
+
|
245
|
+
for (item in this.callbacks) {
|
246
|
+
split = item.split('*');
|
247
|
+
if (item === '*' || (split.length === 2 && eventName.slice(0, split[1].length) === split[1])) {
|
248
|
+
result = result.concat(this.callbacks[item]);
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return result;
|
252
|
+
};
|
253
|
+
|
254
|
+
},{}]},{},[1])(1)
|
255
|
+
});
|
256
|
+
;
|