rack-olark 0.1 → 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b73e4d28f59840a324703890bfe83c2d9d28100e
4
+ data.tar.gz: 64df536b159df3350015d517896dbef859c727a1
5
+ SHA512:
6
+ metadata.gz: e81ec5afdf1e748e05c5d29a05a11f2440122c07c690338b57836da779c6eb15a5be20ed65d9172b0a4e6c80418267a98235978a294114cc24584e6112b5f781
7
+ data.tar.gz: 45ff877ad37199fb94e5ba6ecf42b276ef0eab6eb5a98a9d9a59fb35dc447c269abc2b86b025eb4c09bf7f12515a07f59f1826e848745f9fbd766761060a6087
data/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
- Copyright (C) 2012 Dan Poggi
1
+ Copyright (C) 2011 Dan Poggi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
5
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,34 +1,39 @@
1
1
  # Rack::Olark
2
- Rack middleware which injects the Olark JavaScript code before the end of the body of any HTML document being sent to the client.
2
+
3
+ Middleware which inserts Olark JavaScript embed code before </body> in HTML served by Rack.
3
4
 
4
5
  ## Usage
5
6
 
7
+ In `config.ru`, or wherever else you mount middleware:
8
+
6
9
  use Rack::Olark, id: '1234-567-89-0123'
7
10
 
8
- Most of the options you give Rack::Olark are passed along to Olark in the following format:
11
+ All non-special options given to Rack::Olark are passed through as JavaScript in the following manner:
9
12
 
10
13
  olark.configure('key', value);
11
14
 
12
- There are three special options: id, tag, and paths. id is your Olark API ID, and the middleware won't let your Rack app boot without it.
15
+ There are two special options: `id` and `paths`.
13
16
 
14
- tag is a custom script tag to be used at the beginning of the Olark code. Most people should never need this, and it will default to just `<script>` (HTML5-style).
17
+ `id` is your Olark Site-ID, and the middleware won't allow your app to boot without it.
15
18
 
16
- paths decides which routes in your application will display the Olark chat box. It takes an array of routes, and you need to include the leading slash (/). If you don't give an array for paths, it is empty by default, and this will cause the Olark code to be inserted on every route. As of version 0.0.4, you can now describe routes in the paths array with a Regexp as well, and any non-Regexp entries will be handled like this:
19
+ `paths` decides which of your routes will display the Olark chat box. It accepts an array of routes, with the leading slash (`/`) included. `paths` defaults to empty array (`[]`), causing Olark to be embedded for every route. As of version 0.0.4, routes in `paths` can also be described with a Regexp. Non-Regexp `paths` entries will be handled using:
17
20
 
18
- /^#{Regexp.escape(your_original_path_entry)}$/
21
+ /^#{Regexp.escape('/my/path')}$/
19
22
 
20
- Example using options:
23
+ Example of usage with options:
21
24
 
22
- use Rack::Olark, id: '1234-567-89-0123',
23
- tag: '<script type="text/javascript">',
24
- paths: ['/', '/aboutus']
25
+ use Rack::Olark, {
26
+ :id => '1234-567-89-0123',
27
+ :paths => ['/', '/aboutus'],
28
+ 'features.attention_grabber' => true,
29
+ }
25
30
 
26
- Note that in order to use custom Olark JavaScript options, you may have to revert to using hashrocket syntax.
31
+ Note that in order to use custom Olark JavaScript options, you may have to revert to hashrocket syntax, as they tend to contain characters Ruby doesn't like in symbols.
27
32
 
28
33
  ## Acknowledgements
29
34
 
