annyang-rails 0.2.0 → 1.4.0

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDdiZTM4YmVjNTg1Zjk4NTg4NmNiYzRhN2JjYjViNjAyMGZjZGQxMQ==
5
+ data.tar.gz: !binary |-
6
+ MDAwNDUxY2Y0MWU0NWZlMmNlZTM5ZDZjMTRhZTEwYTc5Y2Q3ZjZiMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NDVhMzhhY2RjOGQ4NGE1ZmU0MWMyNWNlODYxZDU4NzY5MTI3NWJhMGEzYTI0
10
+ MjlkNGVlNGRkNjRjNDRjY2ExMGY5Yzk5ZTI0OWI3NWY3MWQ4ZjkzYzg3MjYw
11
+ Njg4MjgzZmE0MGMyZjFjYzdiNGFiYjU3MmM3N2ZlN2U3NWU2MGY=
12
+ data.tar.gz: !binary |-
13
+ ZDZiMzc1NDkwMDE3ODU0ODFlM2NhNTJkNDkxYzRjOGRhNWNmYzYyOGViYjRi
14
+ ZjBjZDc4OTEwZGUzODExMGQzNjMwOTYzMDdlYTNjNGJlNGRlMWQ2YmJlNjI2
15
+ YmRlODE5ZDk0ODBiN2IxOGMyN2UyYzEzOWZjN2VhZTc4N2RmZWU=
data/Manifest CHANGED
@@ -1,5 +1,6 @@
1
1
  README.md
2
2
  Rakefile
3
+ annyang-rails.gemspec
3
4
  app/helpers/annyang_helper.rb
4
5
  init.rb
5
6
  lib/annyang-rails.rb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # annyang for Rails Asset Pipeline
1
+ # annyang for Rails Asset Pipeline [![Gem Version](https://badge.fury.io/rb/annyang-rails.png)](http://badge.fury.io/rb/annyang-rails)
2
2
 
