copy_tuner_client 0.0.15 → 0.1.0.beta
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 +15 -0
- data/.gitignore +0 -1
- data/.travis.yml +5 -5
- data/Appraisals +10 -7
- data/Gemfile.lock +33 -34
- data/README.md +2 -16
- data/Rakefile +3 -1
- data/app/assets/javascripts/copyray.js.coffee +285 -0
- data/app/assets/stylesheets/copyray.css +349 -0
- data/copy_tuner_client.gemspec +3 -3
- data/features/rails.feature +2 -16
- data/features/step_definitions/copycopter_server_steps.rb +1 -1
- data/features/step_definitions/rails_steps.rb +11 -20
- data/features/support/rails_server.rb +4 -30
- data/gemfiles/{4.0.gemfile → 2.3.gemfile} +2 -2
- data/gemfiles/2.3.gemfile.lock +108 -0
- data/gemfiles/{4.1.gemfile → 3.0.gemfile} +2 -2
- data/gemfiles/3.0.gemfile.lock +153 -0
- data/gemfiles/3.1.gemfile +11 -0
- data/gemfiles/3.1.gemfile.lock +191 -0
- data/lib/copy_tuner_client/cache.rb +0 -2
- data/lib/copy_tuner_client/configuration.rb +4 -4
- data/lib/copy_tuner_client/copyray.rb +29 -0
- data/lib/copy_tuner_client/copyray_middleware.rb +65 -0
- data/lib/copy_tuner_client/engine.rb +29 -0
- data/lib/copy_tuner_client/i18n_backend.rb +1 -2
- data/lib/copy_tuner_client/rails.rb +1 -1
- data/lib/copy_tuner_client/simple_form_extention.rb +19 -0
- data/lib/copy_tuner_client/version.rb +1 -1
- data/spec/copy_tuner_client/cache_spec.rb +3 -15
- data/spec/copy_tuner_client/configuration_spec.rb +1 -1
- data/spec/copy_tuner_client/request_sync_spec.rb +4 -4
- data/spec/support/fake_copy_tuner_app.rb +11 -14
- metadata +25 -60
- data/.ruby-version +0 -1
- data/gemfiles/3.2.gemfile +0 -7
- data/lib/copy_tuner_client/railtie.rb +0 -12
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZjkxOTQ4ODNlMDVlNDNkNWYxNjg1NTI5ZTMxNmY3ZTg4ZDMzYzgxNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODE4OTVlM2JmNWY5YjQyZjViMDBlNzdiYTFhOTlhNGMwMzQ5YjU2Yg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTA4YzcxOGZmMDNmYjNjMGIyZjhiYjYxNjNlYzc5YTE5NzU1YWVhMjNmZDI4
|
10
|
+
M2JlN2MwN2E3NmQ5ZWFhNzM1MzlmODE5N2I1MWE1NTVkOGUzN2EyMWNiMjc5
|
11
|
+
MDEyOTQwMDkyYzU4OTg2NDdlYzFiZmI1M2QwYWJmODMyMmNmZDM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
M2E0ZGMwN2E2MzNmNzM0MDliYmUwOTU3MmMxZjEzNGYzOTQ1NTY5OWE0OTU5
|
14
|
+
ODZlMTBlYzFhNjAyNWNlYWYwNzE4ZDFlNjBhNmJkNDQ2MGJhN2I3Yjc1YzU0
|
15
|
+
ZTA5MTRmZDI1YjJkOGNmNmNmOWQ2NzQ3MWM0NzVkNTUwMjZkZDk=
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Appraisals
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
appraise '3
|
2
|
-
gem 'rails', '3.
|
1
|
+
appraise '2.3' do
|
2
|
+
gem 'rails', '2.3.16'
|
3
3
|
end
|
4
4
|
|
5
|
-
appraise '
|
6
|
-
gem 'rails', '
|
5
|
+
appraise '3.0' do
|
6
|
+
gem 'rails', '3.0.20'
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
gem 'rails'
|
9
|
+
appraise '3.1' do
|
10
|
+
gem 'rails', '3.1.10'
|
11
|
+
gem 'jquery-rails'
|
12
|
+
gem 'uglifier'
|
13
|
+
gem 'sass-rails'
|
14
|
+
gem 'coffee-rails'
|
12
15
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
copy_tuner_client (0.0.
|
4
|
+
copy_tuner_client (0.1.0.beta)
|
5
5
|
i18n (>= 0.5.0)
|
6
6
|
json
|
7
7
|
|
@@ -39,38 +39,37 @@ GEM
|
|
39
39
|
multi_json (~> 1.0)
|
40
40
|
addressable (2.2.6)
|
41
41
|
ansi (1.4.3)
|
42
|
-
appraisal (
|
42
|
+
appraisal (0.4.0)
|
43
43
|
bundler
|
44
44
|
rake
|
45
|
-
thor (>= 0.14.0)
|
46
45
|
arel (2.2.1)
|
47
|
-
aruba (0.
|
48
|
-
childprocess (>= 0.
|
49
|
-
cucumber (>=
|
50
|
-
rspec
|
46
|
+
aruba (0.3.7)
|
47
|
+
childprocess (>= 0.1.9)
|
48
|
+
cucumber (>= 0.10.5)
|
49
|
+
rspec (>= 2.6.0)
|
51
50
|
bcrypt-ruby (3.0.0)
|
52
51
|
bourne (1.0)
|
53
52
|
mocha (= 0.9.8)
|
54
|
-
builder (3.0.
|
55
|
-
childprocess (0.
|
56
|
-
ffi (~> 1.0
|
53
|
+
builder (3.0.0)
|
54
|
+
childprocess (0.2.2)
|
55
|
+
ffi (~> 1.0.6)
|
57
56
|
crack (0.1.8)
|
58
|
-
cucumber (
|
57
|
+
cucumber (0.10.7)
|
59
58
|
builder (>= 2.1.2)
|
60
|
-
diff-lcs (>= 1.1.
|
61
|
-
gherkin (~> 2.
|
62
|
-
|
63
|
-
|
59
|
+
diff-lcs (>= 1.1.2)
|
60
|
+
gherkin (~> 2.4.0)
|
61
|
+
json (>= 1.4.6)
|
62
|
+
term-ansicolor (>= 1.0.5)
|
64
63
|
daemons (1.1.4)
|
65
|
-
diff-lcs (1.
|
64
|
+
diff-lcs (1.1.3)
|
66
65
|
erubis (2.7.0)
|
67
66
|
eventmachine (0.12.10)
|
68
|
-
ffi (1.9
|
69
|
-
gherkin (2.
|
70
|
-
|
67
|
+
ffi (1.0.9)
|
68
|
+
gherkin (2.4.18)
|
69
|
+
json (>= 1.4.6)
|
71
70
|
hike (1.2.1)
|
72
71
|
i18n (0.6.0)
|
73
|
-
json (1.
|
72
|
+
json (1.5.4)
|
74
73
|
mail (2.3.0)
|
75
74
|
i18n (>= 0.4.0)
|
76
75
|
mime-types (~> 1.16)
|
@@ -78,8 +77,7 @@ GEM
|
|
78
77
|
mime-types (1.16)
|
79
78
|
mocha (0.9.8)
|
80
79
|
rake
|
81
|
-
multi_json (1.
|
82
|
-
multi_test (0.1.1)
|
80
|
+
multi_json (1.0.3)
|
83
81
|
polyglot (0.3.2)
|
84
82
|
rack (1.3.2)
|
85
83
|
rack-cache (1.0.3)
|
@@ -105,16 +103,16 @@ GEM
|
|
105
103
|
rake (>= 0.8.7)
|
106
104
|
rdoc (~> 3.4)
|
107
105
|
thor (~> 0.14.6)
|
108
|
-
rake (10.3
|
106
|
+
rake (10.0.3)
|
109
107
|
rdoc (3.9.4)
|
110
|
-
rspec (2.
|
111
|
-
rspec-core (~> 2.
|
112
|
-
rspec-expectations (~> 2.
|
113
|
-
rspec-mocks (~> 2.
|
114
|
-
rspec-core (2.
|
115
|
-
rspec-expectations (2.
|
116
|
-
diff-lcs (
|
117
|
-
rspec-mocks (2.
|
108
|
+
rspec (2.6.0)
|
109
|
+
rspec-core (~> 2.6.0)
|
110
|
+
rspec-expectations (~> 2.6.0)
|
111
|
+
rspec-mocks (~> 2.6.0)
|
112
|
+
rspec-core (2.6.4)
|
113
|
+
rspec-expectations (2.6.0)
|
114
|
+
diff-lcs (~> 1.1.2)
|
115
|
+
rspec-mocks (2.6.0)
|
118
116
|
sham_rack (1.3.3)
|
119
117
|
rack
|
120
118
|
sinatra (1.2.6)
|
@@ -125,6 +123,7 @@ GEM
|
|
125
123
|
rack (~> 1.0)
|
126
124
|
tilt (~> 1.1, != 1.3.0)
|
127
125
|
sqlite3 (1.3.4)
|
126
|
+
term-ansicolor (1.0.6)
|
128
127
|
thin (1.2.11)
|
129
128
|
daemons (>= 1.0.9)
|
130
129
|
eventmachine (>= 0.12.6)
|
@@ -146,11 +145,11 @@ PLATFORMS
|
|
146
145
|
ruby
|
147
146
|
|
148
147
|
DEPENDENCIES
|
149
|
-
appraisal (~>
|
150
|
-
aruba (~> 0.
|
148
|
+
appraisal (~> 0.4)
|
149
|
+
aruba (~> 0.3.2)
|
151
150
|
bourne
|
152
151
|
copy_tuner_client!
|
153
|
-
cucumber (~>
|
152
|
+
cucumber (~> 0.10.0)
|
154
153
|
i18n
|
155
154
|
rails (~> 3.1.0)
|
156
155
|
rake
|
data/README.md
CHANGED
@@ -4,23 +4,9 @@ CopyTuner Client
|
|
4
4
|
[TODO] Write After
|
5
5
|
|
6
6
|
|
7
|
-
|
8
|
-
Development
|
9
|
-
=================
|
10
|
-
|
11
7
|
## Spec
|
12
8
|
|
13
|
-
### default spec
|
14
|
-
|
15
|
-
$ bundle exec rake
|
16
|
-
|
17
9
|
### Appraisal for Multi Version Rails spec
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
## release gem
|
23
|
-
|
24
|
-
$ bundle exec rake build # build gem to pkg/ dir
|
25
|
-
$ bundle exec rake install # install to local gem
|
26
|
-
$ bundle exec rake release # release gem to rubygems.org
|
11
|
+
rake appraisal:install
|
12
|
+
rake appraisal
|
data/Rakefile
CHANGED
@@ -5,7 +5,9 @@ require 'rspec/core/rake_task'
|
|
5
5
|
require 'yard'
|
6
6
|
|
7
7
|
desc 'Default: run the specs and features.'
|
8
|
-
task :default =>
|
8
|
+
task :default => :spec do
|
9
|
+
system "rake -s appraisal cucumber;"
|
10
|
+
end
|
9
11
|
|
10
12
|
desc 'Test the copy_tuner_client plugin.'
|
11
13
|
RSpec::Core::RakeTask.new do |t|
|
@@ -0,0 +1,285 @@
|
|
1
|
+
window.Xray = {}
|
2
|
+
return unless $ = window.jQuery
|
3
|
+
|
4
|
+
# Max CSS z-index. The overlay and xray bar use this.
|
5
|
+
MAX_ZINDEX = 2147483647
|
6
|
+
|
7
|
+
# Initialize Xray. Called immediately, but some setup is deferred until DOM ready.
|
8
|
+
Xray.init = do ->
|
9
|
+
return if Xray.initialized
|
10
|
+
Xray.initialized = true
|
11
|
+
|
12
|
+
is_mac = navigator.platform.toUpperCase().indexOf('MAC') isnt -1
|
13
|
+
|
14
|
+
# Register keyboard shortcuts
|
15
|
+
$(document).keydown (e) ->
|
16
|
+
# cmd+shift+x on Mac, ctrl+shift+x on other platforms
|
17
|
+
if (is_mac and e.metaKey or !is_mac and e.ctrlKey) and e.shiftKey and e.keyCode is 88
|
18
|
+
if Xray.isShowing then Xray.hide() else Xray.show()
|
19
|
+
if Xray.isShowing and e.keyCode is 27 # esc
|
20
|
+
Xray.hide()
|
21
|
+
|
22
|
+
$ ->
|
23
|
+
# Instantiate the overlay singleton.
|
24
|
+
new Xray.Overlay
|
25
|
+
# Go ahead and do a pass on the DOM to find templates.
|
26
|
+
Xray.findTemplates()
|
27
|
+
# Ready to rock.
|
28
|
+
console?.log "Ready to Xray. Press #{if is_mac then 'cmd+shift+x' else 'ctrl+shift+x'} to scan your UI."
|
29
|
+
|
30
|
+
# Returns all currently created Xray.Specimen objects.
|
31
|
+
Xray.specimens = ->
|
32
|
+
Xray.ViewSpecimen.all.concat Xray.TemplateSpecimen.all
|
33
|
+
|
34
|
+
# Looks up the stored constructor info
|
35
|
+
Xray.constructorInfo = (constructor) ->
|
36
|
+
if window.XrayPaths
|
37
|
+
for own info, func of window.XrayPaths
|
38
|
+
return JSON.parse(info) if func == constructor
|
39
|
+
null
|
40
|
+
|
41
|
+
# Scans the document for templates, creating Xray.TemplateSpecimens for them.
|
42
|
+
Xray.findTemplates = -> util.bm 'findTemplates', ->
|
43
|
+
# Find all <!-- XRAY START ... --> comments
|
44
|
+
comments = $('*:not(iframe,script)').contents().filter ->
|
45
|
+
this.nodeType == 8 and this.data[0..9] == "XRAY START"
|
46
|
+
|
47
|
+
# Find the <!-- XRAY END ... --> comment for each. Everything between the
|
48
|
+
# start and end comment becomes the contents of an Xray.TemplateSpecimen.
|
49
|
+
for comment in comments
|
50
|
+
[_, id, path] = comment.data.match(/^XRAY START (\d+) (.*)$/)
|
51
|
+
$templateContents = new jQuery
|
52
|
+
el = comment.nextSibling
|
53
|
+
until !el or (el.nodeType == 8 and el.data == "XRAY END #{id}")
|
54
|
+
if el.nodeType == 1 and el.tagName != 'SCRIPT'
|
55
|
+
$templateContents.push el
|
56
|
+
el = el.nextSibling
|
57
|
+
# Remove XRAY template comments from the DOM.
|
58
|
+
el.parentNode.removeChild(el) if el?.nodeType == 8
|
59
|
+
comment.parentNode.removeChild(comment)
|
60
|
+
# Add the template specimen
|
61
|
+
Xray.TemplateSpecimen.add $templateContents,
|
62
|
+
name: path.split('/').slice(-1)[0]
|
63
|
+
path: path
|
64
|
+
|
65
|
+
# Open the given filesystem path by calling out to Xray's server.
|
66
|
+
Xray.open = (path) ->
|
67
|
+
$.ajax(url: "/_xray/open?path=#{path}")
|
68
|
+
|
69
|
+
# Show the Xray overlay
|
70
|
+
Xray.show = (type = null) ->
|
71
|
+
Xray.Overlay.instance().show(type)
|
72
|
+
|
73
|
+
# Hide the Xray overlay
|
74
|
+
Xray.hide = ->
|
75
|
+
Xray.Overlay.instance().hide()
|
76
|
+
|
77
|
+
Xray.toggleSettings = ->
|
78
|
+
Xray.Overlay.instance().settings.toggle()
|
79
|
+
|
80
|
+
# Wraps a DOM element that Xray is tracking. This is subclassed by
|
81
|
+
# Xray.TemplateSpecimen and Xray.ViewSpecimen.
|
82
|
+
class Xray.Specimen
|
83
|
+
@add: (el, info = {}) ->
|
84
|
+
@all.push new this(el, info)
|
85
|
+
|
86
|
+
@remove: (el) ->
|
87
|
+
@find(el)?.remove()
|
88
|
+
|
89
|
+
@find: (el) ->
|
90
|
+
el = el[0] if el instanceof jQuery
|
91
|
+
for specimen in @all
|
92
|
+
return specimen if specimen.el == el
|
93
|
+
null
|
94
|
+
|
95
|
+
@reset: ->
|
96
|
+
@all = []
|
97
|
+
|
98
|
+
constructor: (contents, info = {}) ->
|
99
|
+
@el = if contents instanceof jQuery then contents[0] else contents
|
100
|
+
@$contents = $(contents)
|
101
|
+
@name = info.name
|
102
|
+
@path = info.path
|
103
|
+
|
104
|
+
remove: ->
|
105
|
+
idx = @constructor.all.indexOf(this)
|
106
|
+
@constructor.all.splice(idx, 1) unless idx == -1
|
107
|
+
|
108
|
+
isVisible: ->
|
109
|
+
@$contents.length and @$contents.is(':visible')
|
110
|
+
|
111
|
+
makeBox: ->
|
112
|
+
@bounds = util.computeBoundingBox(@$contents)
|
113
|
+
@$box = $("<div class='xray-specimen #{@constructor.name}'>").css(@bounds)
|
114
|
+
|
115
|
+
# If the element is fixed, override the computed position with the fixed one.
|
116
|
+
if @$contents.css('position') == 'fixed'
|
117
|
+
@$box.css
|
118
|
+
position : 'fixed'
|
119
|
+
top : @$contents.css('top')
|
120
|
+
left : @$contents.css('left')
|
121
|
+
|
122
|
+
@$box.click => Xray.open @path
|
123
|
+
@$box.append @makeLabel
|
124
|
+
|
125
|
+
makeLabel: =>
|
126
|
+
$("<div class='xray-specimen-handle #{@constructor.name}'>").append(@name)
|
127
|
+
|
128
|
+
|
129
|
+
# Wraps elements that constitute a Javascript "view" object, e.g.
|
130
|
+
# Backbone.View.
|
131
|
+
class Xray.ViewSpecimen extends Xray.Specimen
|
132
|
+
@all = []
|
133
|
+
|
134
|
+
|
135
|
+
# Wraps elements that were rendered by a template, e.g. a Rails partial or
|
136
|
+
# a client-side rendered JS template.
|
137
|
+
class Xray.TemplateSpecimen extends Xray.Specimen
|
138
|
+
@all = []
|
139
|
+
|
140
|
+
|
141
|
+
# Singleton class for the Xray "overlay" invoked by the keyboard shortcut
|
142
|
+
class Xray.Overlay
|
143
|
+
@instance: ->
|
144
|
+
@singletonInstance ||= new this
|
145
|
+
|
146
|
+
constructor: ->
|
147
|
+
Xray.Overlay.singletonInstance = this
|
148
|
+
@bar = new Xray.Bar('#xray-bar')
|
149
|
+
@settings = new Xray.Settings('#xray-settings')
|
150
|
+
@shownBoxes = []
|
151
|
+
@$overlay = $('<div id="xray-overlay">')
|
152
|
+
@$overlay.click => @hide()
|
153
|
+
|
154
|
+
show: (type = null) ->
|
155
|
+
@reset()
|
156
|
+
Xray.isShowing = true
|
157
|
+
util.bm 'show', =>
|
158
|
+
@bar.$el.find('#xray-bar-togglers .xray-bar-btn').removeClass('active')
|
159
|
+
unless @$overlay.is(':visible')
|
160
|
+
$('body').append @$overlay
|
161
|
+
@bar.show()
|
162
|
+
switch type
|
163
|
+
when 'templates'
|
164
|
+
Xray.findTemplates()
|
165
|
+
specimens = Xray.TemplateSpecimen.all
|
166
|
+
@bar.$el.find('.xray-bar-templates-toggler').addClass('active')
|
167
|
+
when 'views'
|
168
|
+
specimens = Xray.ViewSpecimen.all
|
169
|
+
@bar.$el.find('.xray-bar-views-toggler').addClass('active')
|
170
|
+
else
|
171
|
+
Xray.findTemplates()
|
172
|
+
specimens = Xray.specimens()
|
173
|
+
@bar.$el.find('.xray-bar-all-toggler').addClass('active')
|
174
|
+
for element in specimens
|
175
|
+
continue unless element.isVisible()
|
176
|
+
element.makeBox()
|
177
|
+
# A cheap way to "order" the boxes, where boxes positioned closer to the
|
178
|
+
# bottom right of the document have a higher z-index.
|
179
|
+
element.$box.css
|
180
|
+
zIndex: Math.ceil(MAX_ZINDEX*0.9 + element.bounds.top + element.bounds.left)
|
181
|
+
@shownBoxes.push element.$box
|
182
|
+
$('body').append element.$box
|
183
|
+
|
184
|
+
reset: ->
|
185
|
+
$box.remove() for $box in @shownBoxes
|
186
|
+
@shownBoxes = []
|
187
|
+
|
188
|
+
hide: ->
|
189
|
+
Xray.isShowing = false
|
190
|
+
@$overlay.detach()
|
191
|
+
@reset()
|
192
|
+
@bar.hide()
|
193
|
+
|
194
|
+
|
195
|
+
# The Xray bar shows controller, action, and view information, and has
|
196
|
+
# toggle buttons for showing the different types of specimens in the overlay.
|
197
|
+
class Xray.Bar
|
198
|
+
constructor: (el) ->
|
199
|
+
@$el = $(el)
|
200
|
+
@$el.css(zIndex: MAX_ZINDEX)
|
201
|
+
@$el.find('#xray-bar-controller-path .xray-bar-btn').click ->
|
202
|
+
Xray.open($(this).attr('data-path'))
|
203
|
+
@$el.find('.xray-bar-all-toggler').click -> Xray.show()
|
204
|
+
@$el.find('.xray-bar-templates-toggler').click -> Xray.show('templates')
|
205
|
+
@$el.find('.xray-bar-views-toggler').click -> Xray.show('views')
|
206
|
+
@$el.find('.xray-bar-settings-btn').click -> Xray.toggleSettings()
|
207
|
+
|
208
|
+
show: ->
|
209
|
+
@$el.show()
|
210
|
+
@originalPadding = parseInt $('html').css('padding-bottom')
|
211
|
+
if @originalPadding < 40
|
212
|
+
$('html').css paddingBottom: 40
|
213
|
+
|
214
|
+
hide: ->
|
215
|
+
@$el.hide()
|
216
|
+
$('html').css paddingBottom: @originalPadding
|
217
|
+
|
218
|
+
|
219
|
+
class Xray.Settings
|
220
|
+
constructor: (el) ->
|
221
|
+
@$el = $(el)
|
222
|
+
@$el.find('form').submit @save
|
223
|
+
|
224
|
+
toggle: =>
|
225
|
+
@$el.toggle()
|
226
|
+
|
227
|
+
save: (e) =>
|
228
|
+
e.preventDefault()
|
229
|
+
editor = @$el.find('#xray-editor-input').val()
|
230
|
+
$.ajax
|
231
|
+
url: '/_xray/config'
|
232
|
+
type: 'POST'
|
233
|
+
data: {editor: editor}
|
234
|
+
success: => @displayUpdateMsg(true)
|
235
|
+
error: => @displayUpdateMsg(false)
|
236
|
+
|
237
|
+
displayUpdateMsg: (success) =>
|
238
|
+
if success
|
239
|
+
$msg = $("<span class='xray-settings-success xray-settings-update-msg'>Success!</span>")
|
240
|
+
else
|
241
|
+
$msg = $("<span class='xray-settings-error xray-settings-update-msg'>Uh oh, something went wrong!</span>")
|
242
|
+
@$el.append($msg)
|
243
|
+
$msg.delay(2000).fadeOut(500, => $msg.remove(); @toggle())
|
244
|
+
|
245
|
+
|
246
|
+
# Utility methods.
|
247
|
+
util =
|
248
|
+
# Benchmark a piece of code
|
249
|
+
bm: (name, fn) ->
|
250
|
+
time = new Date
|
251
|
+
result = fn()
|
252
|
+
# console.log "#{name} : #{new Date() - time}ms"
|
253
|
+
result
|
254
|
+
|
255
|
+
# Computes the bounding box of a jQuery set, which may be many sibling
|
256
|
+
# elements with no parent in the set.
|
257
|
+
computeBoundingBox: ($contents) ->
|
258
|
+
# Edge case: the container may not physically wrap its children, for
|
259
|
+
# example if they are floated and no clearfix is present.
|
260
|
+
if $contents.length == 1 and $contents.height() <= 0
|
261
|
+
return util.computeBoundingBox($contents.children())
|
262
|
+
|
263
|
+
boxFrame =
|
264
|
+
top : Number.POSITIVE_INFINITY
|
265
|
+
left : Number.POSITIVE_INFINITY
|
266
|
+
right : Number.NEGATIVE_INFINITY
|
267
|
+
bottom : Number.NEGATIVE_INFINITY
|
268
|
+
|
269
|
+
for el in $contents
|
270
|
+
$el = $(el)
|
271
|
+
continue unless $el.is(':visible')
|
272
|
+
frame = $el.offset()
|
273
|
+
frame.right = frame.left + $el.outerWidth()
|
274
|
+
frame.bottom = frame.top + $el.outerHeight()
|
275
|
+
boxFrame.top = frame.top if frame.top < boxFrame.top
|
276
|
+
boxFrame.left = frame.left if frame.left < boxFrame.left
|
277
|
+
boxFrame.right = frame.right if frame.right > boxFrame.right
|
278
|
+
boxFrame.bottom = frame.bottom if frame.bottom > boxFrame.bottom
|
279
|
+
|
280
|
+
return {
|
281
|
+
left : boxFrame.left
|
282
|
+
top : boxFrame.top
|
283
|
+
width : boxFrame.right - boxFrame.left
|
284
|
+
height : boxFrame.bottom - boxFrame.top
|
285
|
+
}
|