gg 0.9.7
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.
- data/.gitignore +4 -0
- data/.project +11 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +49 -0
- data/gg.gemspec +29 -0
- data/lib/gg.rb +34 -0
- data/lib/gg/core.rb +96 -0
- data/lib/gg/demo_app.rb +77 -0
- data/lib/gg/logger.rb +41 -0
- data/lib/gg/public/gg.css +122 -0
- data/lib/gg/rack_plugin.rb +86 -0
- data/lib/gg/slim/_logger.slim +8 -0
- data/lib/gg/slim/array.slim +9 -0
- data/lib/gg/slim/hash.slim +12 -0
- data/lib/gg/slim/history.slim +12 -0
- data/lib/gg/slim/index.slim +12 -0
- data/lib/gg/slim/logger_with_multiple_variables.slim +12 -0
- data/lib/gg/slim/object.slim +2 -0
- data/lib/gg/slim/object_with_instance_variables.slim +10 -0
- data/lib/gg/slim/section.slim +0 -0
- data/lib/gg/slim/string.slim +3 -0
- data/lib/gg/version.rb +3 -0
- data/public/images/accept.png +0 -0
- metadata +124 -0
data/.gitignore
ADDED
data/.project
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# GG
|
2
|
+
|
3
|
+
## WARNINGS! Could not determine CONTENT-LENGTH of response body
|
4
|
+
|
5
|
+
The warning "Could not determine content-length of response body" is a
|
6
|
+
Webrick bug and not a GG bug. In production, if you use Thin, this
|
7
|
+
bug will disappear.
|
8
|
+
|
9
|
+
|
10
|
+
## Overview
|
11
|
+
|
12
|
+
GG is a debugging tool like FireBug for Ruby Rack applications
|
13
|
+
like Rails and Sinatra. It lets you log variables/values to the browser while
|
14
|
+
you work on and debug your web application.
|
15
|
+
|
16
|
+
To use it, simply call "gg" from anywhere in your application.
|
17
|
+
gg stands for the "gg" in "logger" but was also chosen because it is easy to
|
18
|
+
type, even when your right hand is on the mouse.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gg "Hello World"
|
22
|
+
```
|
23
|
+
|
24
|
+
Of course, it would be more useful to see the value of a variable:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
msg = "Hello World"
|
28
|
+
gg msg
|
29
|
+
```
|
30
|
+
|
31
|
+
GG will output to the screen the "gg msg" call, the call position and
|
32
|
+
the data.
|
33
|
+
|
34
|
+
It properly works with Hash and Array values as well as custom objects.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gg [ 1, 2, 3]
|
38
|
+
gg( :a => 'alpha' ) # note: you can't use gg{ :a => 'alpha' } because Ruby thinks its a block
|
39
|
+
gg MyObject.new( 'cool object' )
|
40
|
+
```
|
41
|
+
|
42
|
+
## Choosing Injection Points
|
43
|
+
|
44
|
+
GG always adds the required CSS file at the top of the <head> tag.
|
45
|
+
If there is no <head> tag then it adds it to the top of the content.
|
46
|
+
|
47
|
+
GG tries to add the logging information in the HTML where it finds
|
48
|
+
<!--gg-->.
|
49
|
+
|
50
|
+
If it cannot find <!--gg--> then it adds the HTML to the top of the
|
51
|
+
page after the css link.
|
52
|
+
|
53
|
+
|
54
|
+
## Non-HTML requests
|
55
|
+
|
56
|
+
If you call gg during a non-HTML request like a txt, js or css file, GG
|
57
|
+
does not return the value to the screen since this would mess up your
|
58
|
+
application. When this happens, you can access your dump at:
|
59
|
+
|
60
|
+
/gg/history/0
|
61
|
+
|
62
|
+
Currently, GG is set up to store 10 dumps at:
|
63
|
+
|
64
|
+
/gg/history/0
|
65
|
+
...
|
66
|
+
/gg/history/9
|
67
|
+
|
68
|
+
|
69
|
+
## Build
|
70
|
+
|
71
|
+
rake build
|
72
|
+
|
73
|
+
## Install
|
74
|
+
|
75
|
+
rake install
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
# use "rake install" to create the gem
|
4
|
+
|
5
|
+
task 'demo' do
|
6
|
+
|
7
|
+
require File.join( File.dirname( __FILE__ ), 'lib/gg' )
|
8
|
+
|
9
|
+
app = Rack::Builder.app do
|
10
|
+
use Rack::ShowExceptions
|
11
|
+
use Rack::Reloader, 0
|
12
|
+
use GG
|
13
|
+
# Put this here to make sure that serving files like images aren't broken
|
14
|
+
# by the logger.
|
15
|
+
use Rack::Static, :urls => ["/images"], :root => "public"
|
16
|
+
#run HiLogger::DemoApp.new
|
17
|
+
run lambda { |env|
|
18
|
+
GG::DemoApp.new.call( env )
|
19
|
+
#gg 'Hello World'
|
20
|
+
#[ 200, { 'Content-Type' => 'text/html' }, [ "<h1>HiLogger</h1><p>This is a demo of HiLogger</p>"] ]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
Rack::Handler::WEBrick.run( app )
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# use this for testing to see that if you don't have the rack plugin installed,
|
30
|
+
# that it will display useful error messages to the console.
|
31
|
+
task 'rackless' do
|
32
|
+
|
33
|
+
require File.join( File.dirname( __FILE__ ), 'lib/gg' )
|
34
|
+
|
35
|
+
app = Rack::Builder.app do
|
36
|
+
use Rack::ShowExceptions
|
37
|
+
use Rack::Reloader, 0
|
38
|
+
# Put this here to make sure that serving files like images aren't broken
|
39
|
+
# by the logger.
|
40
|
+
use Rack::Static, :urls => ["/images"], :root => "public"
|
41
|
+
#run HiLogger::DemoApp.new
|
42
|
+
run lambda { |env|
|
43
|
+
GG::DemoApp.new.call( env )
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
Rack::Handler::WEBrick.run( app )
|
48
|
+
|
49
|
+
end
|
data/gg.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gg/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "gg"
|
7
|
+
s.version = GG::VERSION
|
8
|
+
s.authors = ["Sunny Hirai"]
|
9
|
+
s.email = ["thesunny@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Log to the Browser}
|
12
|
+
s.description = %q{Log to the Browser}
|
13
|
+
|
14
|
+
s.rubyforge_project = "gg"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_dependency 'awesome_print'
|
26
|
+
s.add_dependency 'rack'
|
27
|
+
s.add_dependency 'slim'
|
28
|
+
s.add_dependency 'hi_caller'
|
29
|
+
end
|
data/lib/gg.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'awesome_print'
|
3
|
+
require 'slim'
|
4
|
+
require 'hi_caller'
|
5
|
+
require 'gg/version'
|
6
|
+
require 'gg/rack_plugin'
|
7
|
+
require 'gg/demo_app'
|
8
|
+
require 'gg/core'
|
9
|
+
require 'gg/logger'
|
10
|
+
|
11
|
+
class GG
|
12
|
+
|
13
|
+
def self.root
|
14
|
+
@root ||= File.join( File.dirname( __FILE__ ), 'gg' )
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.path( subpath )
|
18
|
+
File.join( root, subpath )
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.render( subpath, scope=nil, &block )
|
22
|
+
Tilt.new( GG.path( subpath ) ).render( scope, &block )
|
23
|
+
# if scope
|
24
|
+
# Tilt.new( GG.path( subpath ) ).render( scope, &block )
|
25
|
+
# elsif block_given?
|
26
|
+
# Tilt.new( GG.path( subpath ) ).render( &block )
|
27
|
+
# else
|
28
|
+
# raise ArgumentError, "Must provide one of scope or block"
|
29
|
+
# end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Your code goes here...
|
33
|
+
end
|
34
|
+
|
data/lib/gg/core.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
|
2
|
+
module Kernel
|
3
|
+
|
4
|
+
def gg( *args )
|
5
|
+
#ap args
|
6
|
+
#ap caller
|
7
|
+
#$gg << "<h1>JFKLDJSKLFSDJKL</h1>"
|
8
|
+
#ap '======================'
|
9
|
+
#ap args.size
|
10
|
+
stack = hi_caller
|
11
|
+
history = {}
|
12
|
+
# case args.size
|
13
|
+
# when 1
|
14
|
+
# $gg << GG.render( 'slim/logger.slim', { stack: stack } ) do
|
15
|
+
# args[0].to_hi_html({})
|
16
|
+
# end
|
17
|
+
# else
|
18
|
+
|
19
|
+
# RENDER HTML
|
20
|
+
$gg << GG.render( 'slim/logger_with_multiple_variables.slim',
|
21
|
+
line: caller[0],
|
22
|
+
objects: args,
|
23
|
+
history: history,
|
24
|
+
stack: stack
|
25
|
+
)
|
26
|
+
|
27
|
+
# RENDER CONSOLE
|
28
|
+
$gg.console_array << <<-EOF
|
29
|
+
#{'-'*79}
|
30
|
+
#{caller[0]}
|
31
|
+
#{stack[0].code_line.strip}
|
32
|
+
#{'.'*79}
|
33
|
+
#{args.ai({})}
|
34
|
+
EOF
|
35
|
+
# end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class Object
|
41
|
+
|
42
|
+
def to_hi_html( history )
|
43
|
+
history[ self ] = true
|
44
|
+
if self.instance_variables.size == 0
|
45
|
+
GG.render( 'slim/object.slim',
|
46
|
+
object: self,
|
47
|
+
classname: "hi-#{ self.class }",
|
48
|
+
history: history
|
49
|
+
)
|
50
|
+
else
|
51
|
+
GG.render( 'slim/object_with_instance_variables.slim',
|
52
|
+
object: self,
|
53
|
+
classname: "hi-#{ self.class }",
|
54
|
+
history: history
|
55
|
+
)
|
56
|
+
end
|
57
|
+
# Rack::Utils.escape_html( self.inspect )
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
class Numeric
|
63
|
+
|
64
|
+
def to_hi_html( history )
|
65
|
+
GG.render( 'slim/object.slim', object: self, classname: "hi-Numeric" )
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
class String
|
71
|
+
|
72
|
+
def to_hi_html( history )
|
73
|
+
GG.render( 'slim/string.slim', self )
|
74
|
+
#Tilt.new( GG.path( 'string.slim' ) ).render( self )
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
class Array
|
80
|
+
|
81
|
+
def to_hi_html( history )
|
82
|
+
return "...recursive..." if history[ self ]
|
83
|
+
history[ self ] = true
|
84
|
+
GG.render( 'slim/array.slim', object: self, history: history )
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
class Hash
|
90
|
+
|
91
|
+
def to_hi_html( history )
|
92
|
+
return "...recursive..." if history[ self ]
|
93
|
+
history[ self ] = true
|
94
|
+
GG.render( 'slim/hash.slim', object: self, history: history )
|
95
|
+
end
|
96
|
+
end
|
data/lib/gg/demo_app.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
class GG::DemoApp
|
2
|
+
|
3
|
+
class Custom
|
4
|
+
|
5
|
+
def initialize(shape, size, color)
|
6
|
+
@shape = shape
|
7
|
+
@size = size
|
8
|
+
@color = color
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :shape, :size, :color
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
case env[ 'PATH_INFO' ]
|
17
|
+
when '/'
|
18
|
+
response = Rack::Response.new
|
19
|
+
response.write GG.render( 'slim/index.slim' )
|
20
|
+
response
|
21
|
+
when '/demo'
|
22
|
+
log_stuff
|
23
|
+
[ 200, { 'Content-Type' => 'text/html' }, [ "<h1>GG</h1><p>This is a demo of GG</p>"] ]
|
24
|
+
when '/inline_demo'
|
25
|
+
log_stuff
|
26
|
+
[ 200, { 'Content-Type' => 'text/html' }, [ %q{
|
27
|
+
<head>
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<h1>GG</h1>
|
31
|
+
<p>This is a demo of GG</p>
|
32
|
+
<div style="border:1px dotted silver;padding: 10px;background-color:#F0F0F0;">
|
33
|
+
<!--gg-->
|
34
|
+
</div>
|
35
|
+
<p>This is a footer</p>
|
36
|
+
</body>
|
37
|
+
} ] ]
|
38
|
+
when '/demo.txt'
|
39
|
+
log_stuff
|
40
|
+
[ 200, { 'Content-Type' => 'text/plain' }, [ "This is a demo of GG (output goes to console using awesome_print gem)"] ]
|
41
|
+
else
|
42
|
+
[ 404, { 'Content-Type' => 'text/html' }, [ "<h1>Page Not Found</h1>" ] ]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def log_stuff
|
47
|
+
gg Object.new
|
48
|
+
gg 123
|
49
|
+
gg 12.5
|
50
|
+
gg Object.new, true, :symbol, 'String'
|
51
|
+
gg true
|
52
|
+
gg false
|
53
|
+
gg nil
|
54
|
+
gg /^http[:]/
|
55
|
+
gg "Hello World <Escaped>"
|
56
|
+
gg [ 1, "two", :three, [ 4, 5, 6 ] ]
|
57
|
+
hash = {
|
58
|
+
make: 'Lamborghini',
|
59
|
+
model: 'Aventador',
|
60
|
+
color: 'yellow',
|
61
|
+
tags: [ 'car', 'exotic' ],
|
62
|
+
wheels: {
|
63
|
+
front: 22,
|
64
|
+
rear: 24
|
65
|
+
}
|
66
|
+
}
|
67
|
+
gg hash
|
68
|
+
custom = Custom.new( 'cube', [ 5, 3 ], 'yellow' )
|
69
|
+
gg custom
|
70
|
+
recursive_hash = { a: 'alpha', b: 'bravo' }
|
71
|
+
recursive_array = [ :a, :b, recursive_hash ]
|
72
|
+
recursive_hash[ :array ] = recursive_array
|
73
|
+
gg recursive_hash
|
74
|
+
gg recursive_array
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/lib/gg/logger.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
class GG::Logger
|
4
|
+
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize( env )
|
8
|
+
@env = env
|
9
|
+
@time = Time.now
|
10
|
+
@html_array = []
|
11
|
+
@console_array = []
|
12
|
+
@is_empty = true
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :env, :time, :html_array, :console_array
|
16
|
+
attr_accessor :response
|
17
|
+
|
18
|
+
def request
|
19
|
+
Rack::Request.new( env )
|
20
|
+
end
|
21
|
+
|
22
|
+
def response
|
23
|
+
Rack::Response.new( env )
|
24
|
+
end
|
25
|
+
|
26
|
+
# Adds the given HTML to the HTML array storing all logging information
|
27
|
+
def <<( html )
|
28
|
+
@is_empty = false
|
29
|
+
html_array << html
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns a String that represent all the HTML sent to the logger via #<<
|
33
|
+
def html
|
34
|
+
html_array.join
|
35
|
+
end
|
36
|
+
|
37
|
+
def empty?
|
38
|
+
@is_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
/* LAYOUT */
|
2
|
+
|
3
|
+
.hi-rounded-corners {
|
4
|
+
-moz-border-radius: 15px;
|
5
|
+
-webkit-border-radius: 15px;
|
6
|
+
-khtml-border-radius: 15px;
|
7
|
+
border-radius: 15px;
|
8
|
+
}
|
9
|
+
|
10
|
+
.hi-logger {
|
11
|
+
border: 1px dotted #CCC;
|
12
|
+
padding: 10px;
|
13
|
+
background-color: #F8F8F8;
|
14
|
+
font: 13px arial;
|
15
|
+
margin-bottom: 10px;
|
16
|
+
color: #888;
|
17
|
+
}
|
18
|
+
|
19
|
+
.hi-logger-header {
|
20
|
+
color: black;
|
21
|
+
margin-bottom: 10px;
|
22
|
+
}
|
23
|
+
|
24
|
+
.hi-code-info {
|
25
|
+
color: #808080;
|
26
|
+
font: 11px arial;
|
27
|
+
margin-bottom: 3px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.hi-code-line {
|
31
|
+
font: 12px consolas, monospace;
|
32
|
+
background-color: #FFFFF0;
|
33
|
+
padding: 5px;
|
34
|
+
-moz-border-radius: 10px;
|
35
|
+
-webkit-border-radius: 10px;
|
36
|
+
-khtml-border-radius: 10px;
|
37
|
+
border-radius: 10px;
|
38
|
+
border: 1px dotted #C0C0C0;
|
39
|
+
float: left;
|
40
|
+
margin-bottom: 4px;
|
41
|
+
}
|
42
|
+
|
43
|
+
.hi-logger-body {
|
44
|
+
clear: both;
|
45
|
+
}
|
46
|
+
|
47
|
+
.hi-logger-section {
|
48
|
+
float: left;
|
49
|
+
padding: 5px;
|
50
|
+
border: 1px dotted #CCC;
|
51
|
+
margin-right: 5px;
|
52
|
+
-moz-border-radius: 10px;
|
53
|
+
-webkit-border-radius: 10px;
|
54
|
+
-khtml-border-radius: 10px;
|
55
|
+
border-radius: 10px;
|
56
|
+
background-color: white;
|
57
|
+
}
|
58
|
+
|
59
|
+
/* OBJECT LAYOUT */
|
60
|
+
|
61
|
+
.hi-indent {
|
62
|
+
margin-left: 20px
|
63
|
+
}
|
64
|
+
|
65
|
+
/* OBJECTS */
|
66
|
+
|
67
|
+
.hi-string {
|
68
|
+
color: #048;
|
69
|
+
}
|
70
|
+
|
71
|
+
.hi-Numeric {
|
72
|
+
color: #080;
|
73
|
+
}
|
74
|
+
|
75
|
+
.hi-NilClass {
|
76
|
+
color: #888;
|
77
|
+
}
|
78
|
+
|
79
|
+
.hi-TrueClass, .hi-FalseClass {
|
80
|
+
color: #A0A020;
|
81
|
+
}
|
82
|
+
|
83
|
+
.hi-Symbol {
|
84
|
+
color: #900;
|
85
|
+
}
|
86
|
+
|
87
|
+
|
88
|
+
.hi-instance-variable {
|
89
|
+
color: #808;
|
90
|
+
}
|
91
|
+
|
92
|
+
/* HISTORY VIEW */
|
93
|
+
|
94
|
+
.hi-history-heading {
|
95
|
+
font: bold 24px arial;
|
96
|
+
margin: 0px;
|
97
|
+
clear: both;
|
98
|
+
}
|
99
|
+
.hi-history-subheading {
|
100
|
+
font: 16px arial;
|
101
|
+
margin-top: 5px;
|
102
|
+
margin-bottom: 20px;
|
103
|
+
}
|
104
|
+
.hi-history-pagination {
|
105
|
+
padding: 6px 0px;
|
106
|
+
}
|
107
|
+
.hi-history-pagination a {
|
108
|
+
font: 13px arial;
|
109
|
+
float: left;
|
110
|
+
display: block;
|
111
|
+
border: 1px solid silver;
|
112
|
+
padding: 5px 10px;
|
113
|
+
margin-right: 5px;
|
114
|
+
margin-bottom: 20px;
|
115
|
+
text-decoration: none;
|
116
|
+
color: #404040;
|
117
|
+
background-color: #F0F0F0;
|
118
|
+
}
|
119
|
+
.hi-history-pagination a:hover {
|
120
|
+
background-color: #D0D0FF;
|
121
|
+
}
|
122
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class GG
|
2
|
+
|
3
|
+
def initialize( app )
|
4
|
+
@app = app
|
5
|
+
@history = []
|
6
|
+
end
|
7
|
+
|
8
|
+
MAX_HISTORY = 10
|
9
|
+
|
10
|
+
attr_reader :app, :history
|
11
|
+
|
12
|
+
def call( env )
|
13
|
+
case env[ 'PATH_INFO' ]
|
14
|
+
when '/gg/history'
|
15
|
+
render_history( 0 )
|
16
|
+
when %r{/gg/history/([0-9])}
|
17
|
+
render_history( $~[1].to_i )
|
18
|
+
when '/gg/main.css'
|
19
|
+
[
|
20
|
+
200,
|
21
|
+
{ 'Content-Type' => 'text/css' },
|
22
|
+
[ File.read(File.join(File.dirname(__FILE__),'public/gg.css'))]
|
23
|
+
]
|
24
|
+
else
|
25
|
+
render_app( env )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def render_app( env )
|
32
|
+
#ap [ $0, *$LOADED_FEATURES ]
|
33
|
+
env[ 'gg' ] = $gg = gg = GG::Logger.new( env )
|
34
|
+
response = @app.call( env )
|
35
|
+
# response = result.is_a?(Rack::Response) ? result : Rack::Response.new(result[2], result[0], result[1])
|
36
|
+
# env[ 'gg' ].response = Rack::Response.new( result )
|
37
|
+
# env[ 'gg' ].response = response
|
38
|
+
# Logs to the HTML page only if the response type is text/html
|
39
|
+
if !gg.empty?
|
40
|
+
if response_is_html(response)
|
41
|
+
add_logger_to_response( response, gg )
|
42
|
+
add_logger_to_history( gg )
|
43
|
+
else
|
44
|
+
puts
|
45
|
+
puts '='*79
|
46
|
+
puts env['REQUEST_URI'] || env['PATH_INFO']
|
47
|
+
$gg.console_array.each do |item|
|
48
|
+
puts item
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
response
|
53
|
+
end
|
54
|
+
|
55
|
+
def render_history( i )
|
56
|
+
logger = history[i]
|
57
|
+
body = logger
|
58
|
+
html = GG.render( 'slim/history.slim', body: body, history: history, logger: logger )
|
59
|
+
[ 200, { 'Content-Type' => 'text/html' }, [ html ] ]
|
60
|
+
end
|
61
|
+
|
62
|
+
def response_is_html( response )
|
63
|
+
return true if response.respond_to?( :content_type ) && response.content_type.match( %r{^text[/]html})
|
64
|
+
return true if response.is_a?( Array ) && response[1][ 'Content-Type' ] && response[1][ 'Content-Type' ].match( %r{^text[/]html})
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_logger_to_history( logger )
|
69
|
+
history.unshift logger.dup # pushes logger on beginning of Array
|
70
|
+
history.slice!( MAX_HISTORY ) # removes item above MAX_HISTORY if there is one
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_logger_to_response(response, gg )
|
74
|
+
css_link = %q{<link href="/gg/main.css" type="text/css" rel="stylesheet">}
|
75
|
+
body = ''
|
76
|
+
response[2].each { |s| body << s }
|
77
|
+
if body.sub!( /<!--\s*gg\s*-->/, gg.html ).nil?
|
78
|
+
body.insert( 0, gg.html )
|
79
|
+
end
|
80
|
+
if body.sub!( /<head>/, "<head>#{ css_link }" ).nil?
|
81
|
+
body.insert( 0, css_link )
|
82
|
+
end
|
83
|
+
response[2] = [ body ]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
span.hi-Hash
|
2
|
+
'{
|
3
|
+
.hi-indent
|
4
|
+
- self[ :object ].each_with_index do |key_value,i|
|
5
|
+
- key, value = *key_value
|
6
|
+
div
|
7
|
+
==' key.to_hi_html( self[ :history ] )
|
8
|
+
'=>
|
9
|
+
== value.to_hi_html( self[ :history ] )
|
10
|
+
- if i < self[ :object ].keys.size-1
|
11
|
+
',
|
12
|
+
'}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
link href="/gg/main.css" type="text/css" rel="stylesheet"
|
2
|
+
div style="margin:10px auto;width:940px;"
|
3
|
+
.hi-history-pagination
|
4
|
+
- (0..[self[:history].size-1,9].min).each do |i|
|
5
|
+
a href="/gg/history/#{ i }"
|
6
|
+
=i
|
7
|
+
-if self[ :logger ].nil?
|
8
|
+
h1.hi-history-heading No Log At This Position in History
|
9
|
+
-else
|
10
|
+
h1.hi-history-heading= self[ :logger ].request.path_info
|
11
|
+
p.hi-history-subheading= self[ :logger ].time
|
12
|
+
== self[ :logger ].html
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.hi-logger.hi-rounded-corners
|
2
|
+
.hi-logger-header
|
3
|
+
div.hi-code-info
|
4
|
+
= self[ :stack ][0].to_s
|
5
|
+
.hi-code-line
|
6
|
+
= self[ :stack ][0].code_line
|
7
|
+
.hi-logger-body
|
8
|
+
- self[ :objects ].each do |object|
|
9
|
+
.hi-logger-section
|
10
|
+
.hi-logger-output
|
11
|
+
== object.to_hi_html( self[ :history ] )
|
12
|
+
div style="clear:both;"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
div class="#{ self[ :classname ] }"
|
2
|
+
= "#<#{ self[ :object ].class }"
|
3
|
+
.hi-indent
|
4
|
+
- self[ :object ].instance_variables.each do |key|
|
5
|
+
div
|
6
|
+
span.hi-instance-variable
|
7
|
+
= key
|
8
|
+
':
|
9
|
+
== self[ :object ].instance_variable_get( key ).to_hi_html( self[ :history ] )
|
10
|
+
'>
|
File without changes
|
data/lib/gg/version.rb
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.7
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sunny Hirai
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &16668576 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *16668576
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: awesome_print
|
27
|
+
requirement: &16668192 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *16668192
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rack
|
38
|
+
requirement: &16684104 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *16684104
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: slim
|
49
|
+
requirement: &16682796 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *16682796
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: hi_caller
|
60
|
+
requirement: &16681908 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *16681908
|
69
|
+
description: Log to the Browser
|
70
|
+
email:
|
71
|
+
- thesunny@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .project
|
78
|
+
- Gemfile
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- gg.gemspec
|
82
|
+
- lib/gg.rb
|
83
|
+
- lib/gg/core.rb
|
84
|
+
- lib/gg/demo_app.rb
|
85
|
+
- lib/gg/logger.rb
|
86
|
+
- lib/gg/public/gg.css
|
87
|
+
- lib/gg/rack_plugin.rb
|
88
|
+
- lib/gg/slim/_logger.slim
|
89
|
+
- lib/gg/slim/array.slim
|
90
|
+
- lib/gg/slim/hash.slim
|
91
|
+
- lib/gg/slim/history.slim
|
92
|
+
- lib/gg/slim/index.slim
|
93
|
+
- lib/gg/slim/logger_with_multiple_variables.slim
|
94
|
+
- lib/gg/slim/object.slim
|
95
|
+
- lib/gg/slim/object_with_instance_variables.slim
|
96
|
+
- lib/gg/slim/section.slim
|
97
|
+
- lib/gg/slim/string.slim
|
98
|
+
- lib/gg/version.rb
|
99
|
+
- public/images/accept.png
|
100
|
+
homepage: ''
|
101
|
+
licenses: []
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project: gg
|
120
|
+
rubygems_version: 1.8.11
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Log to the Browser
|
124
|
+
test_files: []
|