kenny_dialoggins 1.0.0 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.specification CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kenny_dialoggins
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
+ - 1
7
8
  - 0
8
9
  - 2
9
- - 3
10
- version: 0.2.3
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Coroutine
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-07-29 00:00:00 -05:00
20
+ date: 2010-10-19 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
data/README.rdoc CHANGED
@@ -32,16 +32,27 @@ What's that, you want more details? You got it, buddy.
32
32
  <tt>render_dialog</tt> always needs a unique id for its first argument. After that, it will
33
33
  take the same options as <tt>ActionController::Base#render</tt>. It'll also take a few more, namely:
34
34
 
35
+ * <tt>:class</tt> - a css class name that will be appended to the outermost div to facilitate multiple styles
35
36
  * <tt>:before_show</tt> - a Javascript function that will be invoked before the dialog is shown
36
37
  * <tt>:after_show</tt> - a Javascript function that will be invoked after the dialog has become visible
37
38
  * <tt>:before_hide</tt> - a Javascript function that will be invoked before the dialog is hidden
38
39
  * <tt>:after_hide</tt> - a Javascript function that will be invoked after the dialog has been hidden
40
+ * <tt>&block</tt> - HTML markup that will be automatically converted to render's inline option
39
41
 
40
42
  Here's an example using the <tt>before_show</tt> option:
41
43
 
42
44
  # Create the dialog with a callback
43
45
  <%= render_dialog :footloose_dialog, :partial => "footloose", :before_show => "function() { alert('Everybody get footloose!'); }" %>
44
-
46
+
47
+ To invoke the dialog, use unobtrusive javascript to trap a click event and show the dialog.
48
+
49
+ // invoke the dialog
50
+ $("footloose_dialog_link").observe("click", function(evt) {
51
+ KennyDialoggins.Dialog.show("footloose_dialog");
52
+ });
53
+
54
+ Or, if you're using javascript helper functions, you can use the show/hide helpers to accomplish the same thing.
55
+
45
56
  # Invoke the dialog
46
57
  <%= link_to_function "Dance party!", show_dialog(:footloose_dialog) %>
47
58
 
@@ -56,6 +67,35 @@ Kenny Dialoggins
56
67
 
57
68
 
58
69
 
70
+ == Multiple Dialog Styles
71
+
72
+ If you need to style more than one kind of dialog, just use the <tt>:class</tt> option to append a css class name
73
+ on the outermost div. That'll give you a logical anchor around which you can restyle all the interior classes.
74
+
75
+ Please note that the blocking iframe is automatically given an additional class name equal to the outermost div's class
76
+ name plus the string "_frame".
77
+
78
+ By default, the top-level class assignments are "kenny_dialoggins_dialog" and "kenny_dialoggins_dialog_frame".
79
+
80
+ If you set the <tt>:class</tt> option to <tt>:error_dialog</tt>, the top-level class assignments will be
81
+ "kenny_dialoggins_dialog error_dialog" and "kenny_dialoggins_dialog_frame error_dialog_frame".
82
+
83
+
84
+
85
+ == IE6 Support
86
+
87
+ I'm not what you'd call a huge fan of IE6, so I don't provide a blocking
88
+ iframe for my dialogs by default. But I can. You just need to ask nicely.
89
+
90
+ At the top of the generated javascript file, just change the obviously-named property
91
+ hanging right off of the Kenny D namespace. Like this.
92
+
93
+ KennyDialoggins.SUPPORT_IE6_BULLSHIT = true;
94
+
95
+ That's it. I do the rest.
96
+
97
+
98
+
59
99
  == Helpful Links
60
100
 
61
101
  * <b>Repository:</b> http://github.com/coroutine/kenny_dialoggins
@@ -76,7 +116,22 @@ in the mix.
76
116
 
77
117
 
78
118
 
79
- == Installation & Generators
119
+ == Installation & Generators (Rails 3)
120
+
121
+ Install me from RubyGems.org by adding a gem dependency to your Gemfile. Bundler does
122
+ the rest.
123
+
124
+ gem "kenny_dialoggins"
125
+
126
+ $ bundle install
127
+
128
+ Then generate the required javascript file and the starter stylesheet.
129
+
130
+ $ rails g kenny_dialoggins
131
+
132
+
133
+
134
+ == Installation & Generators (Rails 2)
80
135
 
81
136
  Install me from RubyGems.org and add a gem dependency in the appropriate file.
82
137
 
@@ -86,23 +141,24 @@ Or install me as a plugin.
86
141
 
87
142
  $ script/plugin install git://github.com/coroutine/kenny_dialoggins.git
88
143
 
89
- Either way, then generate the stylesheet and javascript files I need.
144
+ Either way, then generate the required javascript file and the starter stylesheet.
90
145
 
