right-rails 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +7 -3
- data/Rakefile +19 -0
- data/generators/right_rails/right_rails_generator.rb +8 -0
- data/images/colorpicker.png +0 -0
- data/images/resizable.png +0 -0
- data/javascripts/right-autocompleter-src.js +1 -4
- data/javascripts/right-calendar-src.js +0 -3
- data/javascripts/right-colorpicker-src.js +635 -0
- data/javascripts/right-colorpicker.js +9 -0
- data/javascripts/right-in-edit-src.js +1 -4
- data/javascripts/right-lightbox-src.js +2 -5
- data/javascripts/right-lightbox.js +1 -1
- data/javascripts/right-rails-src.js +29 -5
- data/javascripts/right-rails.js +1 -1
- data/javascripts/right-rater-src.js +1 -4
- data/javascripts/right-resizable-src.js +336 -0
- data/javascripts/right-resizable.js +9 -0
- data/javascripts/right-selectable-src.js +13 -11
- data/javascripts/right-selectable.js +1 -1
- data/javascripts/right-slider-src.js +1 -4
- data/javascripts/right-sortable-src.js +0 -1
- data/javascripts/right-tabs-src.js +2 -5
- data/javascripts/right-tooltips-src.js +19 -11
- data/javascripts/right-tooltips.js +1 -1
- data/javascripts/right-ui-i18n-de.js +8 -2
- data/javascripts/right-ui-i18n-es.js +7 -1
- data/javascripts/right-ui-i18n-fr.js +7 -1
- data/javascripts/right-ui-i18n-hu.js +6 -1
- data/javascripts/right-ui-i18n-jp.js +8 -1
- data/javascripts/right-ui-i18n-nl.js +8 -1
- data/javascripts/right-ui-i18n-pt-br.js +43 -0
- data/javascripts/right-ui-i18n-ru.js +8 -1
- data/javascripts/right-ui-i18n-ua.js +8 -1
- data/javascripts/right-uploader-src.js +1 -4
- data/lib/right_rails/helpers/basic.rb +7 -0
- data/lib/right_rails/helpers/forms.rb +44 -3
- data/lib/right_rails/helpers/misc.rb +55 -16
- data/lib/right_rails/java_script_generator.rb +4 -4
- data/spec/lib/right_rails/helpers/basic_spec.rb +4 -1
- data/spec/lib/right_rails/helpers/forms_spec.rb +10 -0
- data/spec/lib/right_rails/helpers/misc_spec.rb +39 -8
- metadata +11 -4
data/README.textile
CHANGED
@@ -37,15 +37,19 @@ h3. Usage
|
|
37
37
|
|
38
38
|
Install the plugin to your rails application
|
39
39
|
|
40
|
-
|
40
|
+
<pre>script/plugin install git://github.com/MadRabbit/right-rails.git</pre>
|
41
41
|
|
42
42
|
After that run the @right_rails@ generator, which will put all the JavaScripts in place
|
43
43
|
|
44
|
-
|
44
|
+
<pre>script/generate right_rails</pre>
|
45
|
+
|
46
|
+
And add the following helper to your application layout, this will include all the necessary scripts on your page
|
47
|
+
|
48
|
+
<pre><%= rightjs_scripts %></pre>
|
45
49
|
|
46
50
|
You also will have an ajax-friendly scaffold generator
|
47
51
|
|
48
|
-
|
52
|
+
<pre>script/generate right_scaffold Zing</pre>
|
49
53
|
|
50
54
|
h4. Ruby Gem
|
51
55
|
|
data/Rakefile
CHANGED
@@ -21,3 +21,22 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
21
21
|
rdoc.rdoc_files.include('README')
|
22
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
23
|
end
|
24
|
+
|
25
|
+
|
26
|
+
namespace :rjs do
|
27
|
+
desc 'Patches the JavaScript UI modules for new images location'
|
28
|
+
task :patch_ui do
|
29
|
+
FileList['javascripts/*.js'].each do |filename|
|
30
|
+
old_content = File.read(filename)
|
31
|
+
new_content = old_content.gsub('url(../../img/', "url(/images/rightjs-ui/")
|
32
|
+
new_content = new_content.gsub(/([^\s])no-repeat/, '\1 no-repeat') # front-compiler CSS compressor bug fix
|
33
|
+
|
34
|
+
if old_content != new_content
|
35
|
+
puts "Patching: #{filename}"
|
36
|
+
File.open(filename, "w") do |f|
|
37
|
+
f.write new_content
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -30,6 +30,14 @@ class RightRailsGenerator < Rails::Generator::Base
|
|
30
30
|
# creating the iframed uploads layout
|
31
31
|
m.directory "app/views/layouts"
|
32
32
|
m.file "/../generators/right_rails/templates/iframed.html.erb", "app/views/layouts/iframed.html.erb"
|
33
|
+
|
34
|
+
# copying the images in place
|
35
|
+
m.directory "public/images/rightjs-ui"
|
36
|
+
Dir.open("#{File.dirname(__FILE__)}/../../images").each do |filename|
|
37
|
+
unless ['.', '..'].include?(filename)
|
38
|
+
m.file "/../images/#{filename}", "public/images/rightjs-ui/#{filename}"
|
39
|
+
end
|
40
|
+
end
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
Binary file
|
Binary file
|
@@ -6,7 +6,6 @@
|
|
6
6
|
* @copyright (C) 2009-2010 Nikolay V. Nemshilov
|
7
7
|
*/
|
8
8
|
if (!RightJS) { throw "Gimme RightJS. Please." };
|
9
|
-
|
10
9
|
/**
|
11
10
|
* The RightJS UI Autocompleter unit base class
|
12
11
|
*
|
@@ -316,6 +315,4 @@ document.on({
|
|
316
315
|
Autocompleter.find(event);
|
317
316
|
}
|
318
317
|
}
|
319
|
-
});
|
320
|
-
|
321
|
-
document.write("<style type=\"text/css\">div.right-autocompleter,div.autocompleter,div.autocompleter ul,div.autocompleter ul li,div.autocompleter-spinner,div.autocompleter-spinner div{border:none;background:none;margin:0;padding:0;list-style:none;font-weight:normal}div.right-autocompleter{position:absolute;display:inline}div.autocompleter{display:none;position:absolute;z-index:9999999;background:white;-moz-box-shadow:#BBB .2em .2em .4em;-webkit-box-shadow:#BBB .2em .2em .4em;overflow:hidden}div.autocompleter ul{*border-bottom:1px solid #CCC}div.autocompleter ul li{padding:.2em .4em;border:1px solid #CCC;border-top:none;border-bottom:none;cursor:pointer}div.autocompleter ul li:first-child{border-top:1px solid #CCC}div.autocompleter ul li:last-child{border-bottom:1px solid #CCC;*border-bottom:none}div.autocompleter ul li.current{background:#DDD}div.autocompleter-spinner{position:absolute;z-index:100000000;text-align:center;font-size:140%;font-family:Georgia;background:#DDD;color:#666;display:none;width:1em}div.autocompleter-spinner div.dot-1{margin-left:-4px}div.autocompleter-spinner div.dot-2{}div.autocompleter-spinner div.dot-3{margin-left:4px}</style>");
|
318
|
+
});document.write("<style type=\"text/css\">div.right-autocompleter,div.autocompleter,div.autocompleter ul,div.autocompleter ul li,div.autocompleter-spinner,div.autocompleter-spinner div{border:none;background:none;margin:0;padding:0;list-style:none;font-weight:normal}div.right-autocompleter{position:absolute;display:inline}div.autocompleter{display:none;position:absolute;z-index:9999999;background:white;-moz-box-shadow:#BBB .2em .2em .4em;-webkit-box-shadow:#BBB .2em .2em .4em;overflow:hidden}div.autocompleter ul{*border-bottom:1px solid #CCC}div.autocompleter ul li{padding:.2em .4em;border:1px solid #CCC;border-top:none;border-bottom:none;cursor:pointer}div.autocompleter ul li:first-child{border-top:1px solid #CCC}div.autocompleter ul li:last-child{border-bottom:1px solid #CCC;*border-bottom:none}div.autocompleter ul li.current{background:#DDD}div.autocompleter-spinner{position:absolute;z-index:100000000;text-align:center;font-size:140%;font-family:Georgia;background:#DDD;color:#666;display:none;width:1em}div.autocompleter-spinner div.dot-1{margin-left:-4px}div.autocompleter-spinner div.dot-2{}div.autocompleter-spinner div.dot-3{margin-left:4px}</style>");
|
@@ -6,7 +6,6 @@
|
|
6
6
|
* @copyright (C) 2009-2010 Nikolay V. Nemshilov
|
7
7
|
*/
|
8
8
|
if (!RightJS) { throw "Gimme RightJS. Please." };
|
9
|
-
|
10
9
|
/**
|
11
10
|
* The calendar widget for RightJS
|
12
11
|
*
|
@@ -944,6 +943,4 @@ Calendar.include({
|
|
944
943
|
})();
|
945
944
|
|
946
945
|
|
947
|
-
|
948
|
-
|
949
946
|
document.write("<style type=\"text/css\">div.right-calendar,div.right-calendar table,div.right-calendar table tr,div.right-calendar table th,div.right-calendar table td,div.right-calendar table tbody,div.right-calendar table thead{background:none;border:none;width:auto;height:auto;margin:0;padding:0}*.right-ui-button{display:inline-block;*display:inline;*zoom:1;height:1em;line-height:1em;padding:.2em .5em;text-align:center;border:1px solid #CCC;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em;cursor:pointer;color:#555;background-color:#FFF}*.right-ui-button:hover{color:#222;border-color:#999;background-color:#CCC}*.right-ui-button-disabled,*.right-ui-button-disabled:hover{color:#888;background:#EEE;border-color:#CCC;cursor:default}*.right-ui-buttons{margin-top:.5em}div.right-calendar{position:absolute;height:auto;border:1px solid #BBB;position:relative;padding:.5em;border-radius:.3em;-moz-border-radius:.3em;-webkit-border-radius:.3em;cursor:default;background-color:#EEE;-moz-box-shadow:.2em .4em .8em #666;-webkit-box-shadow:.2em .4em .8em #666}div.right-calendar-inline{position:relative;display:inline-block;vertical-align:top;*display:inline;*zoom:1;-moz-box-shadow:none;-webkit-box-shadow:none}div.right-calendar-prev-button,div.right-calendar-next-button,div.right-calendar-prev-year-button,div.right-calendar-next-year-button{position:absolute;float:left;width:1em;padding:.15em .4em}div.right-calendar-next-button{right:.5em}div.right-calendar-prev-year-button{left:2.55em}div.right-calendar-next-year-button{right:2.55em}div.right-calendar-month-caption{text-align:center;height:1.2em;line-height:1.2em}table.right-calendar-greed{border-spacing:0px}table.right-calendar-greed td{vertical-align:top;padding-right:.4em}table.right-calendar-greed>tbody>td:last-child{padding:0}div.right-calendar-month table{margin-top:.2em;border-spacing:1px;border-collapse:separate}div.right-calendar-month table th{color:#777;text-align:center}div.right-calendar-month table td{text-align:right;padding:.1em .3em;background-color:#FFF;border:1px solid #CCC;cursor:pointer;color:#555;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em}div.right-calendar-month table td:hover{background-color:#CCC;border-color:#AAA;color:#000}div.right-calendar-month table td.right-calendar-day-blank{background:transparent;cursor:default;border:none}div.right-calendar-month table td.right-calendar-day-selected{background-color:#BBB;border-color:#AAA;color:#222;font-weight:bold;padding:.1em .2em}div.right-calendar-month table td.right-calendar-day-disabled{color:#888;background:#EEE;border-color:#CCC;cursor:default}div.right-calendar-time{border-top:1px solid #ccc;margin-top:.3em;padding-top:.5em;text-align:center}div.right-calendar-time select{margin:0 .4em}div.right-calendar-buttons div.right-ui-button{width:3.2em}div.right-calendar-done-button{position:absolute;right:.5em}</style>");
|
@@ -0,0 +1,635 @@
|
|
1
|
+
/**
|
2
|
+
* RightJS UI Colorpicker widget
|
3
|
+
*
|
4
|
+
* See http://rightjs.org/ui/colorpicker
|
5
|
+
*
|
6
|
+
* Copyright (C) 2010 Nikolay Nemshilov
|
7
|
+
*/
|
8
|
+
if (!self.RightJS) throw "Gimme RightJS";
|
9
|
+
/**
|
10
|
+
* The basic file for Colorpicker
|
11
|
+
*
|
12
|
+
* Copyright (C) 2010 Nikolay Nemshilov
|
13
|
+
*/
|
14
|
+
var Colorpicker = new Class(Observer, {
|
15
|
+
extend: {
|
16
|
+
EVENTS: $w('change show hide done'),
|
17
|
+
|
18
|
+
Options: {
|
19
|
+
format: 'hex', // hex or rgb
|
20
|
+
|
21
|
+
update: null, // an element to update with the color text
|
22
|
+
updateBg: null, // an element to update it's background color
|
23
|
+
|
24
|
+
fxName: 'fade', // popup displaying fx
|
25
|
+
fxDuration: 'short',
|
26
|
+
|
27
|
+
cssRule: '*[rel^=colorpicker]'
|
28
|
+
},
|
29
|
+
|
30
|
+
i18n: {
|
31
|
+
Done: 'Done'
|
32
|
+
},
|
33
|
+
|
34
|
+
// builds or finds a colorpicker for the target element
|
35
|
+
find: function(element) {
|
36
|
+
var uid = $uid(element), instances = Colorpicker.instances;
|
37
|
+
|
38
|
+
if (!instances[uid]) {
|
39
|
+
var pick = instances[uid] = new Colorpicker(eval('('+ element.get('data-colorpicker-options') +')'));
|
40
|
+
|
41
|
+
if (element.tagName == 'INPUT')
|
42
|
+
pick.assignTo(element);
|
43
|
+
else {
|
44
|
+
var attr = Colorpicker.Options.cssRule.split('[').last().split('^=').first(),
|
45
|
+
match = /\[(.+?)\]/.exec(element.get(attr)), input;
|
46
|
+
|
47
|
+
if (match && (input = $(match[1]))) {
|
48
|
+
pick.assignTo(input, element);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
return instances[uid];
|
54
|
+
},
|
55
|
+
|
56
|
+
instances: []
|
57
|
+
},
|
58
|
+
|
59
|
+
/**
|
60
|
+
* basic constructor
|
61
|
+
*
|
62
|
+
* @param Object options
|
63
|
+
*/
|
64
|
+
initialize: function(options) {
|
65
|
+
this.$super(options);
|
66
|
+
this.init();
|
67
|
+
},
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Sets the color of the widget
|
71
|
+
*
|
72
|
+
* @param mixed value, Array or HEX or RGB value
|
73
|
+
* @return Colorpicker this
|
74
|
+
*/
|
75
|
+
setValue: function(value) {
|
76
|
+
var color = isArray(value) ? value : this.toColor(value);
|
77
|
+
if (color && color.length == 3) {
|
78
|
+
|
79
|
+
// normalizing the data
|
80
|
+
color = color.map(function(value) {
|
81
|
+
return this.bound((''+value).toInt(), 0, 255);
|
82
|
+
}, this);
|
83
|
+
|
84
|
+
this.color = color;
|
85
|
+
this.color2tint().update();
|
86
|
+
}
|
87
|
+
return this;
|
88
|
+
},
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Returns the value of the widget
|
92
|
+
* formatted according to the options
|
93
|
+
*
|
94
|
+
* @param Boolean if you need a clean RGB values array
|
95
|
+
* @return mixed value
|
96
|
+
*/
|
97
|
+
getValue: function(array) {
|
98
|
+
return array ? this.color : this[this.options.format === 'rgb' ? 'toRgb' : 'toHex']();
|
99
|
+
},
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Inlines the widget into the given element
|
103
|
+
*
|
104
|
+
* @param Element reference
|
105
|
+
* @param String optional position
|
106
|
+
* @return Colorpicker this
|
107
|
+
*/
|
108
|
+
insertTo: function(element, position) {
|
109
|
+
this.element
|
110
|
+
.addClass('right-colorpicker-inline')
|
111
|
+
.insertTo(element, position);
|
112
|
+
|
113
|
+
return this;
|
114
|
+
},
|
115
|
+
|
116
|
+
// protected
|
117
|
+
|
118
|
+
// initializes the widget
|
119
|
+
init: function() {
|
120
|
+
this.build();
|
121
|
+
|
122
|
+
// attaching the mouse-events to the fields
|
123
|
+
[this.field, this.colors].each(function(element) {
|
124
|
+
element.onMousedown(this.startTrack.bind(this));
|
125
|
+
}, this);
|
126
|
+
|
127
|
+
// tracking the changes on the input fields
|
128
|
+
[this.display, this.rDisplay, this.gDisplay, this.bDisplay].each('on', {
|
129
|
+
keyup: this.recalc.bind(this),
|
130
|
+
blur: this.update.bind(this),
|
131
|
+
focus: this.cancelTimer.bind(this)
|
132
|
+
});
|
133
|
+
|
134
|
+
// attaching the done button
|
135
|
+
this.button.onClick(this.fire.bind(this, 'done'));
|
136
|
+
|
137
|
+
// preventing the general body clicks
|
138
|
+
this.element.onMousedown(function(event) {
|
139
|
+
if (event.target.tagName !== 'INPUT') {
|
140
|
+
event.stop();
|
141
|
+
this.cancelTimer();
|
142
|
+
}
|
143
|
+
}.bind(this));
|
144
|
+
|
145
|
+
// attaching the picker own events
|
146
|
+
this
|
147
|
+
.onDone('hide')
|
148
|
+
.onChange(function(color) {
|
149
|
+
if (this.target) {
|
150
|
+
this.target[this.target.tagName == 'INPUT' ? 'value' : 'innerHTML'] =
|
151
|
+
this[this.options.format == 'rgb' ? 'toRgb' : 'toHex']();
|
152
|
+
}
|
153
|
+
}.bind(this));
|
154
|
+
|
155
|
+
// hooking up the elements to update
|
156
|
+
if (this.options.update) this.assignTo(this.options.update);
|
157
|
+
if (this.options.updateBg) this.updateBg(this.options.updateBg);
|
158
|
+
|
159
|
+
// setting up the initial value
|
160
|
+
// NOTE: to speed the things up a bit we use params
|
161
|
+
// for tint, saturation and brightness and
|
162
|
+
// normal RGB value to keep the current color
|
163
|
+
this.tint = [1, 0, 0];
|
164
|
+
this.satur = 0;
|
165
|
+
this.bright = 1;
|
166
|
+
this.color = [255, 255, 255];
|
167
|
+
|
168
|
+
this.recalc().update();
|
169
|
+
},
|
170
|
+
|
171
|
+
// builds the widget
|
172
|
+
build: function() {
|
173
|
+
var base = this.element = $E('div', {'class': 'right-colorpicker right-ui-panel'});
|
174
|
+
|
175
|
+
// the field block
|
176
|
+
this.field = $E('div', {'class': 'field'}).insertTo(base);
|
177
|
+
this.fieldPointer = $E('div', {'class': 'field-pointer'}).insertTo(this.field);
|
178
|
+
|
179
|
+
// the tint block
|
180
|
+
this.colors = $E('div', {'class': 'colors'}).insertTo(base);
|
181
|
+
this.colorsPointer = $E('div', {'class': 'colors-pointer'}).insertTo(this.colors);
|
182
|
+
|
183
|
+
// the controls block
|
184
|
+
$E('div', {'class': 'controls'}).insert([
|
185
|
+
this.preview = $E('div', {'class': 'preview', 'html': ' '}).insertTo(base),
|
186
|
+
this.display = $E('input', {'type': 'text', 'class': 'display', maxlength: 7}).insertTo(base),
|
187
|
+
$E('div', {'class': 'rgb-display'}).insert([
|
188
|
+
$E('div').insert([$E('label', {html: 'R:'}), this.rDisplay = $E('input', {maxlength: 3, cIndex: 0})]),
|
189
|
+
$E('div').insert([$E('label', {html: 'G:'}), this.gDisplay = $E('input', {maxlength: 3, cIndex: 1})]),
|
190
|
+
$E('div').insert([$E('label', {html: 'B:'}), this.bDisplay = $E('input', {maxlength: 3, cIndex: 2})])
|
191
|
+
]),
|
192
|
+
this.button = $E('input', {'type': 'button', 'class': 'right-ui-button', value: Colorpicker.i18n.Done})
|
193
|
+
]).insertTo(base);
|
194
|
+
},
|
195
|
+
|
196
|
+
// updates the preview and pointer positions
|
197
|
+
update: function() {
|
198
|
+
this.field.style.backgroundColor = 'rgb('+ this.tint.map(function(c) { return (c*255).round(); }) +')';
|
199
|
+
this.preview.style.backgroundColor = this.display.value = this.toHex();
|
200
|
+
|
201
|
+
// updating the input fields
|
202
|
+
var color = this.color;
|
203
|
+
this.rDisplay.value = color[0];
|
204
|
+
this.gDisplay.value = color[1];
|
205
|
+
this.bDisplay.value = color[2];
|
206
|
+
|
207
|
+
// adjusting the field pointer position
|
208
|
+
var pointer = this.fieldPointer.style,
|
209
|
+
field = this.field.sizes(),
|
210
|
+
top = field.y - this.bright * field.y - 2,
|
211
|
+
left = this.satur * field.x - 2;
|
212
|
+
|
213
|
+
pointer.top = this.bound(top, 0, field.y - 5) + 'px';
|
214
|
+
pointer.left = this.bound(left, 0, field.x - 5) + 'px';
|
215
|
+
|
216
|
+
// adjusting the ting pointer position
|
217
|
+
var field = this.colors.sizes(), tint = this.tint, position;
|
218
|
+
|
219
|
+
if (tint[1] == 0) { // the red-blue section
|
220
|
+
position = tint[0] == 1 ? tint[2] : (2 - tint[0]);
|
221
|
+
} else if (tint[0] == 0) { // the blue-green section
|
222
|
+
position = 2 + (tint[2] == 1 ? tint[1] : (2 - tint[2]));
|
223
|
+
} else { // the green-red section
|
224
|
+
position = 4 + (tint[1] == 1 ? tint[0] : (2 - tint[1]));
|
225
|
+
}
|
226
|
+
|
227
|
+
position = position / 6 * field.y;
|
228
|
+
|
229
|
+
this.colorsPointer.style.top = this.bound(position, 0, field.y - 4) + 'px';
|
230
|
+
|
231
|
+
// tracking the color change events
|
232
|
+
if (this.prevColor !== ''+this.color) {
|
233
|
+
this.fire('change', this.color);
|
234
|
+
this.prevColor = ''+ this.color;
|
235
|
+
}
|
236
|
+
|
237
|
+
return this;
|
238
|
+
},
|
239
|
+
|
240
|
+
// recalculates the state after the input field changes
|
241
|
+
recalc: function(event) {
|
242
|
+
if (event) {
|
243
|
+
var field = event.target, value = field.value, color = this.color.clone(), changed=false;
|
244
|
+
|
245
|
+
if (field == this.display && /#\w{6}/.test(value)) {
|
246
|
+
// using the hex values
|
247
|
+
changed = color = this.toColor(value);
|
248
|
+
} else if (/^\d+$/.test(value)) {
|
249
|
+
// using the rgb values
|
250
|
+
color[field.cIndex] = value;
|
251
|
+
changed = true;
|
252
|
+
}
|
253
|
+
|
254
|
+
if (changed) this.setValue(color);
|
255
|
+
|
256
|
+
} else {
|
257
|
+
this.tint2color();
|
258
|
+
}
|
259
|
+
|
260
|
+
return this;
|
261
|
+
},
|
262
|
+
|
263
|
+
// starts the mousemoves tracking
|
264
|
+
startTrack: function(event) {
|
265
|
+
event.stop();
|
266
|
+
this.stopTrack();
|
267
|
+
this.cancelTimer();
|
268
|
+
Colorpicker.tracking = this;
|
269
|
+
event.target.tracking = true;
|
270
|
+
this.trackMove(event); // jumping over there
|
271
|
+
},
|
272
|
+
|
273
|
+
// stops tracking the mousemoves
|
274
|
+
stopTrack: function() {
|
275
|
+
Colorpicker.tracking = false;
|
276
|
+
this.field.tracking = false;
|
277
|
+
this.colors.tracking = false;
|
278
|
+
},
|
279
|
+
|
280
|
+
// tracks the cursor moves over the fields
|
281
|
+
trackMove: function(event) {
|
282
|
+
var field, pos = event.position(), top, left;
|
283
|
+
|
284
|
+
if (this.field.tracking) {
|
285
|
+
field = this.field.dimensions();
|
286
|
+
} else if (this.colors.tracking) {
|
287
|
+
field = this.colors.dimensions();
|
288
|
+
}
|
289
|
+
|
290
|
+
if (field) {
|
291
|
+
top = this.bound(pos.y - field.top, 0, field.height);
|
292
|
+
left = this.bound(pos.x - field.left, 0, field.width);
|
293
|
+
|
294
|
+
if (this.field.tracking) {
|
295
|
+
this.satur = left / field.width;
|
296
|
+
this.bright = 1 - top / field.height;
|
297
|
+
|
298
|
+
} else if (this.colors.tracking) {
|
299
|
+
// preventing it from jumping to the top
|
300
|
+
if (top == field.height) top = field.height - 0.1;
|
301
|
+
|
302
|
+
var step = field.height / 6,
|
303
|
+
tint = this.tint = [0, 0, 0],
|
304
|
+
stright = top % step / step,
|
305
|
+
reverse = 1 - stright;
|
306
|
+
|
307
|
+
if (top < step) {
|
308
|
+
tint[0] = 1;
|
309
|
+
tint[2] = stright;
|
310
|
+
} else if (top < step * 2) {
|
311
|
+
tint[0] = reverse;
|
312
|
+
tint[2] = 1;
|
313
|
+
} else if (top < step * 3) {
|
314
|
+
tint[2] = 1;
|
315
|
+
tint[1] = stright;
|
316
|
+
} else if (top < step * 4) {
|
317
|
+
tint[2] = reverse;
|
318
|
+
tint[1] = 1;
|
319
|
+
} else if (top < step * 5) {
|
320
|
+
tint[1] = 1;
|
321
|
+
tint[0] = stright;
|
322
|
+
} else {
|
323
|
+
tint[1] = reverse;
|
324
|
+
tint[0] = 1;
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
this.recalc().update();
|
329
|
+
}
|
330
|
+
}
|
331
|
+
});
|
332
|
+
|
333
|
+
/**
|
334
|
+
* This module contains various caluculations logic for
|
335
|
+
* the Colorpicker widget
|
336
|
+
*
|
337
|
+
* Copyright (C) 2010 Nikolay Nemshilov
|
338
|
+
*/
|
339
|
+
Colorpicker.include({
|
340
|
+
/**
|
341
|
+
* Converts the color to a RGB string value
|
342
|
+
*
|
343
|
+
* @param Array optional color
|
344
|
+
* @return String RGB value
|
345
|
+
*/
|
346
|
+
toRgb: function(color) {
|
347
|
+
return 'rgb('+ this.color.join(',') +')';
|
348
|
+
},
|
349
|
+
|
350
|
+
/**
|
351
|
+
* Converts the color to a HEX string value
|
352
|
+
*
|
353
|
+
* @param Array optional color
|
354
|
+
* @return String HEX value
|
355
|
+
*/
|
356
|
+
toHex: function(color) {
|
357
|
+
return '#'+ this.color.map(function(c) { return (c < 16 ? '0' : '') + c.toString(16); }).join('');
|
358
|
+
},
|
359
|
+
|
360
|
+
/**
|
361
|
+
* Converts a string value into an Array of color
|
362
|
+
*
|
363
|
+
* @param String value
|
364
|
+
* @return Array of color or null
|
365
|
+
*/
|
366
|
+
toColor: function(in_value) {
|
367
|
+
var value = in_value.toLowerCase(), match;
|
368
|
+
|
369
|
+
if (match = /rgb\((\d+),(\d+),(\d+)\)/.exec(value)) {
|
370
|
+
return [match[1], match[2], match[3]].map('toInt');
|
371
|
+
|
372
|
+
} else if (/#[\da-f]+/.test(value)) {
|
373
|
+
// converting the shortified hex in to the full-length version
|
374
|
+
if (match = /^#([\da-f])([\da-f])([\da-f])$/.exec(value))
|
375
|
+
value = '#'+match[1]+match[1]+match[2]+match[2]+match[3]+match[3];
|
376
|
+
|
377
|
+
if (match = /#([\da-f]{2})([\da-f]{2})([\da-f]{2})/.exec(value)) {
|
378
|
+
return [match[1], match[2], match[3]].map('toInt', 16);
|
379
|
+
}
|
380
|
+
}
|
381
|
+
},
|
382
|
+
|
383
|
+
/**
|
384
|
+
* converts color into the tint, saturation and brightness values
|
385
|
+
*
|
386
|
+
* @return Colorpicker this
|
387
|
+
*/
|
388
|
+
color2tint: function() {
|
389
|
+
var color = this.color.clone().sort(function(a,b) { return a-b; }),
|
390
|
+
min = color[0], max = color[2];
|
391
|
+
|
392
|
+
this.bright = max / 255;
|
393
|
+
this.satur = 1 - min / (max || 1);
|
394
|
+
|
395
|
+
this.tint.each(function(value, i) {
|
396
|
+
return this.tint[i] = ((!min && !max) || min == max) ? i == 0 ? 1 : 0 :
|
397
|
+
(this.color[i] - min) / (max - min);
|
398
|
+
}, this);
|
399
|
+
|
400
|
+
return this;
|
401
|
+
},
|
402
|
+
|
403
|
+
/**
|
404
|
+
* Converts tint, saturation and brightness into the actual RGB color
|
405
|
+
*
|
406
|
+
* @return Colorpicker this
|
407
|
+
*/
|
408
|
+
tint2color: function() {
|
409
|
+
var tint = this.tint, color = this.color;
|
410
|
+
|
411
|
+
for (var i=0; i < 3; i++) {
|
412
|
+
color[i] = 1 + this.satur * (tint[i] - 1);
|
413
|
+
color[i] = (255 * color[i] * this.bright).round();
|
414
|
+
}
|
415
|
+
|
416
|
+
return this;
|
417
|
+
},
|
418
|
+
|
419
|
+
/**
|
420
|
+
* bounds the value to the given limits
|
421
|
+
*
|
422
|
+
* @param Number value
|
423
|
+
* @param Number min value
|
424
|
+
* @param Number max value
|
425
|
+
* @return Number the value in bounds
|
426
|
+
*/
|
427
|
+
bound: function(in_value, min, max) {
|
428
|
+
var value = in_value;
|
429
|
+
|
430
|
+
if (min < max) {
|
431
|
+
value = value < min ? min : value > max ? max : value;
|
432
|
+
} else {
|
433
|
+
if (value > max) value = max;
|
434
|
+
if (value < min) value = min;
|
435
|
+
}
|
436
|
+
|
437
|
+
return value;
|
438
|
+
}
|
439
|
+
});
|
440
|
+
|
441
|
+
/**
|
442
|
+
* This module handles the colorpicker assignments
|
443
|
+
* to input fields
|
444
|
+
*
|
445
|
+
* Copyright (C) 2010 Nikolay Nemshilov
|
446
|
+
*/
|
447
|
+
Colorpicker.include({
|
448
|
+
/**
|
449
|
+
* Hides the pop up element
|
450
|
+
*
|
451
|
+
* @return Colorpicker this
|
452
|
+
*/
|
453
|
+
hide: function() {
|
454
|
+
if (!this.element.hasClass('right-colorpicker-inline')) {
|
455
|
+
this.target = null;
|
456
|
+
Colorpicker.current = null;
|
457
|
+
this.element.hide(this.options.fxName, {
|
458
|
+
duration: this.options.fxDuration
|
459
|
+
});
|
460
|
+
|
461
|
+
this.fire('hide');
|
462
|
+
}
|
463
|
+
|
464
|
+
return this;
|
465
|
+
},
|
466
|
+
|
467
|
+
/**
|
468
|
+
* Shows the element as a popup
|
469
|
+
*
|
470
|
+
* @param Element where to show the popup
|
471
|
+
* @return Colorpicker this
|
472
|
+
*/
|
473
|
+
show: function(target) {
|
474
|
+
// moving into the target position
|
475
|
+
if (target) {
|
476
|
+
var element = $(target).dimensions(), style = this.element.style;
|
477
|
+
|
478
|
+
if (element) {
|
479
|
+
style.left = element.left + 'px';
|
480
|
+
style.top = element.top + element.height + 'px';
|
481
|
+
|
482
|
+
this.target = $(target);
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
486
|
+
// hide the others
|
487
|
+
if (Colorpicker.current && Colorpicker.current !== this) {
|
488
|
+
Colorpicker.current.element.hide();
|
489
|
+
}
|
490
|
+
|
491
|
+
this.element.insertTo(document.body);
|
492
|
+
|
493
|
+
if (!this.element.visible()) {
|
494
|
+
this.element.show(this.options.fxName, {
|
495
|
+
duration: this.options.fxDuration
|
496
|
+
});
|
497
|
+
|
498
|
+
this.fire('show');
|
499
|
+
}
|
500
|
+
|
501
|
+
if (this.target) {
|
502
|
+
this.setValue(this.target.value);
|
503
|
+
}
|
504
|
+
|
505
|
+
return Colorpicker.current = this;
|
506
|
+
},
|
507
|
+
|
508
|
+
/**
|
509
|
+
* Toggles the visibility status
|
510
|
+
*
|
511
|
+
* @param Element target
|
512
|
+
* @return Colorpicker this
|
513
|
+
*/
|
514
|
+
toggle: function(target) {
|
515
|
+
return this[this.element.visible() ? 'hide' : 'show'](target);
|
516
|
+
},
|
517
|
+
|
518
|
+
/**
|
519
|
+
* Assigns the colorpicer to work in pair with an input of a content element
|
520
|
+
*
|
521
|
+
* @param Element reference
|
522
|
+
* @param Element optional trigger element
|
523
|
+
* @return Colorpicker this
|
524
|
+
*/
|
525
|
+
assignTo: function(input, trigger) {
|
526
|
+
var input = $(input), trigger = $(trigger);
|
527
|
+
|
528
|
+
if (trigger) {
|
529
|
+
trigger.onClick(function(e) {
|
530
|
+
e.stop();
|
531
|
+
this.toggle(input.focus());
|
532
|
+
}.bind(this));
|
533
|
+
} else {
|
534
|
+
input.onFocus(this.show.bind(this, input));
|
535
|
+
}
|
536
|
+
|
537
|
+
input.on({
|
538
|
+
blur: function() {
|
539
|
+
this.timer = (function() {
|
540
|
+
this.hide();
|
541
|
+
}).bind(this).delay(100);
|
542
|
+
}.bind(this),
|
543
|
+
|
544
|
+
keyUp: function() {
|
545
|
+
this.setValue(input.value);
|
546
|
+
}.bind(this)
|
547
|
+
});
|
548
|
+
|
549
|
+
this.element.hide();
|
550
|
+
|
551
|
+
return this;
|
552
|
+
},
|
553
|
+
|
554
|
+
/**
|
555
|
+
* Assigns the colorpicer to automatically update
|
556
|
+
* given element's background on changes
|
557
|
+
*
|
558
|
+
* @param mixed element reference
|
559
|
+
* @return Colorpicker this
|
560
|
+
*/
|
561
|
+
updateBg: function(element_ref) {
|
562
|
+
var element = $(element_ref);
|
563
|
+
if (element) {
|
564
|
+
this.onChange(function(color) {
|
565
|
+
element.style.backgroundColor = this.toRgb();
|
566
|
+
}.bind(this));
|
567
|
+
}
|
568
|
+
return this;
|
569
|
+
},
|
570
|
+
|
571
|
+
// protected
|
572
|
+
|
573
|
+
cancelTimer: function() {
|
574
|
+
(function() { // IE has a lack of sync in here
|
575
|
+
if (this.timer) {
|
576
|
+
this.timer.cancel();
|
577
|
+
this.timer = null;
|
578
|
+
}
|
579
|
+
}).bind(this).delay(10);
|
580
|
+
}
|
581
|
+
});
|
582
|
+
|
583
|
+
/**
|
584
|
+
* The document level hooks for colorpicker
|
585
|
+
*
|
586
|
+
* Copyright (C) 2010 Nikolay Nemshilov
|
587
|
+
*/
|
588
|
+
document.on({
|
589
|
+
mouseup: function() {
|
590
|
+
if (Colorpicker.tracking) {
|
591
|
+
Colorpicker.tracking.stopTrack();
|
592
|
+
}
|
593
|
+
},
|
594
|
+
|
595
|
+
mousemove: function(event) {
|
596
|
+
if (Colorpicker.tracking) {
|
597
|
+
Colorpicker.tracking.trackMove(event);
|
598
|
+
}
|
599
|
+
},
|
600
|
+
|
601
|
+
mousedown: function(event) {
|
602
|
+
var picker = Colorpicker.current, target = event.target;
|
603
|
+
|
604
|
+
if (picker && target != picker.target && ![target].concat(target.parents()).include(picker.element)) {
|
605
|
+
picker.hide();
|
606
|
+
}
|
607
|
+
}
|
608
|
+
});
|
609
|
+
|
610
|
+
window.on('blur', function() {
|
611
|
+
if (Colorpicker.tracking) {
|
612
|
+
Colorpicker.tracking.stopTrack();
|
613
|
+
}
|
614
|
+
});
|
615
|
+
|
616
|
+
// colorpickers autodiscovery feature
|
617
|
+
Colorpicker.Options.cssRule.on({
|
618
|
+
focus: function(event) {
|
619
|
+
if (this.tagName == 'INPUT') {
|
620
|
+
Colorpicker.find(this).show(this);
|
621
|
+
}
|
622
|
+
},
|
623
|
+
|
624
|
+
click: function(event) {
|
625
|
+
var attr = Colorpicker.Options.cssRule.split('[').last().split('^=').first(),
|
626
|
+
match = /\[(.+?)\]/.exec(this.get(attr)), input;
|
627
|
+
|
628
|
+
if (match && (input = $(match[1]))) {
|
629
|
+
event.stop();
|
630
|
+
|
631
|
+
Colorpicker.find(this).show(input);
|
632
|
+
}
|
633
|
+
}
|
634
|
+
});
|
635
|
+
document.write("<style type=\"text/css\">div.right-colorpicker,div.right-colorpicker*{border:none;background:none;width:auto;height:auto;position:static;float:none;top:none;left:none;right:none;bottom:none;margin:0;padding:0;display:block;font-weight:normal;vertical-align:center}div.right-colorpicker{position:absolute;padding:.6em;background:#EEE;border:1px solid #CCC;-moz-border-radius:.2em;-webkit-border-radius:.2em;-moz-box-shadow:#AAA .3em .3em .4em;-webkit-box-shadow:#AAA .3em .3em .4em;z-index:9999}div.right-colorpicker div.field,div.right-colorpicker div.field-pointer,div.right-colorpicker div.colors,div.right-colorpicker div.colors-pointer{background:url(/images/rightjs-ui/colorpicker.png) no-repeat 0 0}div.right-colorpicker div.field,div.right-colorpicker div.colors,div.right-colorpicker div.controls{display:inline-block;*display:inline;*zoom:1;position:relative;vertical-align:top;height:150px}div.right-colorpicker div.field-pointer,div.right-colorpicker div.colors-pointer{position:absolute;top:0px;left:0;width:9px;height:9px}div.right-colorpicker input.display,div.right-colorpicker div.preview,div.right-colorpicker div.rgb-display,div.right-colorpicker input.right-ui-button{font-size:100%;display:block;width:auto;padding:0 .2em}div.right-colorpicker input.display,div.right-colorpicker div.preview,div.right-colorpicker div.rgb-display input,div.right-colorpicker input.right-ui-button{border:1px solid #AAA;-moz-border-radius:.2em;-webkit-border-radius:.2em}div.right-colorpicker div.field{width:150px;background-color:red;cursor:crosshair;margin-right:1.2em}div.right-colorpicker div.field-pointer{background-position:-170px 0;margin-left:-2px;margin-top:-2px}div.right-colorpicker div.colors{width:16px;background-position:-150px 0;border-color:#EEE;cursor:pointer;margin-right:.6em}div.right-colorpicker div.colors-pointer{cursor:default;background-position:-170px -20px;margin-left:-8px;margin-top:-3px}div.right-colorpicker div.controls{width:5em}div.right-colorpicker div.preview{height:2em;background:white;border-color:#BBB}div.right-colorpicker input.display{margin-top:.5em;background:#FFF;width:4.5em}div.right-colorpicker div.rgb-display{padding:0;text-align:right;margin-top:.5em}div.right-colorpicker div.rgb-display label{display:inline}div.right-colorpicker div.rgb-display input{vertical-align:top;font-size:100%;width:2em;text-align:right;margin-left:.2em;padding:0 .2em;background:#FFF;margin-bottom:1px;display:inline}div.right-colorpicker input.right-ui-button{cursor:pointer;position:absolute;bottom:0;width:5em;background:#CCC}div.right-colorpicker-inline{display:inline-block;*display:inline;*zoom:1;position:relative;-moz-box-shadow:none;-webkit-box-shadow:none;z-index:auto}</style>");
|