3
3
  [annyang](https://github.com/TalAter/annyang) is a tiny javascript SpeechRecognition library that lets your users control your site with voice commands. ([documentation](https://www.talater.com/annyang/)).
4
4
 
@@ -90,3 +90,18 @@ if (annyang) {
90
90
  ````
91
91
 
92
92
  **For more details, [visit the demo and docs site](https://www.talater.com/annyang).**
93
+
94
+ ## Contributors
95
+
96
+ 1. [Ahmad Hussain](https://github.com/ahmad-hussain-confiz)
97
+ 2. [Usman Ali](https://github.com/usman-ali-confiz)
98
+ 3. [Kinaan Khan Sherwani](https://github.com/kinaan-khan-confiz)
99
+
100
+
101
+ ## Contributing
102
+
103
+ 1. Fork it
104
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
105
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
106
+ 4. Push to the branch (`git push origin my-new-feature`)
107
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ Echoe.new('annyang-rails', '0.2.0') do |p|
6
6
  p.description = "A tiny javascript SpeechRecognition library that lets your users control your site with voice commands."
7
7
  p.url = "http://github.com/confiz/annyang-rails"
8
8
  p.author = "Confiz Limited"
9
- p.email = "opensource@confiz.com"
9
+ p.email = "ahmad.hussain@confiz.com"
10
10
  p.ignore_pattern = ["tmp/*", "script/*"]
11
11
  p.development_dependencies = []
12
12
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "annyang-rails"
5
- s.version = "0.2.0"
5
+ s.version = "1.4.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Confiz Limited"]
9
- s.date = "2013-12-09"
9
+ s.date = "2014-09-02"
10
10
  s.description = "A tiny javascript SpeechRecognition library that lets your users control your site with voice commands."
11
11
  s.email = "opensource@confiz.com"
12
12
  s.extra_rdoc_files = ["README.md", "lib/annyang-rails.rb", "lib/annyang-rails/version.rb"]
@@ -1,31 +1,41 @@
1
1
  //! annyang
2
- //! version : 0.2.0
2
+ //! version : 1.4.0
3
3
  //! author : Tal Ater @TalAter
4
4
  //! license : MIT
5
5
  //! https://www.TalAter.com/annyang/
6
- (function () {
6
+
7
+ (function (undefined) {
7
8
  "use strict";
8
9
 
10
+ /**
11
+ * # Quick Tutorial, Intro and Demos
12
+ *
13
+ * The quickest way to get started is to visit the [annyang homepage](https://www.talater.com/annyang/).
14
+ *
15
+ * For a more in-depth look at annyang, read on.
16
+ *
17
+ * # API Reference
18
+ */
19
+
9
20
  // Save a reference to the global object (window in the browser)
10
21
  var root = this;
11
22
 
12
23
  // Get the SpeechRecognition object, while handling browser prefixes
13
- var SpeechRecognition = root.webkitSpeechRecognition ||
24
+ var SpeechRecognition = root.SpeechRecognition ||
25
+ root.webkitSpeechRecognition ||
14
26
  root.mozSpeechRecognition ||
15
27
  root.msSpeechRecognition ||
16
- root.oSpeechRecognition ||
17
- root.SpeechRecognition;
28
+ root.oSpeechRecognition;
18
29
 
19
30
  // Check browser support
20
31
  // This is done as early as possible, to make it as fast as possible for unsupported browsers
21
- if ( !SpeechRecognition ) {
32
+ if (!SpeechRecognition) {
22
33
  root.annyang = null;
23
- return null;
34
+ return undefined;
24
35
  }
25
36
 
26
- var commandsList;
37
+ var commandsList = [];
27
38
  var recognition;
28
- var lang = 'en-US';
29
39
  var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };
30
40
  var autoRestart;
31
41
  var lastStartedAt = 0;
@@ -51,16 +61,52 @@
51
61
 
52
62
  // This method receives an array of callbacks to iterate over, and invokes each of them
53
63
  var invokeCallbacks = function(callbacks) {
54
- for (var j = 0, l = callbacks.length; j < l; j++) {
55
- callbacks[j].callback.apply(callbacks[j].context);
64
+ callbacks.forEach(function(callback) {
65
+ callback.callback.apply(callback.context);
66
+ });
67
+ };
68
+
69
+ var initIfNeeded = function() {
70
+ if (!isInitialized()) {
71
+ root.annyang.init({}, false);
56
72
  }
57
73
  };
58
74
 
75
+ var isInitialized = function() {
76
+ return recognition !== undefined;
77
+ };
78
+
59
79
  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.
63
- init: function(commands) {
80
+
81
+ /**
82
+ * Initialize annyang with a list of commands to recognize.
83
+ *
84
+ * ### Examples:
85
+ *
86
+ * var commands = {'hello :name': helloFunction};
87
+ * var commands2 = {'hi': helloFunction};
88
+ *
89
+ * // initialize annyang, overwriting any previously added commands
90
+ * annyang.init(commands, true);
91
+ * // adds an additional command without removing the previous commands
92
+ * annyang.init(commands2, false);
93
+ *
94
+ * As of v1.1.0 it is no longer required to call init(). Just start() listening whenever you want, and addCommands() whenever, and as often as you like.
95
+ *
96
+ * @param {Object} commands - Commands that annyang should listen to
97
+ * @param {Boolean} [resetCommands=true] - Remove all commands before initializing?
98
+ * @method init
99
+ * @deprecated
100
+ * @see [Commands Object](#commands-object)
101
+ */
102
+ init: function(commands, resetCommands) {
103
+
104
+ // resetCommands defaults to true
105
+ if (resetCommands === undefined) {
106
+ resetCommands = true;
107
+ } else {
108
+ resetCommands = !!resetCommands;
109
+ }
64
110
 
65
111
  // Abort previous instances of recognition already running
66
112
  if (recognition && recognition.abort) {
@@ -72,9 +118,13 @@
72
118
 
73
119
  // Set the max number of alternative transcripts to try and match with a command
74
120
  recognition.maxAlternatives = 5;
75
- recognition.continuous = true;
121
+
122
+ // In HTTPS, turn off continuous mode for faster results.
123
+ // In HTTP, turn on continuous mode for much slower results, but no repeating security notices
124
+ recognition.continuous = root.location.protocol === 'http:';
125
+
76
126
  // Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()
77
- recognition.lang = lang;
127
+ recognition.lang = 'en-US';
78
128
 
79
129
  recognition.onstart = function() { invokeCallbacks(callbacks.start); };
80
130
 
@@ -147,17 +197,32 @@
147
197
  };
148
198
 
149
199
  // build commands list
150
- commandsList = [];
151
- this.addCommands(commands);
200
+ if (resetCommands) {
201
+ commandsList = [];
202
+ }
203
+ if (commands.length) {
204
+ this.addCommands(commands);
205
+ }
152
206
  },
153
207
 
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 }
208
+ /**
209
+ * Start listening.
210
+ * It's a good idea to call this after adding some commands first, but not mandatory.
211
+ *
212
+ * Receives an optional options object which currently only supports one option:
213
+ * - `autoRestart` (Boolean, default: true) Should annyang restart itself if it is closed indirectly, because of silence or window conflicts?
214
+ *
215
+ * ### Examples:
216
+ * // Start listening, but don't restart automatically
217
+ * annyang.start({ autoRestart: false });
218
+ *
219
+ * @param {Object} [options] - Optional options.
220
+ * @method start
221
+ */
158
222
  start: function(options) {
223
+ initIfNeeded();
159
224
  options = options || {};
160
- if (options.autoRestart !== void 0) {
225
+ if (options.autoRestart !== undefined) {
161
226
  autoRestart = !!options.autoRestart;
162
227
  } else {
163
228
  autoRestart = true;
@@ -166,13 +231,24 @@
166
231
  recognition.start();
167
232
  },
168
233
 
169
- // abort the listening session (aka stop)
234
+ /**
235
+ * Stop listening.
236
+ *
237
+ * @method abort
238
+ */
170
239
  abort: function() {
171
240
  autoRestart = false;
172
- recognition.abort();
241
+ if (isInitialized) {
242
+ recognition.abort();
243
+ }
173
244
  },
174
245
 
175
- // Turn on output of debug messages to the console. Ugly, but super-handy!
246
+ /**
247
+ * Turn on output of debug messages to the console. Ugly, but super-handy!
248
+ *
249
+ * @param {Boolean} [newState=true] - Turn on/off debug messages
250
+ * @method debug
251
+ */
176
252
  debug: function(newState) {
177
253
  if (arguments.length > 0) {
178
254
  debugState = !!newState;
@@ -181,19 +257,41 @@
181
257
  }
182
258
  },
183
259
 
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)
260
+ /**
261
+ * Set the language the user will speak in. If this method is not called, defaults to 'en-US'.
262
+ *
263
+ * @param {String} language - The language (locale)
264
+ * @method setLanguage
265
+ * @see [Languages](#languages)
266
+ */
186
267
  setLanguage: function(language) {
187
- lang = language;
188
- if (recognition && recognition.abort) {
189
- recognition.lang = language;
190
- }
268
+ initIfNeeded();
269
+ recognition.lang = language;
191
270
  },
192
271
 
193
- // Add additional commands that annyang will respond to. Similar in syntax to annyang.init()
272
+ /**
273
+ * Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands.
274
+ *
275
+ * ### Examples:
276
+ *
277
+ * var commands = {'hello :name': helloFunction, 'howdy': helloFunction};
278
+ * var commands2 = {'hi': helloFunction};
279
+ *
280
+ * annyang.addCommands(commands);
281
+ * annyang.addCommands(commands2);
282
+ * // annyang will now listen to all three commands
283
+ *
284
+ *
285
+ * @param {Object} commands - Commands that annyang should listen to
286
+ * @method addCommands
287
+ * @see [Commands Object](#commands-object)
288
+ */
194
289
  addCommands: function(commands) {
195
290
  var cb,
196
291
  command;
292
+
293
+ initIfNeeded();
294
+
197
295
  for (var phrase in commands) {
198
296
  if (commands.hasOwnProperty(phrase)) {
199
297
  cb = root[commands[phrase]] || commands[phrase];
@@ -211,11 +309,68 @@
211
309
  }
212
310
  },
213
311
 
312
+ /**
313
+ * Remove existing commands. Called with a single phrase, array of phrases, or methodically. Pass no params to remove all commands.
314
+ *
315
+ * ### Examples:
316
+ *
317
+ * var commands = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction};
318
+ *
319
+ * // Remove all existing commands
320
+ * annyang.removeCommands();
321
+ *
322
+ * // Add some commands
323
+ * annyang.addCommands(commands);
324
+ *
325
+ * // Don't respond to hello
326
+ * annyang.removeCommands('hello');
327
+ *
328
+ * // Don't respond to howdy or hi
329
+ * annyang.removeCommands(['howdy', 'hi']);
330
+ *
331
+ * @param {String|Array|Undefined} [commandsToRemove] - Commands to remove
332
+ * @method removeCommands
333
+ */
334
+ removeCommands: function(commandsToRemove) {
335
+ if (commandsToRemove === undefined) {
336
+ commandsList = [];
337
+ return;
338
+ }
339
+ commandsToRemove = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove];
340
+ commandsList = commandsList.filter(function(command) {
341
+ for (var i = 0; i<commandsToRemove.length; i++) {
342
+ if (commandsToRemove[i] === command.originalPhrase) {
343
+ return false;
344
+ }
345
+ }
346
+ return true;
347
+ });
348
+ },
349
+
214
350
  // 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
351
+ //
352
+ //
353
+ /**
354
+ * Add a callback function to be called in case one of the following events happens:
355
+ *
356
+ * start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied.
357
+ *
358
+ * ### Examples:
359
+ *
360
+ * annyang.addCallback('error', function () {
361
+ * $('.myErrorText').text('There was an error!');
362
+ * });
363
+ *
364
+ * // pass local context to a global function called notConnected
365
+ * annyang.addCallback('errorNetwork', notConnected, this);
366
+ *
367
+ * @param {String} type - Name of event that will trigger this callback
368
+ * @param {Function} callback - The function to call when event is triggered
369
+ * @param {Object} [context] - Optional context for the callback function
370
+ * @method addCallback
371
+ */
217
372
  addCallback: function(type, callback, context) {
218
- if (callbacks[type] === void 0) {
373
+ if (callbacks[type] === undefined) {
219
374
  return;
220
375
  }
221
376
  var cb = root[callback] || callback;
@@ -227,3 +382,131 @@
227
382
  };
228
383
 
229
384
  }).call(this);
385
+
386
+ /**
387
+ * # Good to Know
388
+ *
389
+ * ## Commands Object
390
+ *
391
+ * Both the [init()]() and addCommands() methods receive a `commands` object.
392
+ *
393
+ * annyang understands commands with `named variables`, `splats`, and `optional words`.
394
+ *
395
+ * * Use `named variables` for one word arguments in your command.
396
+ * * Use `splats` to capture multi-word text at the end of your command (greedy).
397
+ * * Use `optional words` or phrases to define a part of the command as optional.
398
+ *
399
+ * ### Examples:
400
+ *
401
+ * <script>
402
+ * var commands = {
403
+ * // annyang will capture anything after a splat (*) and pass it to the function.
404
+ * // e.g. saying "Show me Batman and Robin" will call showFlickr('Batman and Robin');
405
+ * 'show me *term': showFlickr,
406
+ *
407
+ * // A named variable is a one word variable, that can fit anywhere in your command.
408
+ * // e.g. saying "calculate October stats" will call calculateStats('October');
409
+ * 'calculate :month stats': calculateStats,
410
+ *
411
+ * // By defining a part of the following command as optional, annyang will respond
412
+ * // to both: "say hello to my little friend" as well as "say hello friend"
413
+ * 'say hello (to my little) friend': greeting
414
+ * };
415
+ *
416
+ * var showFlickr = function(term) {
417
+ * var url = 'http://api.flickr.com/services/rest/?tags='+tag;
418
+ * $.getJSON(url);
419
+ * }
420
+ *
421
+ * var calculateStats = function(month) {
422
+ * $('#stats').text('Statistics for '+month);
423
+ * }
424
+ *
425
+ * var greeting = function() {
426
+ * $('#greeting').text('Hello!');
427
+ * }
428
+ * </script>
429
+ *
430
+ * ## Languages
431
+ *
432
+ * While there isn't an official list of supported languages (cultures? locales?), here is a list based on [anecdotal evidence](http://stackoverflow.com/a/14302134/338039).
433
+ *
434
+ * * Afrikaans `af`
435
+ * * Basque `eu`
436
+ * * Bulgarian `bg`
437
+ * * Catalan `ca`
438
+ * * Arabic (Egypt) `ar-EG`
439
+ * * Arabic (Jordan) `ar-JO`
440
+ * * Arabic (Kuwait) `ar-KW`
441
+ * * Arabic (Lebanon) `ar-LB`
442
+ * * Arabic (Qatar) `ar-QA`
443
+ * * Arabic (UAE) `ar-AE`
444
+ * * Arabic (Morocco) `ar-MA`
445
+ * * Arabic (Iraq) `ar-IQ`
446
+ * * Arabic (Algeria) `ar-DZ`
447
+ * * Arabic (Bahrain) `ar-BH`
448
+ * * Arabic (Lybia) `ar-LY`
449
+ * * Arabic (Oman) `ar-OM`
450
+ * * Arabic (Saudi Arabia) `ar-SA`
451
+ * * Arabic (Tunisia) `ar-TN`
452
+ * * Arabic (Yemen) `ar-YE`
453
+ * * Czech `cs`
454
+ * * Dutch `nl-NL`
455
+ * * English (Australia) `en-AU`
456
+ * * English (Canada) `en-CA`
457
+ * * English (India) `en-IN`
458
+ * * English (New Zealand) `en-NZ`
459
+ * * English (South Africa) `en-ZA`
460
+ * * English(UK) `en-GB`
461
+ * * English(US) `en-US`
462
+ * * Finnish `fi`
463
+ * * French `fr-FR`
464
+ * * Galician `gl`
465
+ * * German `de-DE`
466
+ * * Hebrew `he`
467
+ * * Hungarian `hu`
468
+ * * Icelandic `is`
469
+ * * Italian `it-IT`
470
+ * * Indonesian `id`
471
+ * * Japanese `ja`
472
+ * * Korean `ko`
473
+ * * Latin `la`
474
+ * * Mandarin Chinese `zh-CN`
475
+ * * Traditional Taiwan `zh-TW`
476
+ * * Simplified China zh-CN `?`
477
+ * * Simplified Hong Kong `zh-HK`
478
+ * * Yue Chinese (Traditional Hong Kong) `zh-yue`
479
+ * * Malaysian `ms-MY`
480
+ * * Norwegian `no-NO`
481
+ * * Polish `pl`
482
+ * * Pig Latin `xx-piglatin`
483
+ * * Portuguese `pt-PT`
484
+ * * Portuguese (Brasil) `pt-BR`
485
+ * * Romanian `ro-RO`
486
+ * * Russian `ru`
487
+ * * Serbian `sr-SP`
488
+ * * Slovak `sk`
489
+ * * Spanish (Argentina) `es-AR`
490
+ * * Spanish (Bolivia) `es-BO`
491
+ * * Spanish (Chile) `es-CL`
492
+ * * Spanish (Colombia) `es-CO`
493
+ * * Spanish (Costa Rica) `es-CR`
494
+ * * Spanish (Dominican Republic) `es-DO`
495
+ * * Spanish (Ecuador) `es-EC`
496
+ * * Spanish (El Salvador) `es-SV`
497
+ * * Spanish (Guatemala) `es-GT`
498
+ * * Spanish (Honduras) `es-HN`
499
+ * * Spanish (Mexico) `es-MX`
500
+ * * Spanish (Nicaragua) `es-NI`
501
+ * * Spanish (Panama) `es-PA`
502
+ * * Spanish (Paraguay) `es-PY`
503
+ * * Spanish (Peru) `es-PE`
504
+ * * Spanish (Puerto Rico) `es-PR`
505
+ * * Spanish (Spain) `es-ES`
506
+ * * Spanish (US) `es-US`
507
+ * * Spanish (Uruguay) `es-UY`
508
+ * * Spanish (Venezuela) `es-VE`
509
+ * * Swedish `sv-SE`
510
+ * * Turkish `tr`
511
+ * * Zulu `zu`
512
+ */
@@ -1,6 +1,6 @@
1
1
  //! annyang
2
- //! version : 0.2.0
2
+ //! version : 1.4.0
3
3
  //! author : Tal Ater @TalAter
4
4
  //! license : MIT
5
5
  //! https://www.TalAter.com/annyang/
6
- (function(){"use strict";var a=this,b=a.webkitSpeechRecognition||a.mozSpeechRecognition||a.msSpeechRecognition||a.oSpeechRecognition||a.SpeechRecognition;if(!b)return a.annyang=null,null;var c,d,e,f="en-US",g={start:[],error:[],end:[],result:[],resultMatch:[],resultNoMatch:[],errorNetwork:[],errorPermissionBlocked:[],errorPermissionDenied:[]},h=0,i=!1,j="font-weight: bold; color: #00f;",k=/\s*\((.*?)\)\s*/g,l=/(\(\?:[^)]+\))\?/g,m=/(\(\?)?:\w+/g,n=/\*\w+/g,o=/[\-{}\[\]+?.,\\\^$|#]/g,p=function(a){return a=a.replace(o,"\\$&").replace(k,"(?:$1)?").replace(m,function(a,b){return b?a:"([^\\s]+)"}).replace(n,"(.*?)").replace(l,"\\s*$1?\\s*"),new RegExp("^"+a+"$","i")},q=function(a){for(var b=0,c=a.length;c>b;b++)a[b].callback.apply(a[b].context)};a.annyang={init:function(k){d&&d.abort&&d.abort(),d=new b,d.maxAlternatives=5,d.continuous=!0,d.lang=f,d.onstart=function(){q(g.start)},d.onerror=function(a){switch(q(g.error),a.error){case"network":q(g.errorNetwork);break;case"not-allowed":case"service-not-allowed":e=!1,(new Date).getTime()-h<200?q(g.errorPermissionBlocked):q(g.errorPermissionDenied)}},d.onend=function(){if(q(g.end),e){var b=(new Date).getTime()-h;1e3>b?setTimeout(a.annyang.start,1e3-b):a.annyang.start()}},d.onresult=function(b){q(g.result);for(var d,e=b.results[b.resultIndex],f=0;f<e.length;f++){d=e[f].transcript.trim(),i&&a.console.log("Speech recognized: %c"+d,j);for(var h=0,k=c.length;k>h;h++){var l=c[h].command.exec(d);if(l){var m=l.slice(1);return i&&(a.console.log("command matched: %c"+c[h].originalPhrase,j),m.length&&a.console.log("with parameters",m)),c[h].callback.apply(this,m),q(g.resultMatch),!0}}}return q(g.resultNoMatch),!1},c=[],this.addCommands(k)},start:function(a){a=a||{},e=void 0!==a.autoRestart?!!a.autoRestart:!0,h=(new Date).getTime(),d.start()},abort:function(){e=!1,d.abort()},debug:function(a){i=arguments.length>0?!!a:!0},setLanguage:function(a){f=a,d&&d.abort&&(d.lang=a)},addCommands:function(b){var d,e;for(var f in b)if(b.hasOwnProperty(f)){if(d=a[b[f]]||b[f],"function"!=typeof d)continue;e=p(f),c.push({command:e,callback:d,originalPhrase:f})}i&&a.console.log("Commands successfully loaded: %c"+c.length,j)},addCallback:function(b,c,d){if(void 0!==g[b]){var e=a[c]||c;"function"==typeof e&&g[b].push({callback:e,context:d||this})}}}}).call(this);
6
+ (function(a){"use strict";var b=this,c=b.SpeechRecognition||b.webkitSpeechRecognition||b.mozSpeechRecognition||b.msSpeechRecognition||b.oSpeechRecognition;if(!c)return b.annyang=null,a;var d,e,f=[],g={start:[],error:[],end:[],result:[],resultMatch:[],resultNoMatch:[],errorNetwork:[],errorPermissionBlocked:[],errorPermissionDenied:[]},h=0,i=!1,j="font-weight: bold; color: #00f;",k=/\s*\((.*?)\)\s*/g,l=/(\(\?:[^)]+\))\?/g,m=/(\(\?)?:\w+/g,n=/\*\w+/g,o=/[\-{}\[\]+?.,\\\^$|#]/g,p=function(a){return a=a.replace(o,"\\$&").replace(k,"(?:$1)?").replace(m,function(a,b){return b?a:"([^\\s]+)"}).replace(n,"(.*?)").replace(l,"\\s*$1?\\s*"),new RegExp("^"+a+"$","i")},q=function(a){a.forEach(function(a){a.callback.apply(a.context)})},r=function(){s()||b.annyang.init({},!1)},s=function(){return d!==a};b.annyang={init:function(k,l){l=l===a?!0:!!l,d&&d.abort&&d.abort(),d=new c,d.maxAlternatives=5,d.continuous="http:"===b.location.protocol,d.lang="en-US",d.onstart=function(){q(g.start)},d.onerror=function(a){switch(q(g.error),a.error){case"network":q(g.errorNetwork);break;case"not-allowed":case"service-not-allowed":e=!1,q((new Date).getTime()-h<200?g.errorPermissionBlocked:g.errorPermissionDenied)}},d.onend=function(){if(q(g.end),e){var a=(new Date).getTime()-h;1e3>a?setTimeout(b.annyang.start,1e3-a):b.annyang.start()}},d.onresult=function(a){q(g.result);for(var c,d=a.results[a.resultIndex],e=0;e<d.length;e++){c=d[e].transcript.trim(),i&&b.console.log("Speech recognized: %c"+c,j);for(var h=0,k=f.length;k>h;h++){var l=f[h].command.exec(c);if(l){var m=l.slice(1);return i&&(b.console.log("command matched: %c"+f[h].originalPhrase,j),m.length&&b.console.log("with parameters",m)),f[h].callback.apply(this,m),q(g.resultMatch),!0}}}return q(g.resultNoMatch),!1},l&&(f=[]),k.length&&this.addCommands(k)},start:function(b){r(),b=b||{},e=b.autoRestart!==a?!!b.autoRestart:!0,h=(new Date).getTime(),d.start()},abort:function(){e=!1,s&&d.abort()},debug:function(a){i=arguments.length>0?!!a:!0},setLanguage:function(a){r(),d.lang=a},addCommands:function(a){var c,d;r();for(var e in a)if(a.hasOwnProperty(e)){if(c=b[a[e]]||a[e],"function"!=typeof c)continue;d=p(e),f.push({command:d,callback:c,originalPhrase:e})}i&&b.console.log("Commands successfully loaded: %c"+f.length,j)},removeCommands:function(b){return b===a?void(f=[]):(b=Array.isArray(b)?b:[b],void(f=f.filter(function(a){for(var c=0;c<b.length;c++)if(b[c]===a.originalPhrase)return!1;return!0})))},addCallback:function(c,d,e){if(g[c]!==a){var f=b[d]||d;"function"==typeof f&&g[c].push({callback:f,context:e||this})}}}}).call(this);
metadata CHANGED
@@ -1,15 +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
5
- prerelease:
4
+ version: 1.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Confiz Limited
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-12-09 00:00:00.000000000 Z
11
+ date: 2014-09-02 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: A tiny javascript SpeechRecognition library that lets your users control
15
14
  your site with voice commands.
@@ -21,18 +20,19 @@ extra_rdoc_files:
21
20
  - lib/annyang-rails.rb
22
21
  - lib/annyang-rails/version.rb
23
22
  files:
23
+ - Manifest
24
24
  - README.md
25
25
  - Rakefile
26
+ - annyang-rails.gemspec
26
27
  - app/helpers/annyang_helper.rb
27
28
  - init.rb
28
29
  - lib/annyang-rails.rb
29
30
  - lib/annyang-rails/version.rb
30
31
  - vendor/assets/javascripts/annyang.js
31
32
  - vendor/assets/javascripts/annyang.min.js
32
- - Manifest
33
- - annyang-rails.gemspec
34
33
  homepage: http://github.com/confiz/annyang-rails
35
34
  licenses: []
35
+ metadata: {}
36
36
  post_install_message:
37
37
  rdoc_options:
38
38
  - --line-numbers
@@ -43,20 +43,18 @@ rdoc_options:
43
43
  require_paths:
44
44
  - lib
45
45
  required_ruby_version: !ruby/object:Gem::Requirement
46
- none: false
47
46
  requirements:
48
47
  - - ! '>='
49
48
  - !ruby/object:Gem::Version
50
49
  version: '0'
51
50
  required_rubygems_version: !ruby/object:Gem::Requirement
52
- none: false
53
51
  requirements:
54
52
  - - ! '>='
55
53
  - !ruby/object:Gem::Version
56
54
  version: '1.2'
57
55
  requirements: []
58
56
  rubyforge_project: annyang-rails
59
- rubygems_version: 1.8.24
57
+ rubygems_version: 2.2.2
60
58
  signing_key:
61
59
  specification_version: 3
62
60
  summary: A tiny javascript SpeechRecognition library that lets your users control