annyang_rails 0.2.0 → 0.2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODY0NWUzZjVhZDkzNzE4NzU0ZWUxMGFkY2UwYzhkMGE3MGJmZGY0Zg==
4
+ YzE5NzFjZmY0ZTNhZThlOTA2NWExMDJjZGU5Y2VhYmRiYTY5NDY4OQ==
5
5
  data.tar.gz: !binary |-
6
- MzFjZjZiZmVlMGU5NzkwMDMyNzY5NWM5YmQ0YjNlOThlM2QyZjUxYw==
6
+ OTM1Njc4ZTAxYTgzOTIyYzQxYmIwZWY2MmI2M2I3NjM4YjQwMTk3OQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjI5MmI3MWEyYTFiMTkzN2E0NTU2MDNiNDkzZWFmY2U2MWFhMjM2Y2M2ZWZj
10
- ZjQ1NGVkMTg2NzA0M2ViYWQ5ZTRkZjA1NTlhNTZmYzhjNjA2ODAyNjA5YWE2
11
- OWVlMWI0NzIzNjY0ZDkwY2ExMjRiOGE3ZTUxOTI1YjRjNjFkOTI=
9
+ MDRhMjgwNGRmNjIyNjc3MjA5ZjhmN2E0YTE4MDc4ZWE3MzkzMzQ5Njk1MDkz
10
+ MWI5YjQ0NTFjYzE2Y2I1YTQzZDU5MzE5YTQ5MzA3NzdkYTk3N2ExZWU5ZmE1
11
+ MTNhOWY1NWM1NTJjY2IxM2E1N2VmNzRlNDAzODRjMmUzYWFmYWE=
12
12
  data.tar.gz: !binary |-
13
- MjA2NWI5YTcwMDNhNDg0YTQ3MTQxMTU2NzM1YTFmYWU2ZmU0M2Q4YWNjMTE5
14
- NmU1YmRiZDZhNzkzNGZmNDMyYzRhNGU2YWU4MDFlNTI2YTY1NmZjN2M2Yjcx
15
- MTEyOWY0NjM4MjdhMGZmZWQ3ZGVkMjJiMjQ4NTEwZWJjYjhhMTQ=
13
+ NGE5MTI5NzJkMjM4OThjMTU5OWE1ZTk3ZTdlMGIyOWE5ZWQzZTRjMmIzYjZi
14
+ M2UxNDVmZWI1ZWNjNDM0MTk4YTlkMDhhN2Q1OWZlZjliMDc0ODg4NzlhODBm
15
+ ZTk0Y2VhM2RlYTM0YTQ2N2Q1NGE5NDIwM2FhOTUwMGU4YjM4MDI=
@@ -1,20 +1,23 @@
1
- /*! annyang - speech recognition in js
2
- * version : 0.2.0
3
- * author : Tal Ater @TalAter
4
- * license : MIT
5
- * https://www.TalAter.com/annyang/
6
- * https://github.com/TalAter/annyang
7
- */
1
+ //! annyang
2
+ //! version : 0.2.0
3
+ //! author : Tal Ater @TalAter
4
+ //! license : MIT
5
+ //! https://www.TalAter.com/annyang/
8
6
  (function () {
9
7
  "use strict";
10
8
 
9
+ // Save a reference to the global object (window in the browser)
11
10
  var root = this;
11
+
12
+ // Get the SpeechRecognition object, while handling browser prefixes
12
13
  var SpeechRecognition = root.webkitSpeechRecognition ||
13
14
  root.mozSpeechRecognition ||
14
15
  root.msSpeechRecognition ||
15
16
  root.oSpeechRecognition ||
16
17
  root.SpeechRecognition;
18
+
17
19
  // Check browser support
20
+ // This is done as early as possible, to make it as fast as possible for unsupported browsers
18
21
  if ( !SpeechRecognition ) {
19
22
  root.annyang = null;
20
23
  return null;
@@ -23,12 +26,12 @@
23
26
  var commandsList;
24
27
  var recognition;
25
28
  var lang = 'en-US';
26
- var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [] };
29
+ var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };
27
30
  var autoRestart;
31
+ var lastStartedAt = 0;
28
32
  var debugState = false;
29
33
  var debugStyle = 'font-weight: bold; color: #00f;';
30
34
 
31
-
32
35
  // The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
33
36
  var optionalParam = /\s*\((.*?)\)\s*/g;
34
37
  var optionalRegex = /(\(\?:[^)]+\))\?/g;
@@ -46,13 +49,17 @@
46
49
  return new RegExp('^' + command + '$', 'i');
47
50
  };
48
51
 
52
+ // This method receives an array of callbacks to iterate over, and invokes each of them
49
53
  var invokeCallbacks = function(callbacks) {
50
54
  for (var j = 0, l = callbacks.length; j < l; j++) {
51
- callbacks[j].apply(this);
55
+ callbacks[j].callback.apply(callbacks[j].context);
52
56
  }
53
57
  };
54
58
 