30
- Code from rack/google-analytics has been used liberally and expanded/trimmed down where needed. Mucho thanks to Lee Hambley and other cool rack/google-analytics bros.
35
+ Originally based on code from [rack-google-analytics](https://github.com/kangguru/rack-google-analytics). Never would've gotten started without them!
31
36
 
32
37
  ## Copyright
33
38
 
34
- Copyright (C) 2012 Dan Poggi. MIT License, see LICENSE for details.
39
+ Copyright (C) 2011 Dan Poggi. MIT License, see LICENSE for details.
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class Olark
3
+ VERSION = '0.2.0'
4
+ end
5
+ end
data/lib/rack/olark.rb CHANGED
@@ -1,67 +1,69 @@
1
+ require 'erb'
2
+ require 'json'
1
3
  require 'rack'
2
4
  require 'rack/request'
3
- require 'erb'
4
5
 
5
6
  module Rack
6
7
  class Olark
7
- DEFAULTS = {
8
- tag: '<script>',
9
- paths: []
10
- }
8
+ TEMPLATE_PATH = ::File.expand_path(
9
+ ::File.join('..', 'templates', 'olark.erb'),
10
+ __FILE__
11
+ )
11
12
 
12
13
  def initialize(app, options = {})
13
- unless options[:id] && options[:id].length == 16
14
- raise ArgumentError, 'Need a valid Olark ID!'
14
+ @app = app
15
+
16
+ # Validity check on Site-ID
17
+ site_id = (options.delete(:id) || '').gsub(/[^0-9-]/, '')
18
+ unless site_id.length == 16
19
+ raise ArgumentError, 'rack-olark requires a valid Olark Site-ID!'
15
20
  end
16
21
 
17
- @app, @options = app, DEFAULTS.merge(options)
18
- @id, @tag, @paths = [@options.delete(:id),
19
- @options.delete(:tag),
20
- @options.delete(:paths)]
22
+ # Deprecation warnings
23
+ deprecation_warning('format') if options.delete(:format)
24
+ deprecation_warning('tag') if options.delete(:tag)
21
25
 
22
- if @paths.is_a?(Array)
23
- @paths.map! { |path| path.is_a?(Regexp) ? path : /^#{Regexp.escape(path.to_s)}$/ }
24
- else
25
- @paths = []
26
+ # Is it a Regexp? No? Then escape it, and make it a Regexp.
27
+ @paths = (options.delete(:paths) || []).map do |path|
28
+ path.is_a?(Regexp) ? path : /^#{Regexp.escape(path.to_s)}$/
26
29
  end
30
+ # Let's please not call Array#empty? on every request.
31
+ @inject_all = @paths.empty?
27
32
 
28
- @option_js = "olark.identify('#{@id}');"
29
- @options.each do |key, val|
30
- val = [String, Symbol].include?(val.class) ? "'#{val.to_s}'" : val.to_s
31
- @option_js << "olark.configure('#{key.to_s}', #{val});"
32
- end
33
+ js = options.map { |k, v| olarkify(k, v) }.join
34
+ @html = ERB.new(::File.read(TEMPLATE_PATH)).result(binding)
33
35
  end
34
36
 
35
- def call(env); dup._call(env); end
36
-
37
- def _call(env)
38
- @status, @headers, @response = @app.call(env)
39
- @request = Rack::Request.new(env)
40
- valid_path = @paths.select { |path| @request.path_info =~ path }.length > 0
37
+ def call(env)
38
+ status, headers, body = @app.call(env)
39
+ request = Rack::Request.new(env)
41
40
 
42
- # Deprecation warning, repeated and annoying. Sorry about your log space.
43
- if @options[:format]
44
- logger = env['rack.errors']
45
- logger.write("[#{Time.now.strftime("%Y-%M-%d %H:%M:%S")}] WARNING ")
46
- logger.write("Rack::Olark: The 'format' option no longer works! See README.md for details.\n")
47
- end
48
-
49
- if html? && (@paths.empty? || valid_path)
50
- response = Rack::Response.new([], @status, @headers)
51
- @response.each { |fragment| response.write(inject(fragment)) }
41
+ if html?(headers) && (@inject_all || should_inject?(request))
42
+ response = Rack::Response.new([], status, headers)
43
+ body.each do |fragment|
44
+ response.write(fragment.gsub('</body>', @html))
45
+ end
52
46
  response.finish
53
47
  else
54
- [@status, @headers, @response]
48
+ [status, headers, body]
55
49
  end
56
50
  end
57
51
 
58
52
  private
59
- def html?; @headers['Content-Type'] =~ /html/; end
53
+ def olarkify(key, val)
54
+ "olark.configure(#{key.to_s.to_json}, #{val.to_json});"
55
+ end
56
+
57
+ def deprecation_warning(option)
58
+ STDOUT.puts("Rack::Olark: The '#{option}' option is deprecated and no longer functions! See README.md for details.")
59
+ end
60
+
61
+ def html?(headers)
62
+ (Rack::Utils::HeaderHash.new(headers)['Content-Type'] || '').include?('html')
63
+ end
60
64
 
61
- def inject(response)
62
- template_file = ::File.read(::File.expand_path('../templates/olark.erb', __FILE__))
63
- @template = ERB.new(template_file).result(binding)
64
- response.gsub('</body>', @template)
65
+ def should_inject?(request)
66
+ @paths.select { |p| request.path_info =~ p }.length > 0
65
67
  end
66
68
  end
67
69
  end
@@ -1,7 +1,21 @@
1
- <!-- Begin Olark code -->
2
- <%= @tag %>
3
- window.olark||(function(i){var e=window,h=document,a=e.location.protocol=="https:"?"https:":"http:",g=i.name,b="load";(function(){e[g]=function(){(c.s=c.s||[]).push(arguments)};var c=e[g]._={},f=i.methods.length; while(f--){(function(j){e[g][j]=function(){e[g]("call",j,arguments)}})(i.methods[f])} c.l=i.loader;c.i=arguments.callee;c.f=setTimeout(function(){if(c.f){(new Image).src=a+"//"+c.l.replace(".js",".png")+"&"+escape(e.location.href)}c.f=null},20000);c.p={0:+new Date};c.P=function(j){c.p[j]=new Date-c.p[0]};function d(){c.P(b);e[g](b)}e.addEventListener?e.addEventListener(b,d,false):e.attachEvent("on"+b,d); (function(){function l(j){j="head";return["<",j,"></",j,"><",z,' onload="var d=',B,";d.getElementsByTagName('head')[0].",y,"(d.",A,"('script')).",u,"='",a,"//",c.l,"'",'"',"></",z,">"].join("")}var z="body",s=h[z];if(!s){return setTimeout(arguments.callee,100)}c.P(1);var y="appendChild",A="createElement",u="src",r=h[A]("div"),G=r[y](h[A](g)),D=h[A]("iframe"),B="document",C="domain",q;r.style.display="none";s.insertBefore(r,s.firstChild).id=g;D.frameBorder="0";D.id=g+"-loader";if(/MSIE[ ]+6/.test(navigator.userAgent)){D.src="javascript:false"} D.allowTransparency="true";G[y](D);try{D.contentWindow[B].open()}catch(F){i[C]=h[C];q="javascript:var d="+B+".open();d.domain='"+h.domain+"';";D[u]=q+"void(0);"}try{var H=D.contentWindow[B];H.write(l());H.close()}catch(E){D[u]=q+'d.write("'+l().replace(/"/g,String.fromCharCode(92)+'"')+'");d.close();'}c.P(2)})()})()})({loader:(function(a){return "static.olark.com/jsclient/loader0.js?ts="+(a?a[1]:(+new Date))})(document.cookie.match(/olarkld=([0-9]+)/)),name:"olark",methods:["configure","extend","declare","identify"]});
4
- <%= @option_js %>
5
- </script>
6
- <!-- End Olark code -->
1
+ <!-- begin olark code -->
2
+ <script data-cfasync="false" type='text/javascript'>/*<![CDATA[*/window.olark||(function(c){var f=window,d=document,l=f.location.protocol=="https:"?"https:":"http:",z=c.name,r="load";var nt=function(){
3
+ f[z]=function(){
4
+ (a.s=a.s||[]).push(arguments)};var a=f[z]._={
5
+ },q=c.methods.length;while(q--){(function(n){f[z][n]=function(){
6
+ f[z]("call",n,arguments)}})(c.methods[q])}a.l=c.loader;a.i=nt;a.p={
7
+ 0:+new Date};a.P=function(u){
8
+ a.p[u]=new Date-a.p[0]};function s(){
9
+ a.P(r);f[z](r)}f.addEventListener?f.addEventListener(r,s,false):f.attachEvent("on"+r,s);var ld=function(){function p(hd){
10
+ hd="head";return["<",hd,"></",hd,"><",i,' onl' + 'oad="var d=',g,";d.getElementsByTagName('head')[0].",j,"(d.",h,"('script')).",k,"='",l,"//",a.l,"'",'"',"></",i,">"].join("")}var i="body",m=d[i];if(!m){
11
+ return setTimeout(ld,100)}a.P(1);var j="appendChild",h="createElement",k="src",n=d[h]("div"),v=n[j](d[h](z)),b=d[h]("iframe"),g="document",e="domain",o;n.style.display="none";m.insertBefore(n,m.firstChild).id=z;b.frameBorder="0";b.id=z+"-loader";if(/MSIE[ ]+6/.test(navigator.userAgent)){
12
+ b.src="javascript:false"}b.allowTransparency="true";v[j](b);try{
13
+ b.contentWindow[g].open()}catch(w){
14
+ c[e]=d[e];o="javascript:var d="+g+".open();d.domain='"+d.domain+"';";b[k]=o+"void(0);"}try{
15
+ var t=b.contentWindow[g];t.write(p());t.close()}catch(x){
16
+ b[k]=o+'d.write("'+p().replace(/"/g,String.fromCharCode(92)+'"')+'");d.close();'}a.P(2)};ld()};nt()})({
17
+ loader: "static.olark.com/jsclient/loader0.js",name:"olark",methods:["configure","extend","declare","identify"]});
18
+ /* custom configuration goes here (www.olark.com/documentation) */
19
+ olark.identify('<%= site_id %>');<%= js %>/*]]>*/</script><noscript><a href="https://www.olark.com/site/<%= site_id %>/contact" title="Contact us" target="_blank">Questions? Feedback?</a> powered by <a href="http://www.olark.com?welcome" title="Olark live chat software">Olark live chat software</a></noscript>
20
+ <!-- end olark code -->
7
21
  </body>
metadata CHANGED
@@ -1,104 +1,93 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-olark
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Dan Poggi
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-09 00:00:00.000000000 Z
11
+ date: 2016-03-17 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rack
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: '1.2'
19
+ version: 1.2.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '1.2'
26
+ version: 1.2.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: bundler
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
- description: Rack middleware which injects the Olark JavaScript code before the end
63
- of the body of any HTML document being sent to the client. See README.md for details.
55
+ description: Middleware which inserts Olark JavaScript embed code before </body> in
56
+ HTML served by Rack.
64
57
  email:
65
58
  - dan.poggi@gmail.com
66
59
  executables: []
67
60
  extensions: []
68
61
  extra_rdoc_files: []
69
62
  files:
70
- - .gitignore
71
- - Gemfile
72
63
  - LICENSE
73
64
  - README.md
74
- - Rakefile
75
- - VERSION
76
65
  - lib/rack-olark.rb
77
66
  - lib/rack/olark.rb
67
+ - lib/rack/olark/version.rb
78
68
  - lib/rack/templates/olark.erb
79
- - rack-olark.gemspec
80
69
  homepage: https://github.com/dpoggi/rack-olark
81
- licenses: []
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
82
73
  post_install_message:
83
74
  rdoc_options: []
84
75
  require_paths:
85
76
  - lib
86
77
  required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
78
  requirements:
89
- - - ! '>='
79
+ - - ">="
90
80
  - !ruby/object:Gem::Version
91
- version: '0'
81
+ version: 2.1.0
92
82
  required_rubygems_version: !ruby/object:Gem::Requirement
93
- none: false
94
83
  requirements:
95
- - - ! '>='
84
+ - - ">="
96
85
  - !ruby/object:Gem::Version
97
86
  version: '0'
98
87
  requirements: []
99
- rubyforge_project: rack-olark
100
- rubygems_version: 1.8.23
88
+ rubyforge_project:
89
+ rubygems_version: 2.5.1
101
90
  signing_key:
102
- specification_version: 3
103
- summary: Rack middleware for embedding Olark.
91
+ specification_version: 4
92
+ summary: Rack middleware for inserting Olark JavaScript embed code.
104
93
  test_files: []
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.DS_Store
2
- *.gem
3
- .bundle
4
- Gemfile.lock
5
- pkg/*
data/Gemfile DELETED
@@ -1,2 +0,0 @@
1
- source :rubygems
2
- gemspec
data/Rakefile DELETED
@@ -1 +0,0 @@
1
- require 'bundler/gem_tasks'
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1
data/rack-olark.gemspec DELETED
@@ -1,21 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'rack-olark'
3
- s.version = File.read(File.expand_path('../VERSION', __FILE__)).strip
4
- s.date = Date.today.to_s
5
- s.platform = Gem::Platform::RUBY
6
- s.authors = ['Dan Poggi']
7
- s.email = ['dan.poggi@gmail.com']
8
- s.homepage = 'https://github.com/dpoggi/rack-olark'
9
- s.summary = %q{Rack middleware for embedding Olark.}
10
- s.description = %q{Rack middleware which injects the Olark JavaScript code before the end of the body of any HTML document being sent to the client. See README.md for details.}
11
-
12
- s.rubyforge_project = "rack-olark"
13
-
14
- s.add_dependency 'rack', ['>= 1.2']
15
-
16
- s.add_development_dependency 'rake'
17
- s.add_development_dependency 'bundler'
18
-
19
- s.files = `git ls-files`.split("\n")
20
- s.require_paths = ['lib']
21
- end