91
146
  $ script/generate kenny_dialoggins
92
147
 
93
148
 
94
149
 
95
- == IE6 Support
96
-
97
- I'm not what you'd call a huge fan of IE6, so I don't provide a blocking
98
- iframe for my dialogs by default. But I can. You just need to ask nicely.
150
+ == Gemroll
99
151
 
100
- At the top of the generated javascript file, just change the obviously-named property
101
- hanging right off of the Kenny D namespace. Like this.
152
+ If you think I'm awesome, you should check out my soulmate
153
+ {Michael Hintbuble}[http://github.com/coroutine/michael_hintbuble].
102
154
 
103
- KennyDialoggins.SUPPORT_IE6_BULLSHIT = true;
155
+ Other gems by Coroutine include:
104
156
 
105
- That's it. I do the rest.
157
+ * {acts_as_current}[http://github.com/coroutine/acts_as_current]
158
+ * {acts_as_label}[http://github.com/coroutine/acts_as_label]
159
+ * {acts_as_list_with_sti_support}[http://github.com/coroutine/acts_as_list_with_sti_support]
160
+ * {delayed_form_observer}[http://github.com/coroutine/delayed_form_observer]
161
+ * {tiny_navigation}[http://github.com/coroutine/tiny_navigation]
106
162
 
107
163
 
108
164
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.3
@@ -1,20 +1,39 @@
1
- /**
2
- * These styles are provided as examples. Feel free to change them however you like.
3
- */
1
+ /* core styles */
4
2
  .kenny_dialoggins_dialog {
5
3
  position: absolute;
6
4
  padding: 1em;
7
- border: 1px solid #BBB;
8
- background: #FFF;
5
+ width: 500px;
9
6
  z-index: 2;
7
+ box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
10
8
  -moz-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
11
9
  -webkit-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
12
- filter: alpha(opacity=100); /* really only needed if ie6 suport is enabled */
10
+ opacity: 1;
11
+ filter: alpha(opacity=100);
12
+ background: #fff;
13
+ border: 1px solid #bbb;
13
14
  }
14
-
15
15
  .kenny_dialoggins_dialog_frame {
16
16
  position: absolute;
17
- border: none;
18
17
  z-index: 1;
19
- filter: alpha(opacity=0); /* really only needed if ie6 suport is enabled */
18
+ opacity: 0;
19
+ filter: alpha(opacity=0);
20
+ border: none;
21
+ }
22
+
23
+
24
+ /* error dialog */
25
+ .error_dialog {
26
+ width: 300px;
27
+ background: #d00;
28
+ color: #fff;
29
+ border: 1px solid #d00;
30
+ }
31
+
32
+
33
+ /* help dialog */
34
+ .help_dialog {
35
+ width: 600px;
36
+ background: #ccc;
37
+ color: #333;
38
+ border: 1px solid #666;
20
39
  }
@@ -8,7 +8,7 @@
8
8
  * Brought to you by the good folks at Coroutine. Hire us!
9
9
  * http://coroutine.com
10
10
  */
11
- var KennyDialoggins = {}
11
+ var KennyDialoggins = {};
12
12
 
13
13
 
14
14
  /**
@@ -31,8 +31,9 @@ KennyDialoggins.Dialog = function(content, options) {
31
31
  this._element = null;
32
32
  this._frame = null;
33
33
  this._hideListener = this._generateHideListener();
34
- this._is_showing = false;
34
+ this._isShowing = false;
35
35
 
36
+ this._class = options["class"] || ""
36
37
  this._beforeShow = options["beforeShow"] || Prototype.emptyFunction
37
38
  this._afterShow = options["afterShow"] || Prototype.emptyFunction
38
39
  this._beforeHide = options["beforeHide"] || Prototype.emptyFunction
@@ -40,13 +41,11 @@ KennyDialoggins.Dialog = function(content, options) {
40
41
 
41
42
  this._makeDialog();
42
43
  this.setContent(content);
43
- document.body.appendChild(this._element);
44
44
 
45
45
  if (KennyDialoggins.SUPPORT_IE6_BULLSHIT) {
46
46
  this._makeFrame();
47
- document.body.appendChild(this._frame);
48
47
  }
49
- }
48
+ };
50
49
 
51
50
 
52
51
 
@@ -72,21 +71,18 @@ KennyDialoggins.Dialog._POSITION_FN_MAP = $H({
72
71
 
73
72
 
74
73
  /**
75
- * This method shows the dialog with the corresponding id.
74
+ * This method destroys the dialog with the corresponding id.
76
75
  *
77
76
  * @param {String} id The id value of the dialog element (also the key
78
77
  * in the instances hash.)
79
- *
80
- * @return {Object} an instance of KennyDialoggins.Dialog
81
- *
82
78
  */
83
- KennyDialoggins.Dialog.show = function(id) {
79
+ KennyDialoggins.Dialog.destroy = function(id) {
84
80
  var dialog = this.instances[id];
85
- if(dialog) {
86
- dialog.show();
81
+ if (dialog) {
82
+ dialog.finalize();
87
83
  }
88
- return dialog;
89
- }
84
+ this.instances[id] = null;
85
+ };
90
86
 
91
87
 
92
88
  /**
@@ -100,11 +96,11 @@ KennyDialoggins.Dialog.show = function(id) {
100
96
  */
101
97
  KennyDialoggins.Dialog.hide = function(id) {
102
98
  var dialog = this.instances[id];
103
- if(dialog) {
99
+ if (dialog) {
104
100
  dialog.hide();
105
101
  }
106
102
  return dialog;
107
- }
103
+ };
108
104
 
109
105
 
110
106
  /**
@@ -118,13 +114,31 @@ KennyDialoggins.Dialog.hide = function(id) {
118
114
  * id is showing.
119
115
  *
120
116
  */
121
- KennyDialoggins.Dialog.is_showing = function(id) {
117
+ KennyDialoggins.Dialog.isShowing = function(id) {
122
118
  var dialog = this.instances[id];
123
119
  if (!dialog) {
124
120
  throw "No dialog cound be found for the supplied id.";
125
121
  }
126
- return dialog.is_showing();
127
- }
122
+ return dialog.isShowing();
123
+ };
124
+
125
+
126
+ /**
127
+ * This method shows the dialog with the corresponding id.
128
+ *
129
+ * @param {String} id The id value of the dialog element (also the key
130
+ * in the instances hash.)
131
+ *
132
+ * @return {Object} an instance of KennyDialoggins.Dialog
133
+ *
134
+ */
135
+ KennyDialoggins.Dialog.show = function(id) {
136
+ var dialog = this.instances[id];
137
+ if (dialog) {
138
+ dialog.show();
139
+ }
140
+ return dialog;
141
+ };
128
142
 
129
143
 
130
144
 
@@ -133,6 +147,33 @@ KennyDialoggins.Dialog.is_showing = function(id) {
133
147
  // ----------------------------------------------------------------------------
134
148
 
135
149
  Object.extend(KennyDialoggins.Dialog.prototype, {
150
+
151
+
152
+ /**
153
+ * This function creates the function that handles click events when the dialog is
154
+ * shown. The handler ignores clicks targeted from within the dialog; any click
155
+ * targeted outside the dialog causes the dialog to hide itself and cancel the
156
+ * observer.
157
+ */
158
+ _generateHideListener: function() {
159
+ return function(evt) {
160
+ var origin = evt.findElement(".kenny_dialoggins_dialog");
161
+ if (this._element !== origin) {
162
+ this.hide();
163
+ }
164
+ }.bind(this);
165
+ },
166
+
167
+
168
+ /**
169
+ * This function indicates whether or not the dialog is currently
170
+ * being shown.
171
+ *
172
+ * @return {Boolean} Whether or not the dialog is being shown.
173
+ */
174
+ _isShowing: function() {
175
+ return this._isShowing;
176
+ },
136
177
 
137
178
  /**
138
179
  * This function constructs the dialog element and hides it by default.
@@ -146,8 +187,12 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
146
187
  _makeDialog: function() {
147
188
  if (!this._element) {
148
189
  this._element = new Element("DIV");
149
- this._element.className = "kenny_dialoggins_dialog";
190
+ this._element.addClassName("kenny_dialoggins_dialog");
191
+ if (this._class) {
192
+ this._element.addClassName(this._class);
193
+ }
150
194
  this._element.hide();
195
+ document.body.appendChild(this._element);
151
196
  }
152
197
  },
153
198
 
@@ -164,26 +209,56 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
164
209
  _makeFrame: function() {
165
210
  if (!this._frame) {
166
211
  this._frame = new Element("IFRAME");
167
- this._frame.className = "kenny_dialoggins_dialog_frame";
212
+ this._frame.addClassName("kenny_dialoggins_dialog_frame");
213
+ if (this._class) {
214
+ this._element.addClassName(this._class);
215
+ }
168
216
  this._frame.setAttribute("src", "about:blank");
169
217
  this._frame.hide();
218
+ document.body.appendChild(this._frame);
170
219
  }
171
220
  },
172
-
173
-
221
+
222
+
174
223
  /**
175
- * This function creates the function that handles click events when the dialog is
176
- * shown. The handler ignores clicks targeted from within the dialog; any click
177
- * targeted outside the dialog causes the dialog to hide itself and cancel the
178
- * observer.
224
+ * This function allows the dialog object to be destroyed without
225
+ * creating memory leaks.
179
226
  */
180
- _generateHideListener: function() {
181
- return function(evt) {
182
- var origin = evt.findElement(".kenny_dialoggins_dialog");
183
- if (this._element !== origin) {
184
- this.hide();
185
- }
186
- }.bind(this);
227
+ finalize: function() {
228
+ this.hide();
229
+
230
+ this._element.remove();
231
+ this._element = null;
232
+
233
+ if (this._frame) {
234
+ this._frame.remove();
235
+ this._frame = null;
236
+ }
237
+
238
+ this._hideListener = null;
239
+ },
240
+
241
+
242
+ /**
243
+ * This function hides the dialog. It uses a scriptaculous effect to fade out
244
+ * and disconnects the click observer to prevent memory leaks.
245
+ */
246
+ hide: function() {
247
+ new Effect.Fade(this._element, {
248
+ duration: 0.2,
249
+ beforeStart: this._beforeHide,
250
+ afterFinish: function() {
251
+ this._isShowing = false;
252
+ this._afterHide();
253
+ document.stopObserving("click", this._hideListener);
254
+ }.bind(this)
255
+ });
256
+
257
+ if (this._frame) {
258
+ new Effect.Fade(this._frame, {
259
+ duration: 0.2
260
+ });
261
+ }
187
262
  },
188
263
 
189
264
 
@@ -197,6 +272,16 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
197
272
  },
198
273
 
199
274
 
275
+ /**
276
+ * This function sets the position of the dialog element.
277
+ */
278
+ setPosition: function() {
279
+ var layout = new Element.Layout(this._element);
280
+ this._element.style.top = Math.ceil(((document.viewport.getHeight()/2) + (document.viewport.getScrollOffsets().top) - (layout.get("padding-box-height")/2)) * 2/3) + "px";
281
+ this._element.style.left = Math.ceil((document.viewport.getWidth()/2) + (document.viewport.getScrollOffsets().left) - (layout.get("padding-box-width")/2)) + "px";
282
+ },
283
+
284
+
200
285
  /**
201
286
  * This function displays the dialog. It uses a scriptaculous effect to fade in,
202
287
  * centers the dialog in the viewport (and adjusts the blocking iframe, if in use),
@@ -204,17 +289,14 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
204
289
  * the dialog.
205
290
  */
206
291
  show: function() {
207
- KennyDialoggins.Dialog._POSITION_FN_MAP.each(function(pair) {
208
- var method = pair.last();
209
- this._element.style[pair.first()] =
210
- (document.viewport[method]() / 2 + document.viewport.getScrollOffsets()[pair.first()] - this._element[method]() / 2) + "px";
211
- }.bind(this));
292
+ this.setPosition();
212
293
 
213
294
  if (this._frame) {
295
+ var layout = new Element.Layout(this._element);
214
296
  this._frame.style.top = this._element.style.top;
215
297
  this._frame.style.left = this._element.style.left;
216
- this._frame.style.width = this._element.getWidth() + "px";
217
- this._frame.style.height = this._element.getHeight() + "px";
298
+ this._frame.style.width = layout.get("padding-box-width") + "px";
299
+ this._frame.style.height = layout.get("padding-box-height") + "px";
218
300
 
219
301
  new Effect.Appear(this._frame, {
220
302
  duration: 0.2
@@ -225,44 +307,10 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
225
307
  duration: 0.2,
226
308
  beforeStart: this._beforeShow,
227
309
  afterFinish: function() {
228
- this._is_showing = true;
310
+ this._isShowing = true;
229
311
  this._afterShow();
230
312
  document.observe("click", this._hideListener);
231
313
  }.bind(this)
232
314
  });
233
- },
234
-
235
-
236
- /**
237
- * This function hides the dialog. It uses a scriptaculous effect to fade out
238
- * and disconnects the click observer to prevent memory leaks.
239
- */
240
- hide: function() {
241
- new Effect.Fade(this._element, {
242
- duration: 0.2,
243
- beforeStart: this._beforeHide,
244
- afterFinish: function() {
245
- this._is_showing = false;
246
- this._afterHide();
247
- document.stopObserving("click", this._hideListener);
248
- }.bind(this)
249
- });
250
-
251
- if (this._frame) {
252
- new Effect.Fade(this._frame, {
253
- duration: 0.2
254
- });
255
- }
256
- },
257
-
258
-
259
- /**
260
- * This function indicates whether or not the dialog is currently
261
- * being shown.
262
- *
263
- * @return {Boolean} Whether or not the dialog is being shown.
264
- */
265
- is_showing: function() {
266
- return this._is_showing;
267
315
  }
268
316
  });
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{kenny_dialoggins}
8
- s.version = "1.0.0"
8
+ s.version = "1.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Coroutine", "Tim Lowrimore", "John Dugan"]
12
- s.date = %q{2010-07-29}
12
+ s.date = %q{2010-10-19}
13
13
  s.description = %q{Kenny Dialoggins allows you to include scriptaculous dialogs in Rails applications using the same syntax employed for rendering partials.}
14
14
  s.email = %q{gems@coroutine.com}
15
15
  s.extra_rdoc_files = [
@@ -1,20 +1,39 @@
1
- /**
2
- * These styles are provided as examples. Feel free to change them however you like.
3
- */
1
+ /* core styles */
4
2
  .kenny_dialoggins_dialog {
5
3
  position: absolute;
6
4
  padding: 1em;
7
- border: 1px solid #BBB;
8
- background: #FFF;
5
+ width: 500px;
9
6
  z-index: 2;
7
+ box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
10
8
  -moz-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
11
9
  -webkit-box-shadow: 4px 4px 16px rgba(0,0,0,0.5);
12
- filter: alpha(opacity=100); /* really only needed if ie6 suport is enabled */
10
+ opacity: 1;
11
+ filter: alpha(opacity=100);
12
+ background: #fff;
13
+ border: 1px solid #bbb;
13
14
  }
14
-
15
15
  .kenny_dialoggins_dialog_frame {
16
16
  position: absolute;
17
- border: none;
18
17
  z-index: 1;
19
- filter: alpha(opacity=0); /* really only needed if ie6 suport is enabled */
18
+ opacity: 0;
19
+ filter: alpha(opacity=0);
20
+ border: none;
21
+ }
22
+
23
+
24
+ /* error dialog */
25
+ .error_dialog {
26
+ width: 300px;
27
+ background: #d00;
28
+ color: #fff;
29
+ border: 1px solid #d00;
30
+ }
31
+
32
+
33
+ /* help dialog */
34
+ .help_dialog {
35
+ width: 600px;
36
+ background: #ccc;
37
+ color: #333;
38
+ border: 1px solid #666;
20
39
  }
@@ -8,7 +8,7 @@
8
8
  * Brought to you by the good folks at Coroutine. Hire us!
9
9
  * http://coroutine.com
10
10
  */
11
- var KennyDialoggins = {}
11
+ var KennyDialoggins = {};
12
12
 
13
13
 
14
14
  /**
@@ -31,8 +31,9 @@ KennyDialoggins.Dialog = function(content, options) {
31
31
  this._element = null;
32
32
  this._frame = null;
33
33
  this._hideListener = this._generateHideListener();
34
- this._is_showing = false;
34
+ this._isShowing = false;
35
35
 
36
+ this._class = options["class"] || ""
36
37
  this._beforeShow = options["beforeShow"] || Prototype.emptyFunction
37
38
  this._afterShow = options["afterShow"] || Prototype.emptyFunction
38
39
  this._beforeHide = options["beforeHide"] || Prototype.emptyFunction
@@ -40,13 +41,11 @@ KennyDialoggins.Dialog = function(content, options) {
40
41
 
41
42
  this._makeDialog();
42
43
  this.setContent(content);
43
- document.body.appendChild(this._element);
44
44
 
45
45
  if (KennyDialoggins.SUPPORT_IE6_BULLSHIT) {
46
46
  this._makeFrame();
47
- document.body.appendChild(this._frame);
48
47
  }
49
- }
48
+ };
50
49
 
51
50
 
52
51
 
@@ -72,21 +71,18 @@ KennyDialoggins.Dialog._POSITION_FN_MAP = $H({
72
71
 
73
72
 
74
73
  /**
75
- * This method shows the dialog with the corresponding id.
74
+ * This method destroys the dialog with the corresponding id.
76
75
  *
77
76
  * @param {String} id The id value of the dialog element (also the key
78
77
  * in the instances hash.)
79
- *
80
- * @return {Object} an instance of KennyDialoggins.Dialog
81
- *
82
78
  */
83
- KennyDialoggins.Dialog.show = function(id) {
79
+ KennyDialoggins.Dialog.destroy = function(id) {
84
80
  var dialog = this.instances[id];
85
- if(dialog) {
86
- dialog.show();
81
+ if (dialog) {
82
+ dialog.finalize();
87
83
  }
88
- return dialog;
89
- }
84
+ this.instances[id] = null;
85
+ };
90
86
 
91
87
 
92
88
  /**
@@ -100,11 +96,11 @@ KennyDialoggins.Dialog.show = function(id) {
100
96
  */
101
97
  KennyDialoggins.Dialog.hide = function(id) {
102
98
  var dialog = this.instances[id];
103
- if(dialog) {
99
+ if (dialog) {
104
100
  dialog.hide();
105
101
  }
106
102
  return dialog;
107
- }
103
+ };
108
104
 
109
105
 
110
106
  /**
@@ -118,13 +114,31 @@ KennyDialoggins.Dialog.hide = function(id) {
118
114
  * id is showing.
119
115
  *
120
116
  */
121
- KennyDialoggins.Dialog.is_showing = function(id) {
117
+ KennyDialoggins.Dialog.isShowing = function(id) {
122
118
  var dialog = this.instances[id];
123
119
  if (!dialog) {
124
120
  throw "No dialog cound be found for the supplied id.";
125
121
  }
126
- return dialog.is_showing();
127
- }
122
+ return dialog.isShowing();
123
+ };
124
+
125
+
126
+ /**
127
+ * This method shows the dialog with the corresponding id.
128
+ *
129
+ * @param {String} id The id value of the dialog element (also the key
130
+ * in the instances hash.)
131
+ *
132
+ * @return {Object} an instance of KennyDialoggins.Dialog
133
+ *
134
+ */
135
+ KennyDialoggins.Dialog.show = function(id) {
136
+ var dialog = this.instances[id];
137
+ if (dialog) {
138
+ dialog.show();
139
+ }
140
+ return dialog;
141
+ };
128
142
 
129
143
 
130
144
 
@@ -133,6 +147,33 @@ KennyDialoggins.Dialog.is_showing = function(id) {
133
147
  // ----------------------------------------------------------------------------
134
148
 
135
149
  Object.extend(KennyDialoggins.Dialog.prototype, {
150
+
151
+
152
+ /**
153
+ * This function creates the function that handles click events when the dialog is
154
+ * shown. The handler ignores clicks targeted from within the dialog; any click
155
+ * targeted outside the dialog causes the dialog to hide itself and cancel the
156
+ * observer.
157
+ */
158
+ _generateHideListener: function() {
159
+ return function(evt) {
160
+ var origin = evt.findElement(".kenny_dialoggins_dialog");
161
+ if (this._element !== origin) {
162
+ this.hide();
163
+ }
164
+ }.bind(this);
165
+ },
166
+
167
+
168
+ /**
169
+ * This function indicates whether or not the dialog is currently
170
+ * being shown.
171
+ *
172
+ * @return {Boolean} Whether or not the dialog is being shown.
173
+ */
174
+ _isShowing: function() {
175
+ return this._isShowing;
176
+ },
136
177
 
137
178
  /**
138
179
  * This function constructs the dialog element and hides it by default.
@@ -146,8 +187,12 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
146
187
  _makeDialog: function() {
147
188
  if (!this._element) {
148
189
  this._element = new Element("DIV");
149
- this._element.className = "kenny_dialoggins_dialog";
190
+ this._element.addClassName("kenny_dialoggins_dialog");
191
+ if (this._class) {
192
+ this._element.addClassName(this._class);
193
+ }
150
194
  this._element.hide();
195
+ document.body.appendChild(this._element);
151
196
  }
152
197
  },
153
198
 
@@ -164,26 +209,56 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
164
209
  _makeFrame: function() {
165
210
  if (!this._frame) {
166
211
  this._frame = new Element("IFRAME");
167
- this._frame.className = "kenny_dialoggins_dialog_frame";
212
+ this._frame.addClassName("kenny_dialoggins_dialog_frame");
213
+ if (this._class) {
214
+ this._element.addClassName(this._class);
215
+ }
168
216
  this._frame.setAttribute("src", "about:blank");
169
217
  this._frame.hide();
218
+ document.body.appendChild(this._frame);
170
219
  }
171
220
  },
172
-
173
-
221
+
222
+
174
223
  /**
175
- * This function creates the function that handles click events when the dialog is
176
- * shown. The handler ignores clicks targeted from within the dialog; any click
177
- * targeted outside the dialog causes the dialog to hide itself and cancel the
178
- * observer.
224
+ * This function allows the dialog object to be destroyed without
225
+ * creating memory leaks.
179
226
  */
180
- _generateHideListener: function() {
181
- return function(evt) {
182
- var origin = evt.findElement(".kenny_dialoggins_dialog");
183
- if (this._element !== origin) {
184
- this.hide();
185
- }
186
- }.bind(this);
227
+ finalize: function() {
228
+ this.hide();
229
+
230
+ this._element.remove();
231
+ this._element = null;
232
+
233
+ if (this._frame) {
234
+ this._frame.remove();
235
+ this._frame = null;
236
+ }
237
+
238
+ this._hideListener = null;
239
+ },
240
+
241
+
242
+ /**
243
+ * This function hides the dialog. It uses a scriptaculous effect to fade out
244
+ * and disconnects the click observer to prevent memory leaks.
245
+ */
246
+ hide: function() {
247
+ new Effect.Fade(this._element, {
248
+ duration: 0.2,
249
+ beforeStart: this._beforeHide,
250
+ afterFinish: function() {
251
+ this._isShowing = false;
252
+ this._afterHide();
253
+ document.stopObserving("click", this._hideListener);
254
+ }.bind(this)
255
+ });
256
+
257
+ if (this._frame) {
258
+ new Effect.Fade(this._frame, {
259
+ duration: 0.2
260
+ });
261
+ }
187
262
  },
188
263
 
189
264
 
@@ -197,6 +272,16 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
197
272
  },
198
273
 
199
274
 
275
+ /**
276
+ * This function sets the position of the dialog element.
277
+ */
278
+ setPosition: function() {
279
+ var layout = new Element.Layout(this._element);
280
+ this._element.style.top = Math.ceil(((document.viewport.getHeight()/2) + (document.viewport.getScrollOffsets().top) - (layout.get("padding-box-height")/2)) * 2/3) + "px";
281
+ this._element.style.left = Math.ceil((document.viewport.getWidth()/2) + (document.viewport.getScrollOffsets().left) - (layout.get("padding-box-width")/2)) + "px";
282
+ },
283
+
284
+
200
285
  /**
201
286
  * This function displays the dialog. It uses a scriptaculous effect to fade in,
202
287
  * centers the dialog in the viewport (and adjusts the blocking iframe, if in use),
@@ -204,17 +289,14 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
204
289
  * the dialog.
205
290
  */
206
291
  show: function() {
207
- KennyDialoggins.Dialog._POSITION_FN_MAP.each(function(pair) {
208
- var method = pair.last();
209
- this._element.style[pair.first()] =
210
- (document.viewport[method]() / 2 + document.viewport.getScrollOffsets()[pair.first()] - this._element[method]() / 2) + "px";
211
- }.bind(this));
292
+ this.setPosition();
212
293
 
213
294
  if (this._frame) {
295
+ var layout = new Element.Layout(this._element);
214
296
  this._frame.style.top = this._element.style.top;
215
297
  this._frame.style.left = this._element.style.left;
216
- this._frame.style.width = this._element.getWidth() + "px";
217
- this._frame.style.height = this._element.getHeight() + "px";
298
+ this._frame.style.width = layout.get("padding-box-width") + "px";
299
+ this._frame.style.height = layout.get("padding-box-height") + "px";
218
300
 
219
301
  new Effect.Appear(this._frame, {
220
302
  duration: 0.2
@@ -225,44 +307,10 @@ Object.extend(KennyDialoggins.Dialog.prototype, {
225
307
  duration: 0.2,
226
308
  beforeStart: this._beforeShow,
227
309
  afterFinish: function() {
228
- this._is_showing = true;
310
+ this._isShowing = true;
229
311
  this._afterShow();
230
312
  document.observe("click", this._hideListener);
231
313
  }.bind(this)
232
314
  });
233
- },
234
-
235
-
236
- /**
237
- * This function hides the dialog. It uses a scriptaculous effect to fade out
238
- * and disconnects the click observer to prevent memory leaks.
239
- */
240
- hide: function() {
241
- new Effect.Fade(this._element, {
242
- duration: 0.2,
243
- beforeStart: this._beforeHide,
244
- afterFinish: function() {
245
- this._is_showing = false;
246
- this._afterHide();
247
- document.stopObserving("click", this._hideListener);
248
- }.bind(this)
249
- });
250
-
251
- if (this._frame) {
252
- new Effect.Fade(this._frame, {
253
- duration: 0.2
254
- });
255
- }
256
- },
257
-
258
-
259
- /**
260
- * This function indicates whether or not the dialog is currently
261
- * being shown.
262
- *
263
- * @return {Boolean} Whether or not the dialog is being shown.
264
- */
265
- is_showing: function() {
266
- return this._is_showing;
267
315
  }
268
316
  });
@@ -6,10 +6,12 @@ module Coroutine
6
6
  # to this method is the dialog's <tt>id</tt>. The id is required and should be unique.
7
7
  # Further options may be provided; those that are specific to the dialog are:
8
8
  #
9
+ # * <tt>:class</tt> - a css class name that will be appended to the outermost div to facilitate multiple styles
9
10
  # * <tt>:before_show</tt> - a Javascript function that will be invoked before the dialog is shown
10
11
  # * <tt>:after_show</tt> - a Javascript function that will be invoked after the dialog has become visible
11
12
  # * <tt>:before_hide</tt> - a Javascript function that will be invoked before the dialog is hidden
12
13
  # * <tt>:after_hide</tt> - a Javascript function that will be invoked after the dialog has been hidden
14
+ # * <tt>&block</tt> - HTML markup that will be automatically converted to render's inline option
13
15
  #
14
16
  # All remaining options are the same as the options available to ActionController::Base#render. Please
15
17
  # see the documentation for ActionController::Base#render for further details.
@@ -39,41 +41,92 @@ module Coroutine
39
41
  # <%= render_dialog :foo_dialog, :partial => "foo", :before_show => "function() { alert('bar!') }" %>
40
42
  #
41
43
  # This case is similar to the previous case, except that an alert containing the string, "bar!" will
42
- # appear before the dialog is shown
43
- def render_dialog(id, options={})
44
- dialog_options = [:before_show, :after_show, :before_hide, :after_hide].inject({}) do |result, key|
45
- result[key] = options.delete(key) if options[key]
46
- result
47
- end
48
-
49
- content = escape_javascript render(options)
50
- javascript_tag "KennyDialoggins.Dialog.instances['#{id.to_s}'] = new KennyDialoggins.Dialog('#{content}', #{dialog_options_to_js dialog_options});"
44
+ # appear before the dialog is shown.
45
+ #
46
+ def render_dialog(id, options = {}, &block)
47
+ options[:inline] = capture(&block) if block_given?
48
+ render_options = extract_dialog_render_options(options)
49
+ javascript_options = dialog_options_to_js(extract_dialog_javascript_options(options))
50
+
51
+ content = escape_javascript(render(render_options))
52
+
53
+ raise "You must specify an id to register a dialog." unless id
54
+ raise "You must provide content to register a dialog." unless content
55
+
56
+ javascript_tag "KennyDialoggins.Dialog.instances['#{id.to_s}'] = new KennyDialoggins.Dialog('#{content}', #{javascript_options});"
51
57
  end
52
58
 
59
+
53
60
  # Returns a string of Javascript that will show the dialog identified by the supplied
54
61
  # dialog_id. As an example of useage, this method might be called as the second argument
55
62
  # to ActionView::Helpers::JavaScriptHelper#link_to_function.
63
+ #
56
64
  def show_dialog(dialog_id)
57
65
  "KennyDialoggins.Dialog.show('#{dialog_id.to_s}')"
58
66
  end
59
67
 
68
+
60
69
  # Returns a string of Javascript that will hide the dialog identified by the supplied
61
70
  # dialog_id. As an example of useage, this method might be called as the second argument
62
71
  # to ActionView::Helpers::JavaScriptHelper#link_to_function.
72
+ #
63
73
  def hide_dialog(dialog_id)
64
74
  "KennyDialoggins.Dialog.hide('#{dialog_id.to_s}')"
65
75
  end
66
76
 
77
+
78
+
67
79
  private
68
-
80
+
81
+ # This method returns an array of javascript option keys supported by the accompanying
82
+ # javascript library.
83
+ #
84
+ def dialog_javascript_option_keys
85
+ [:class, :before_show, :after_show, :before_hide, :after_hide]
86
+ end
87
+
88
+
89
+ # This method converts ruby hashes using underscore notation to js strings using camelcase
90
+ # notation, which is more common in javascript.
91
+ #
69
92
  def dialog_options_to_js(options={})
70
93
  js_kv_pairs = []
71
- options.each do |key, value|
72
- js_kv_pairs << "#{key.to_s.camelize(:lower)}:#{value || 'null'}"
94
+ sorted_keys = options.keys.map { |k| k.to_s }.sort.map { |s| s.to_sym }
95
+
96
+ sorted_keys.each do |key|
97
+ js_key = key.to_s.camelcase(:lower)
98
+ js_value = "null"
99
+
100
+ unless options[key].empty?
101
+ case key
102
+ when :before_show, :after_show, :before_hide, :after_hide
103
+ js_value = "#{options[key]}"
104
+ else
105
+ js_value = "'#{options[key]}'"
106
+ end
107
+ end
108
+
109
+ js_kv_pairs << "'#{js_key}':#{js_value}"
73
110
  end
111
+
74
112
  "{#{js_kv_pairs.join(',')}}"
75
113
  end
76
114
 
115
+
116
+ # This method returns a hash with javascript options. It also inspects the supplied options
117
+ # and adds defaults as necessary.
118
+ #
119
+ def extract_dialog_javascript_options(options)
120
+ options.reject { |k,v| !dialog_javascript_option_keys.include?(k) }
121
+ end
122
+
123
+
124
+ # This method returns a hash with rendering options.
125
+ #
126
+ def extract_dialog_render_options(options)
127
+ options.reject { |k,v| dialog_javascript_option_keys.include?(k) }
128
+ end
129
+
77
130
  end
78
131
  end
79
132
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kenny_dialoggins
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ - 3
10
+ version: 1.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Coroutine
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-07-29 00:00:00 -05:00
20
+ date: 2010-10-19 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency