coffeebox 0.0.3
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/coffeebox.js.coffee +3 -0
- data/app/assets/javascripts/coffeebox/imgpreload.js.coffee +50 -0
- data/app/assets/javascripts/coffeebox/main.js.coffee +222 -0
- data/app/assets/javascripts/coffeebox/spin.js +355 -0
- data/app/assets/stylesheets/coffeebox.css.sass +67 -0
- data/coffeebox.gemspec +25 -0
- data/lib/coffeebox.rb +4 -0
- data/lib/coffeebox/engine.rb +5 -0
- data/lib/coffeebox/version.rb +3 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e644c896b42d51146dc5efde89a445afdbad05b3
|
4
|
+
data.tar.gz: d20b14e690c374431bb5ddc069cd1ea7ed076e6a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a71d814d9c7a2e0e4a2342a664bbc3e6eb5cc4eba4b0cbf8e0b409572edc55b152690886c54d91c8bbdd4509f22f5804196f619ac1ea32f3e73c956d8110c18
|
7
|
+
data.tar.gz: def05fdf40007b4a1b64d456b448986e15fb0287f307df09ab45875007d3fe6f7f1264cd2463152ee756ce367813fc19684775611fc6feefaf8e798f4c68377d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 glebtv
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Coffeebox
|
2
|
+
|
3
|
+
This is an opinionated rewrite of [Facebox](http://defunkt.github.com/facebox/).
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
1. Everything is converted to coffescript
|
8
|
+
2. Shipped as a Rails 3.2/4.0 asset pipeline compatible gem
|
9
|
+
3. Includes [spin.js](http://fgnass.github.io/spin.js/) instead of a gif preloader
|
10
|
+
4. Preloads images with [imgpreload](https://github.com/farinspace/jquery.imgpreload)
|
11
|
+
5. Built-in support for turbolinks
|
12
|
+
6. Support for fully custom popup HTML
|
13
|
+
7. Does not stay in DOM when closed
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'coffeebox'
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install coffeebox
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
require it in application.js
|
32
|
+
|
33
|
+
//= require coffeebox
|
34
|
+
|
35
|
+
Or require it in application.js.coffe
|
36
|
+
|
37
|
+
#= require coffeebox
|
38
|
+
|
39
|
+
and in application.css.sass:
|
40
|
+
|
41
|
+
//= require coffeebox
|
42
|
+
|
43
|
+
or (sass\scss only)
|
44
|
+
|
45
|
+
// Set some options
|
46
|
+
$facebox-background: #fff
|
47
|
+
$facebox-close-color: #000
|
48
|
+
$facebox-close-hover: #333
|
49
|
+
$facebox-close-size: 25px
|
50
|
+
$facebox-border: 3px solid rgba(0, 0, 0, 0)
|
51
|
+
$facebox-border-radius: 25px
|
52
|
+
|
53
|
+
// Then import
|
54
|
+
@import coffeebox
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
1. Fork it
|
59
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
61
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# v1.4
|
2
|
+
#Copyright (c) 2009 Dimas Begunoff, http://www.farinspace.com
|
3
|
+
#
|
4
|
+
#https://github.com/farinspace/jquery.imgpreload
|
5
|
+
#
|
6
|
+
# Licensed under the MIT:
|
7
|
+
# http://www.opensource.org/licenses/mit-license.php
|
8
|
+
|
9
|
+
unless "undefined" is typeof jQuery
|
10
|
+
(($) ->
|
11
|
+
|
12
|
+
# extend jquery (because i love jQuery)
|
13
|
+
$.imgpreload = (imgs, settings) ->
|
14
|
+
settings = $.extend({}, $.fn.imgpreload.defaults, (if (settings instanceof Function) then all: settings else settings))
|
15
|
+
|
16
|
+
# use of typeof required
|
17
|
+
# https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Operators/Special_Operators/Instanceof_Operator#Description
|
18
|
+
imgs = new Array(imgs) if "string" is typeof imgs
|
19
|
+
loaded = new Array()
|
20
|
+
$.each imgs, (i, elem) ->
|
21
|
+
img = new Image()
|
22
|
+
url = elem
|
23
|
+
img_obj = img
|
24
|
+
unless "string" is typeof elem
|
25
|
+
url = $(elem).attr("src")
|
26
|
+
img_obj = elem
|
27
|
+
$(img).bind "load error", (e) ->
|
28
|
+
loaded.push img_obj
|
29
|
+
$.data img_obj, "loaded", (if ("error" is e.type) then false else true)
|
30
|
+
settings.each.call(img_obj) if settings.each instanceof Function
|
31
|
+
|
32
|
+
# http://jsperf.com/length-in-a-variable
|
33
|
+
if loaded.length >= imgs.length and settings.all instanceof Function
|
34
|
+
settings.all.call(loaded)
|
35
|
+
|
36
|
+
$(this).unbind "load error"
|
37
|
+
|
38
|
+
img.src = url
|
39
|
+
|
40
|
+
|
41
|
+
$.fn.imgpreload = (settings) ->
|
42
|
+
$.imgpreload this, settings
|
43
|
+
this
|
44
|
+
|
45
|
+
$.fn.imgpreload.defaults =
|
46
|
+
each: null # callback invoked when each image in a group loads
|
47
|
+
all: null # callback invoked when when the entire group of images has loaded
|
48
|
+
) jQuery
|
49
|
+
|
50
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# Coffeebox (for jQuery) version: 0.1
|
2
|
+
# @requires jQuery v1.2 or later
|
3
|
+
# @homepage https://github.com/rs-pro/coffeebox
|
4
|
+
#
|
5
|
+
# Licensed under the MIT:
|
6
|
+
# http://www.opensource.org/licenses/mit-license.php
|
7
|
+
#
|
8
|
+
# Copyright (c) 2013 RocketScience.pro
|
9
|
+
#
|
10
|
+
# Based on coffeebox: https://github.com/defunkt/coffeebox
|
11
|
+
# Copyright Forever Chris Wanstrath, Kyle Neath
|
12
|
+
|
13
|
+
$.fn.stopSpinner = ->
|
14
|
+
$(this).each ->
|
15
|
+
$t = $(this)
|
16
|
+
spinner = $t.data('spinner')
|
17
|
+
if spinner
|
18
|
+
spinner.stop()
|
19
|
+
$t.removeData('spinner')
|
20
|
+
|
21
|
+
$.coffeebox = (data, klass) ->
|
22
|
+
if data.ajax
|
23
|
+
$.coffeebox.loading data.settings or []
|
24
|
+
fillcoffeeboxFromAjax data.ajax, klass
|
25
|
+
else if data.image
|
26
|
+
$.coffeebox.loading data.settings or []
|
27
|
+
fillcoffeeboxFromImage data.image, klass
|
28
|
+
else if data.div
|
29
|
+
fillcoffeeboxFromHref data.div, klass
|
30
|
+
else if $.isFunction(data)
|
31
|
+
data.call $
|
32
|
+
else
|
33
|
+
$.coffeebox.reveal data, klass
|
34
|
+
|
35
|
+
# Public, $.coffeebox methods
|
36
|
+
$.extend $.coffeebox,
|
37
|
+
spinner:
|
38
|
+
lines: 11 # The number of lines to draw
|
39
|
+
length: 13 # The length of each line
|
40
|
+
width: 4 # The line thickness
|
41
|
+
radius: 13 # The radius of the inner circle
|
42
|
+
corners: 1 # Corner roundness (0..1)
|
43
|
+
color: "#000" # #rgb or #rrggbb or array of colors
|
44
|
+
speed: 1 # Rounds per second
|
45
|
+
trail: 89 # Afterglow percentage
|
46
|
+
hwaccel: true # Whether to use hardware acceleration
|
47
|
+
className: "spinner" # The CSS class to assign to the spinner
|
48
|
+
|
49
|
+
settings:
|
50
|
+
overlay: true
|
51
|
+
imageTypes: ["png", "jpg", "jpeg", "gif"]
|
52
|
+
html: """
|
53
|
+
<div id="coffeebox" style="display:none;">
|
54
|
+
<div class="popup">
|
55
|
+
<div class="content"></div>
|
56
|
+
<a class="close">×</a>
|
57
|
+
</div>
|
58
|
+
</div>
|
59
|
+
"""
|
60
|
+
|
61
|
+
loading: ->
|
62
|
+
init()
|
63
|
+
return true if $("#coffeebox .loading").length is 1
|
64
|
+
showOverlay()
|
65
|
+
$("#coffeebox .content").empty().append "<div class='loading'></div>"
|
66
|
+
$(document).bind "keydown.coffeebox", (e) ->
|
67
|
+
$.coffeebox.close() if e.keyCode is 27
|
68
|
+
true
|
69
|
+
$(document).trigger "loading.coffeebox"
|
70
|
+
$.coffeebox.align()
|
71
|
+
setTimeout ->
|
72
|
+
new Spinner($.coffeebox.spinner).spin($('#coffeebox .loading')[0])
|
73
|
+
, 0
|
74
|
+
$('#coffeebox')
|
75
|
+
|
76
|
+
align: ->
|
77
|
+
$("#coffeebox").show().css
|
78
|
+
top: getPageScroll()[1] + (getPageHeight() / 10)
|
79
|
+
left: $(window).width() / 2 - ($("#coffeebox .popup").outerWidth() / 2)
|
80
|
+
|
81
|
+
reveal: (data, klass) ->
|
82
|
+
if $("#coffebox .loading").length
|
83
|
+
$("#coffebox .loading").stopSpinner()
|
84
|
+
init()
|
85
|
+
$(document).trigger "beforeReveal.coffeebox"
|
86
|
+
$("#coffeebox .content").addClass klass if klass
|
87
|
+
$("#coffeebox .content").empty().append data
|
88
|
+
$("#coffeebox .popup").children().fadeIn "normal"
|
89
|
+
$(document).trigger("reveal.coffeebox").trigger "afterReveal.coffeebox"
|
90
|
+
$.coffeebox.align()
|
91
|
+
close: ->
|
92
|
+
$(document).trigger "close.coffeebox"
|
93
|
+
false
|
94
|
+
|
95
|
+
# Public, $.fn methods
|
96
|
+
$.fn.coffeebox = (settings) ->
|
97
|
+
clickHandler = ->
|
98
|
+
$.coffeebox.loading()
|
99
|
+
|
100
|
+
# support for rel="coffeebox.inline_popup" syntax, to add a class
|
101
|
+
# also supports deprecated "coffeebox[.inline_popup]" syntax
|
102
|
+
klass = @rel.match(/coffeebox\[?\.(\w+)\]?/)
|
103
|
+
klass = klass[1] if klass
|
104
|
+
fillcoffeeboxFromHref @href, klass
|
105
|
+
false
|
106
|
+
return init(settings) if $(this).length is 0
|
107
|
+
@bind "click.coffeebox", clickHandler
|
108
|
+
|
109
|
+
# Private methods
|
110
|
+
|
111
|
+
# called one time to setup coffeebox on this page
|
112
|
+
init = (settings) ->
|
113
|
+
if $('#coffeebox').length > 0
|
114
|
+
return true
|
115
|
+
$(document).trigger "init.coffeebox"
|
116
|
+
imageTypes = $.coffeebox.settings.imageTypes.join("|")
|
117
|
+
$.coffeebox.settings.imageTypesRegexp = new RegExp("\\.(" + imageTypes + ")(\\?.*)?$", "i")
|
118
|
+
$.extend $.coffeebox.settings, settings if settings
|
119
|
+
$("body").append $.coffeebox.settings.html
|
120
|
+
$("#coffeebox .close").click($.coffeebox.close)
|
121
|
+
|
122
|
+
# getPageScroll() by quirksmode.com
|
123
|
+
getPageScroll = ->
|
124
|
+
xScroll = undefined
|
125
|
+
yScroll = undefined
|
126
|
+
if self.pageYOffset
|
127
|
+
yScroll = self.pageYOffset
|
128
|
+
xScroll = self.pageXOffset
|
129
|
+
else if document.documentElement and document.documentElement.scrollTop # Explorer 6 Strict
|
130
|
+
yScroll = document.documentElement.scrollTop
|
131
|
+
xScroll = document.documentElement.scrollLeft
|
132
|
+
else if document.body # all other Explorers
|
133
|
+
yScroll = document.body.scrollTop
|
134
|
+
xScroll = document.body.scrollLeft
|
135
|
+
new Array(xScroll, yScroll)
|
136
|
+
|
137
|
+
# Adapted from getPageSize() by quirksmode.com
|
138
|
+
getPageHeight = ->
|
139
|
+
windowHeight = undefined
|
140
|
+
if self.innerHeight # all except Explorer
|
141
|
+
windowHeight = self.innerHeight
|
142
|
+
else if document.documentElement and document.documentElement.clientHeight # Explorer 6 Strict Mode
|
143
|
+
windowHeight = document.documentElement.clientHeight
|
144
|
+
# other Explorers
|
145
|
+
else windowHeight = document.body.clientHeight if document.body
|
146
|
+
windowHeight
|
147
|
+
|
148
|
+
# Figures out what you want to display and displays it
|
149
|
+
# formats are:
|
150
|
+
# div: #id
|
151
|
+
# image: blah.extension
|
152
|
+
# ajax: anything else
|
153
|
+
fillcoffeeboxFromHref = (href, klass) ->
|
154
|
+
# div
|
155
|
+
if href.match(/#/)
|
156
|
+
url = window.location.href.split("#")[0]
|
157
|
+
target = href.replace(url, "")
|
158
|
+
$.coffeebox.reveal $(target).html(), klass if target is "#"
|
159
|
+
|
160
|
+
# image
|
161
|
+
else if href.match($.coffeebox.settings.imageTypesRegexp)
|
162
|
+
fillcoffeeboxFromImage href, klass
|
163
|
+
|
164
|
+
# ajax
|
165
|
+
else
|
166
|
+
fillcoffeeboxFromAjax href, klass
|
167
|
+
|
168
|
+
fillcoffeeboxFromImage = (href, klass) ->
|
169
|
+
$.imgpreload href, (images)->
|
170
|
+
$.coffeebox.reveal "<div class='image'><img src='#{@[0].src}' /></div>", klass
|
171
|
+
|
172
|
+
fillcoffeeboxFromAjax = (href, klass) ->
|
173
|
+
$.coffeebox.jqxhr = $.get(href, (data) ->
|
174
|
+
$.coffeebox.reveal data, klass
|
175
|
+
)
|
176
|
+
|
177
|
+
skipOverlay = ->
|
178
|
+
$.coffeebox.settings.overlay is false
|
179
|
+
|
180
|
+
hideOverlay = ->
|
181
|
+
if skipOverlay()
|
182
|
+
false
|
183
|
+
else
|
184
|
+
$("#coffeebox_overlay").addClass('hide')
|
185
|
+
setTimeout ->
|
186
|
+
$("#coffeebox_overlay.hide").remove()
|
187
|
+
, 300
|
188
|
+
|
189
|
+
showOverlay = ->
|
190
|
+
if skipOverlay()
|
191
|
+
false
|
192
|
+
else
|
193
|
+
if $("#coffeebox_overlay").length is 0
|
194
|
+
$("body").append '<div id="coffeebox_overlay" class="hide"></div>'
|
195
|
+
$("#coffeebox_overlay").click(->
|
196
|
+
$(document).trigger "close.coffeebox"
|
197
|
+
)
|
198
|
+
setTimeout ->
|
199
|
+
$("#coffeebox_overlay").removeClass('hide')
|
200
|
+
, 10
|
201
|
+
else if $("#coffeebox_overlay").hasClass('hide')
|
202
|
+
$("#coffeebox_overlay").removeClass('hide')
|
203
|
+
|
204
|
+
# Bindings
|
205
|
+
$(document).bind "close.coffeebox", ->
|
206
|
+
if $.coffeebox.jqxhr
|
207
|
+
$.coffeebox.jqxhr.abort()
|
208
|
+
$.coffeebox.jqxhr = null
|
209
|
+
|
210
|
+
$(document).unbind "keydown.coffeebox"
|
211
|
+
$('#coffeebox').fadeOut ->
|
212
|
+
if $("#coffebox .loading").length
|
213
|
+
$("#coffebox .loading").stopSpinner()
|
214
|
+
$('#coffeebox').remove()
|
215
|
+
$(document).trigger "afterClose.coffeebox"
|
216
|
+
|
217
|
+
hideOverlay()
|
218
|
+
|
219
|
+
# shorter alias
|
220
|
+
$.cbox = $.coffebox
|
221
|
+
$.fn.cbox = $.fn.coffebox
|
222
|
+
|
@@ -0,0 +1,355 @@
|
|
1
|
+
//fgnass.github.com/spin.js#v1.3.2
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Copyright (c) 2011-2013 Felix Gnass
|
5
|
+
* Licensed under the MIT license
|
6
|
+
*/
|
7
|
+
(function(root, factory) {
|
8
|
+
|
9
|
+
/* CommonJS */
|
10
|
+
if (typeof exports == 'object') module.exports = factory()
|
11
|
+
|
12
|
+
/* AMD module */
|
13
|
+
else if (typeof define == 'function' && define.amd) define(factory)
|
14
|
+
|
15
|
+
/* Browser global */
|
16
|
+
else root.Spinner = factory()
|
17
|
+
}
|
18
|
+
(this, function() {
|
19
|
+
"use strict";
|
20
|
+
|
21
|
+
var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
|
22
|
+
, animations = {} /* Animation rules keyed by their name */
|
23
|
+
, useCssAnimations /* Whether to use CSS animations or setTimeout */
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Utility function to create elements. If no tag name is given,
|
27
|
+
* a DIV is created. Optionally properties can be passed.
|
28
|
+
*/
|
29
|
+
function createEl(tag, prop) {
|
30
|
+
var el = document.createElement(tag || 'div')
|
31
|
+
, n
|
32
|
+
|
33
|
+
for(n in prop) el[n] = prop[n]
|
34
|
+
return el
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Appends children and returns the parent.
|
39
|
+
*/
|
40
|
+
function ins(parent /* child1, child2, ...*/) {
|
41
|
+
for (var i=1, n=arguments.length; i<n; i++)
|
42
|
+
parent.appendChild(arguments[i])
|
43
|
+
|
44
|
+
return parent
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Insert a new stylesheet to hold the @keyframe or VML rules.
|
49
|
+
*/
|
50
|
+
var sheet = (function() {
|
51
|
+
var el = createEl('style', {type : 'text/css'})
|
52
|
+
ins(document.getElementsByTagName('head')[0], el)
|
53
|
+
return el.sheet || el.styleSheet
|
54
|
+
}())
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Creates an opacity keyframe animation rule and returns its name.
|
58
|
+
* Since most mobile Webkits have timing issues with animation-delay,
|
59
|
+
* we create separate rules for each line/segment.
|
60
|
+
*/
|
61
|
+
function addAnimation(alpha, trail, i, lines) {
|
62
|
+
var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
|
63
|
+
, start = 0.01 + i/lines * 100
|
64
|
+
, z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
|
65
|
+
, prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
|
66
|
+
, pre = prefix && '-' + prefix + '-' || ''
|
67
|
+
|
68
|
+
if (!animations[name]) {
|
69
|
+
sheet.insertRule(
|
70
|
+
'@' + pre + 'keyframes ' + name + '{' +
|
71
|
+
'0%{opacity:' + z + '}' +
|
72
|
+
start + '%{opacity:' + alpha + '}' +
|
73
|
+
(start+0.01) + '%{opacity:1}' +
|
74
|
+
(start+trail) % 100 + '%{opacity:' + alpha + '}' +
|
75
|
+
'100%{opacity:' + z + '}' +
|
76
|
+
'}', sheet.cssRules.length)
|
77
|
+
|
78
|
+
animations[name] = 1
|
79
|
+
}
|
80
|
+
|
81
|
+
return name
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Tries various vendor prefixes and returns the first supported property.
|
86
|
+
*/
|
87
|
+
function vendor(el, prop) {
|
88
|
+
var s = el.style
|
89
|
+
, pp
|
90
|
+
, i
|
91
|
+
|
92
|
+
prop = prop.charAt(0).toUpperCase() + prop.slice(1)
|
93
|
+
for(i=0; i<prefixes.length; i++) {
|
94
|
+
pp = prefixes[i]+prop
|
95
|
+
if(s[pp] !== undefined) return pp
|
96
|
+
}
|
97
|
+
if(s[prop] !== undefined) return prop
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Sets multiple style properties at once.
|
102
|
+
*/
|
103
|
+
function css(el, prop) {
|
104
|
+
for (var n in prop)
|
105
|
+
el.style[vendor(el, n)||n] = prop[n]
|
106
|
+
|
107
|
+
return el
|
108
|
+
}
|
109
|
+
|
110
|
+
/**
|
111
|
+
* Fills in default values.
|
112
|
+
*/
|
113
|
+
function merge(obj) {
|
114
|
+
for (var i=1; i < arguments.length; i++) {
|
115
|
+
var def = arguments[i]
|
116
|
+
for (var n in def)
|
117
|
+
if (obj[n] === undefined) obj[n] = def[n]
|
118
|
+
}
|
119
|
+
return obj
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Returns the absolute page-offset of the given element.
|
124
|
+
*/
|
125
|
+
function pos(el) {
|
126
|
+
var o = { x:el.offsetLeft, y:el.offsetTop }
|
127
|
+
while((el = el.offsetParent))
|
128
|
+
o.x+=el.offsetLeft, o.y+=el.offsetTop
|
129
|
+
|
130
|
+
return o
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Returns the line color from the given string or array.
|
135
|
+
*/
|
136
|
+
function getColor(color, idx) {
|
137
|
+
return typeof color == 'string' ? color : color[idx % color.length]
|
138
|
+
}
|
139
|
+
|
140
|
+
// Built-in defaults
|
141
|
+
|
142
|
+
var defaults = {
|
143
|
+
lines: 12, // The number of lines to draw
|
144
|
+
length: 7, // The length of each line
|
145
|
+
width: 5, // The line thickness
|
146
|
+
radius: 10, // The radius of the inner circle
|
147
|
+
rotate: 0, // Rotation offset
|
148
|
+
corners: 1, // Roundness (0..1)
|
149
|
+
color: '#000', // #rgb or #rrggbb
|
150
|
+
direction: 1, // 1: clockwise, -1: counterclockwise
|
151
|
+
speed: 1, // Rounds per second
|
152
|
+
trail: 100, // Afterglow percentage
|
153
|
+
opacity: 1/4, // Opacity of the lines
|
154
|
+
fps: 20, // Frames per second when using setTimeout()
|
155
|
+
zIndex: 2e9, // Use a high z-index by default
|
156
|
+
className: 'spinner', // CSS class to assign to the element
|
157
|
+
top: 'auto', // center vertically
|
158
|
+
left: 'auto', // center horizontally
|
159
|
+
position: 'relative' // element position
|
160
|
+
}
|
161
|
+
|
162
|
+
/** The constructor */
|
163
|
+
function Spinner(o) {
|
164
|
+
if (typeof this == 'undefined') return new Spinner(o)
|
165
|
+
this.opts = merge(o || {}, Spinner.defaults, defaults)
|
166
|
+
}
|
167
|
+
|
168
|
+
// Global defaults that override the built-ins:
|
169
|
+
Spinner.defaults = {}
|
170
|
+
|
171
|
+
merge(Spinner.prototype, {
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Adds the spinner to the given target element. If this instance is already
|
175
|
+
* spinning, it is automatically removed from its previous target b calling
|
176
|
+
* stop() internally.
|
177
|
+
*/
|
178
|
+
spin: function(target) {
|
179
|
+
this.stop()
|
180
|
+
|
181
|
+
var self = this
|
182
|
+
, o = self.opts
|
183
|
+
, el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
|
184
|
+
, mid = o.radius+o.length+o.width
|
185
|
+
, ep // element position
|
186
|
+
, tp // target position
|
187
|
+
|
188
|
+
if (target) {
|
189
|
+
target.insertBefore(el, target.firstChild||null)
|
190
|
+
tp = pos(target)
|
191
|
+
ep = pos(el)
|
192
|
+
css(el, {
|
193
|
+
left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
|
194
|
+
top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
|
195
|
+
})
|
196
|
+
}
|
197
|
+
|
198
|
+
el.setAttribute('role', 'progressbar')
|
199
|
+
self.lines(el, self.opts)
|
200
|
+
|
201
|
+
if (!useCssAnimations) {
|
202
|
+
// No CSS animation support, use setTimeout() instead
|
203
|
+
var i = 0
|
204
|
+
, start = (o.lines - 1) * (1 - o.direction) / 2
|
205
|
+
, alpha
|
206
|
+
, fps = o.fps
|
207
|
+
, f = fps/o.speed
|
208
|
+
, ostep = (1-o.opacity) / (f*o.trail / 100)
|
209
|
+
, astep = f/o.lines
|
210
|
+
|
211
|
+
;(function anim() {
|
212
|
+
i++;
|
213
|
+
for (var j = 0; j < o.lines; j++) {
|
214
|
+
alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
|
215
|
+
|
216
|
+
self.opacity(el, j * o.direction + start, alpha, o)
|
217
|
+
}
|
218
|
+
self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
|
219
|
+
})()
|
220
|
+
}
|
221
|
+
return self
|
222
|
+
},
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Stops and removes the Spinner.
|
226
|
+
*/
|
227
|
+
stop: function() {
|
228
|
+
var el = this.el
|
229
|
+
if (el) {
|
230
|
+
clearTimeout(this.timeout)
|
231
|
+
if (el.parentNode) el.parentNode.removeChild(el)
|
232
|
+
this.el = undefined
|
233
|
+
}
|
234
|
+
return this
|
235
|
+
},
|
236
|
+
|
237
|
+
/**
|
238
|
+
* Internal method that draws the individual lines. Will be overwritten
|
239
|
+
* in VML fallback mode below.
|
240
|
+
*/
|
241
|
+
lines: function(el, o) {
|
242
|
+
var i = 0
|
243
|
+
, start = (o.lines - 1) * (1 - o.direction) / 2
|
244
|
+
, seg
|
245
|
+
|
246
|
+
function fill(color, shadow) {
|
247
|
+
return css(createEl(), {
|
248
|
+
position: 'absolute',
|
249
|
+
width: (o.length+o.width) + 'px',
|
250
|
+
height: o.width + 'px',
|
251
|
+
background: color,
|
252
|
+
boxShadow: shadow,
|
253
|
+
transformOrigin: 'left',
|
254
|
+
transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
|
255
|
+
borderRadius: (o.corners * o.width>>1) + 'px'
|
256
|
+
})
|
257
|
+
}
|
258
|
+
|
259
|
+
for (; i < o.lines; i++) {
|
260
|
+
seg = css(createEl(), {
|
261
|
+
position: 'absolute',
|
262
|
+
top: 1+~(o.width/2) + 'px',
|
263
|
+
transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
|
264
|
+
opacity: o.opacity,
|
265
|
+
animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
|
266
|
+
})
|
267
|
+
|
268
|
+
if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
|
269
|
+
ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')))
|
270
|
+
}
|
271
|
+
return el
|
272
|
+
},
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Internal method that adjusts the opacity of a single line.
|
276
|
+
* Will be overwritten in VML fallback mode below.
|
277
|
+
*/
|
278
|
+
opacity: function(el, i, val) {
|
279
|
+
if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
|
280
|
+
}
|
281
|
+
|
282
|
+
})
|
283
|
+
|
284
|
+
|
285
|
+
function initVML() {
|
286
|
+
|
287
|
+
/* Utility function to create a VML tag */
|
288
|
+
function vml(tag, attr) {
|
289
|
+
return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
|
290
|
+
}
|
291
|
+
|
292
|
+
// No CSS transforms but VML support, add a CSS rule for VML elements:
|
293
|
+
sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
|
294
|
+
|
295
|
+
Spinner.prototype.lines = function(el, o) {
|
296
|
+
var r = o.length+o.width
|
297
|
+
, s = 2*r
|
298
|
+
|
299
|
+
function grp() {
|
300
|
+
return css(
|
301
|
+
vml('group', {
|
302
|
+
coordsize: s + ' ' + s,
|
303
|
+
coordorigin: -r + ' ' + -r
|
304
|
+
}),
|
305
|
+
{ width: s, height: s }
|
306
|
+
)
|
307
|
+
}
|
308
|
+
|
309
|
+
var margin = -(o.width+o.length)*2 + 'px'
|
310
|
+
, g = css(grp(), {position: 'absolute', top: margin, left: margin})
|
311
|
+
, i
|
312
|
+
|
313
|
+
function seg(i, dx, filter) {
|
314
|
+
ins(g,
|
315
|
+
ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
|
316
|
+
ins(css(vml('roundrect', {arcsize: o.corners}), {
|
317
|
+
width: r,
|
318
|
+
height: o.width,
|
319
|
+
left: o.radius,
|
320
|
+
top: -o.width>>1,
|
321
|
+
filter: filter
|
322
|
+
}),
|
323
|
+
vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
|
324
|
+
vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
|
325
|
+
)
|
326
|
+
)
|
327
|
+
)
|
328
|
+
}
|
329
|
+
|
330
|
+
if (o.shadow)
|
331
|
+
for (i = 1; i <= o.lines; i++)
|
332
|
+
seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
|
333
|
+
|
334
|
+
for (i = 1; i <= o.lines; i++) seg(i)
|
335
|
+
return ins(el, g)
|
336
|
+
}
|
337
|
+
|
338
|
+
Spinner.prototype.opacity = function(el, i, val, o) {
|
339
|
+
var c = el.firstChild
|
340
|
+
o = o.shadow && o.lines || 0
|
341
|
+
if (c && i+o < c.childNodes.length) {
|
342
|
+
c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
|
343
|
+
if (c) c.opacity = val
|
344
|
+
}
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
|
349
|
+
|
350
|
+
if (!vendor(probe, 'transform') && probe.adj) initVML()
|
351
|
+
else useCssAnimations = vendor(probe, 'animation')
|
352
|
+
|
353
|
+
return Spinner
|
354
|
+
|
355
|
+
}));
|
@@ -0,0 +1,67 @@
|
|
1
|
+
$coffeebox-background: #fff !default
|
2
|
+
$coffeebox-close-color: #000 !default
|
3
|
+
$coffeebox-close-hover: #333 !default
|
4
|
+
$coffeebox-close-size: 25px !default
|
5
|
+
|
6
|
+
$coffeebox-border: 3px solid rgba(0, 0, 0, 0) !default
|
7
|
+
$coffeebox-border-radius: 25px !default
|
8
|
+
|
9
|
+
#coffeebox
|
10
|
+
position: absolute
|
11
|
+
top: 0
|
12
|
+
left: 0
|
13
|
+
z-index: 100
|
14
|
+
text-align: left
|
15
|
+
.loading
|
16
|
+
width: 400px
|
17
|
+
height: 200px
|
18
|
+
position: relative
|
19
|
+
.popup
|
20
|
+
position: relative
|
21
|
+
border: $coffeebox-border
|
22
|
+
border-radius: $coffeebox-border-radius
|
23
|
+
box-shadow: 0 0 18px rgba(0, 0, 0, 0.4)
|
24
|
+
.content
|
25
|
+
display: table
|
26
|
+
padding: 10px
|
27
|
+
background: $coffeebox-backgound
|
28
|
+
border-radius: $coffeebox-border-radius
|
29
|
+
min-width: 100px
|
30
|
+
min-height: 40px
|
31
|
+
> p
|
32
|
+
&:first-child
|
33
|
+
margin-top: 0
|
34
|
+
&:last-child
|
35
|
+
margin-bottom: 0
|
36
|
+
.close
|
37
|
+
cursor: pointer
|
38
|
+
position: absolute
|
39
|
+
top: 5px
|
40
|
+
right: 5px
|
41
|
+
padding: 2px
|
42
|
+
background: $coffeebox-background
|
43
|
+
font:
|
44
|
+
size: $coffeebox-close-size
|
45
|
+
weight: bold
|
46
|
+
text-decoration: none
|
47
|
+
color: $coffeebox-close-color
|
48
|
+
&:hover
|
49
|
+
color: $coffeebox-close-hover
|
50
|
+
.image
|
51
|
+
text-align: center
|
52
|
+
img
|
53
|
+
border: 0
|
54
|
+
margin: 0
|
55
|
+
|
56
|
+
#coffeebox_overlay
|
57
|
+
position: fixed
|
58
|
+
top: 0px
|
59
|
+
left: 0px
|
60
|
+
height: 100%
|
61
|
+
width: 100%
|
62
|
+
transition: opacity 0.3s ease
|
63
|
+
background-color: #000
|
64
|
+
z-index: 99
|
65
|
+
opacity: 0.4
|
66
|
+
&.hide
|
67
|
+
opacity: 0
|
data/coffeebox.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'coffeebox/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "coffeebox"
|
8
|
+
spec.version = Coffeebox::VERSION
|
9
|
+
spec.authors = ["glebtv"]
|
10
|
+
spec.email = ["glebtv@gmail.com"]
|
11
|
+
spec.description = %q{An opinionated rewrite of Facebox in coffescript bundled as a rails gem}
|
12
|
+
spec.summary = %q{An opinionated rewrite of Facebox in coffescript bundled as a rails gem}
|
13
|
+
spec.homepage = "https://github.com/rs-pro/coffeebox"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "rails", ">= 3.2"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
data/lib/coffeebox.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: coffeebox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- glebtv
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: An opinionated rewrite of Facebox in coffescript bundled as a rails gem
|
56
|
+
email:
|
57
|
+
- glebtv@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- app/assets/javascripts/coffeebox.js.coffee
|
68
|
+
- app/assets/javascripts/coffeebox/imgpreload.js.coffee
|
69
|
+
- app/assets/javascripts/coffeebox/main.js.coffee
|
70
|
+
- app/assets/javascripts/coffeebox/spin.js
|
71
|
+
- app/assets/stylesheets/coffeebox.css.sass
|
72
|
+
- coffeebox.gemspec
|
73
|
+
- lib/coffeebox.rb
|
74
|
+
- lib/coffeebox/engine.rb
|
75
|
+
- lib/coffeebox/version.rb
|
76
|
+
homepage: https://github.com/rs-pro/coffeebox
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.0.6
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: An opinionated rewrite of Facebox in coffescript bundled as a rails gem
|
100
|
+
test_files: []
|