kenny_dialoggins 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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