55
59
  root.annyang = {
60
+ // Initialize annyang with a list of commands to recognize.
61
+ // e.g. annyang.init({'hello :name': helloFunction})
62
+ // annyang understands commands with named variables, splats, and optional words.
56
63
  init: function(commands) {
57
64
 
58
65
  // Abort previous instances of recognition already running
@@ -60,21 +67,48 @@
60
67
  recognition.abort();
61
68
  }
62
69
 
63
- // initiate
70
+ // initiate SpeechRecognition
64
71
  recognition = new SpeechRecognition();
65
72
 
73
+ // Set the max number of alternative transcripts to try and match with a command
66
74
  recognition.maxAlternatives = 5;
67
75
  recognition.continuous = true;
76
+ // Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()
68
77
  recognition.lang = lang;
69
78
 
70
79
  recognition.onstart = function() { invokeCallbacks(callbacks.start); };
71
80
 
72
- recognition.onerror = function() { invokeCallbacks(callbacks.error); };
81
+ recognition.onerror = function(event) {
82
+ invokeCallbacks(callbacks.error);
83
+ switch (event.error) {
84
+ case 'network':
85
+ invokeCallbacks(callbacks.errorNetwork);
86
+ break;
87
+ case 'not-allowed':
88
+ case 'service-not-allowed':
89
+ // if permission to use the mic is denied, turn off auto-restart
90
+ autoRestart = false;
91
+ // determine if permission was denied by user or automatically.
92
+ if (new Date().getTime()-lastStartedAt < 200) {
93
+ invokeCallbacks(callbacks.errorPermissionBlocked);
94
+ } else {
95
+ invokeCallbacks(callbacks.errorPermissionDenied);
96
+ }
97
+ break;
98
+ }
99
+ };
73
100
 
74
101
  recognition.onend = function() {
75
102
  invokeCallbacks(callbacks.end);
103
+ // annyang will auto restart if it is closed automatically and not by user action.
76
104
  if (autoRestart) {
77
- root.annyang.start();
105
+ // play nicely with the browser, and never restart annyang automatically more than once per second
106
+ var timeSinceLastStart = new Date().getTime()-lastStartedAt;
107
+ if (timeSinceLastStart < 1000) {
108
+ setTimeout(root.annyang.start, 1000-timeSinceLastStart);
109
+ } else {
110
+ root.annyang.start();
111
+ }
78
112
  }
79
113
  };
80
114
 
@@ -82,12 +116,15 @@
82
116
  invokeCallbacks(callbacks.result);
83
117
  var results = event.results[event.resultIndex];
84
118
  var commandText;
119
+ // go over each of the 5 results and alternative results received (we've set maxAlternatives to 5 above)
85
120
  for (var i = 0; i<results.length; i++) {
121
+ // the text recognized
86
122
  commandText = results[i].transcript.trim();
87
123
  if (debugState) {
88
124
  root.console.log('Speech recognized: %c'+commandText, debugStyle);
89
125
  }
90
126
 
127
+ // try and match recognized text to one of the commands on the list
91
128
  for (var j = 0, l = commandsList.length; j < l; j++) {
92
129
  var result = commandsList[j].command.exec(commandText);
93
130
  if (result) {
@@ -98,6 +135,7 @@
98
135
  root.console.log('with parameters', parameters);
99
136
  }
100
137
  }
138
+ // execute the matched command
101
139
  commandsList[j].callback.apply(this, parameters);
102
140
  invokeCallbacks(callbacks.resultMatch);
103
141
  return true;
@@ -113,21 +151,28 @@
113
151
  this.addCommands(commands);
114
152
  },
115
153
 
154
+ // Start listening (asking for permission first, if needed).
155
+ // Call this after you've initialized annyang with commands.
156
+ // Receives an optional options object:
157
+ // { autoRestart: true }
116
158
  start: function(options) {
117
159
  options = options || {};
118
- if (typeof options.autoRestart !== 'undefined') {
160
+ if (options.autoRestart !== void 0) {
119
161
  autoRestart = !!options.autoRestart;
120
162
  } else {
121
163
  autoRestart = true;
122
164
  }
165
+ lastStartedAt = new Date().getTime();
123
166
  recognition.start();
124
167
  },
125
168
 
169
+ // abort the listening session (aka stop)
126
170
  abort: function() {
127
171
  autoRestart = false;
128
172
  recognition.abort();
129
173
  },
130
174
 
175
+ // Turn on output of debug messages to the console. Ugly, but super-handy!
131
176
  debug: function(newState) {
132
177
  if (arguments.length > 0) {
133
178
  debugState = !!newState;
@@ -136,6 +181,8 @@
136
181
  }
137
182
  },
138
183
 
184
+ // Set the language the user will speak in. If not called, defaults to 'en-US'.
185
+ // e.g. 'fr-FR' (French-France), 'es-CR' (Español-Costa Rica)
139
186
  setLanguage: function(language) {
140
187
  lang = language;
141
188
  if (recognition && recognition.abort) {
@@ -143,6 +190,7 @@
143
190
  }
144
191
  },
145
192
 
193
+ // Add additional commands that annyang will respond to. Similar in syntax to annyang.init()
146
194
  addCommands: function(commands) {
147
195
  var cb,
148
196
  command;
@@ -163,10 +211,10 @@
163
211
  }
164
212
  },
165
213
 
166
- /**
167
- * Lets the user add a callback of one of 6 types: start, error, end, result, resultMatch, resultNoMatch
168
- */
169
- addCallback: function(type, callback) {
214
+ // Lets the user add a callback of one of 9 types:
215
+ // start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied
216
+ // Can also optionally receive a context for the callback function as the third argument
217
+ addCallback: function(type, callback, context) {
170
218
  if (callbacks[type] === void 0) {
171
219
  return;
172
220
  }
@@ -174,7 +222,7 @@
174
222
  if (typeof cb !== 'function') {
175
223
  return;
176
224
  }
177
- callbacks[type].push(cb);
225
+ callbacks[type].push({callback: cb, context: context || this});
178
226
  }
179
227
  };
180
228
 
@@ -1,3 +1,3 @@
1
1
  module AnnyangRails
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.0.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: annyang_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guy Israeli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-16 00:00:00.000000000 Z
11
+ date: 2013-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler