coffeebox 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|