wontomedia 0.0.1

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.
Files changed (193) hide show
  1. data/COPYING +661 -0
  2. data/COPYING.DOCUMENTATION +450 -0
  3. data/LICENSE +661 -0
  4. data/README.markdown +56 -0
  5. data/Rakefile +185 -0
  6. data/VERSION.yml +4 -0
  7. data/app/controllers/admin_controller.rb +144 -0
  8. data/app/controllers/application_controller.rb +29 -0
  9. data/app/controllers/connections_controller.rb +150 -0
  10. data/app/controllers/items_controller.rb +365 -0
  11. data/app/helpers/connections_helper.rb +67 -0
  12. data/app/helpers/format_helper.rb +154 -0
  13. data/app/helpers/items_helper.rb +105 -0
  14. data/app/models/category_item.rb +23 -0
  15. data/app/models/connection.rb +210 -0
  16. data/app/models/individual_item.rb +23 -0
  17. data/app/models/item.rb +86 -0
  18. data/app/models/property_item.rb +23 -0
  19. data/app/models/qualified_item.rb +23 -0
  20. data/app/views/admin/index.html.erb +74 -0
  21. data/app/views/connections/_index_outbound_links.html.erb +48 -0
  22. data/app/views/connections/_spo_select_controls.html.erb +151 -0
  23. data/app/views/connections/edit.html.erb +70 -0
  24. data/app/views/connections/index.html.erb +84 -0
  25. data/app/views/connections/new.html.erb +61 -0
  26. data/app/views/connections/show.html.erb +110 -0
  27. data/app/views/items/_active_content.html.erb +26 -0
  28. data/app/views/items/_content_examples.html.erb +55 -0
  29. data/app/views/items/_core_tasks.html.erb +23 -0
  30. data/app/views/items/_form_fields.html.erb +69 -0
  31. data/app/views/items/_list_outbound_links.html.erb +58 -0
  32. data/app/views/items/_screen_select.html.erb +24 -0
  33. data/app/views/items/_show_outbound_links.html.erb +70 -0
  34. data/app/views/items/_topic_list.html.erb +26 -0
  35. data/app/views/items/_type_select.html.erb +47 -0
  36. data/app/views/items/edit.html.erb +63 -0
  37. data/app/views/items/index.html.erb +74 -0
  38. data/app/views/items/new.html.erb +124 -0
  39. data/app/views/items/newpop.html.erb +58 -0
  40. data/app/views/items/show.html.erb +209 -0
  41. data/app/views/layouts/_amazon_ads.html.erb +55 -0
  42. data/app/views/layouts/_glossary_help_box.html.erb +43 -0
  43. data/app/views/layouts/_google_ads.html.erb +40 -0
  44. data/app/views/layouts/_language_select.html.erb +24 -0
  45. data/app/views/layouts/_login_controls.html.erb +24 -0
  46. data/app/views/layouts/_master_help.html.erb +24 -0
  47. data/app/views/layouts/_navigation_menu.html.erb +39 -0
  48. data/app/views/layouts/_search_box.html.erb +27 -0
  49. data/app/views/layouts/_status_msgs.html.erb +25 -0
  50. data/app/views/layouts/application.html.erb +67 -0
  51. data/app/views/layouts/base.html.erb +93 -0
  52. data/app/views/layouts/home.html.erb +67 -0
  53. data/app/views/layouts/popup.html.erb +23 -0
  54. data/assets/wontomedia-sample.rb +47 -0
  55. data/config/asset_packages.yml +44 -0
  56. data/config/boot.rb +110 -0
  57. data/config/cucumber.yml +65 -0
  58. data/config/database-mysql-development.yml +47 -0
  59. data/config/database-mysql.yml +26 -0
  60. data/config/environment.rb +94 -0
  61. data/config/environments/cucumber.rb +29 -0
  62. data/config/environments/development.rb +26 -0
  63. data/config/environments/production.rb +33 -0
  64. data/config/environments/test.rb +31 -0
  65. data/config/initializers/inflections.rb +19 -0
  66. data/config/initializers/mime_types.rb +14 -0
  67. data/config/initializers/new_rails_defaults.rb +26 -0
  68. data/config/locales/en.yml +14 -0
  69. data/config/routes.rb +37 -0
  70. data/db/fixtures/connections.yml +96 -0
  71. data/db/fixtures/items.yml +277 -0
  72. data/db/migrate/20090312212805_create_items.rb +31 -0
  73. data/db/migrate/20090406221320_create_connections.rb +32 -0
  74. data/db/migrate/20090411014503_add_type_for_item_subclasses.rb +29 -0
  75. data/db/migrate/20090415142152_rename_item_type.rb +31 -0
  76. data/db/migrate/20090518022918_rename_object_and_self.rb +33 -0
  77. data/db/migrate/20090529171442_add_flags_to_items.rb +27 -0
  78. data/db/migrate/20090529171508_add_flags_to_connections.rb +27 -0
  79. data/db/migrate/20090605213800_flags_columns_not_null.rb +29 -0
  80. data/db/migrate/20090605215028_flags_columns_default_zero.rb +29 -0
  81. data/db/schema.rb +30 -0
  82. data/default-custom/app/views/items/_home_extern_list.html.erb +32 -0
  83. data/default-custom/app/views/items/_home_introductory_text.html.erb +70 -0
  84. data/default-custom/app/views/items/home.html.erb +77 -0
  85. data/default-custom/public/images/logo.png +0 -0
  86. data/default-custom/public/images/logo.svg +74 -0
  87. data/default-custom/public/stylesheets/wm.css +301 -0
  88. data/doc/README.markdown +44 -0
  89. data/doc/README_FOR_APP +82 -0
  90. data/doc/customization.markdown +93 -0
  91. data/doc/scripts/rake-customize.markdown +83 -0
  92. data/lib/helpers/connection_helper.rb +41 -0
  93. data/lib/helpers/item_helper.rb +141 -0
  94. data/lib/helpers/tripple_navigation.rb +158 -0
  95. data/lib/tasks/cucumber.rake +83 -0
  96. data/lib/tasks/customize.rake +70 -0
  97. data/lib/tasks/db.rake +65 -0
  98. data/lib/tasks/javascript_testing_tasks.rake +176 -0
  99. data/public/404.html +50 -0
  100. data/public/422.html +50 -0
  101. data/public/500.html +53 -0
  102. data/public/dispatch.cgi +20 -0
  103. data/public/dispatch.fcgi +34 -0
  104. data/public/dispatch.rb +20 -0
  105. data/public/favicon.ico +0 -0
  106. data/public/images/blank_error_icon.png +0 -0
  107. data/public/images/blank_status_icon.png +0 -0
  108. data/public/images/error_error_icon.png +0 -0
  109. data/public/images/error_status_icon.png +0 -0
  110. data/public/images/good_status_icon.png +0 -0
  111. data/public/images/help_icon.png +0 -0
  112. data/public/images/twitter_icon.png +0 -0
  113. data/public/images/warn_error_icon.png +0 -0
  114. data/public/images/working_status_icon.gif +0 -0
  115. data/public/javascripts/application.js +56 -0
  116. data/public/javascripts/controls.js +963 -0
  117. data/public/javascripts/dragdrop.js +973 -0
  118. data/public/javascripts/effects.js +1128 -0
  119. data/public/javascripts/event.simulate.js +64 -0
  120. data/public/javascripts/fancybox.js +43 -0
  121. data/public/javascripts/forConnectionsForms.js +218 -0
  122. data/public/javascripts/forItemsForms.js +511 -0
  123. data/public/javascripts/itemCreatePopup.js +115 -0
  124. data/public/javascripts/itemTitleToName.js +119 -0
  125. data/public/javascripts/jquery.js +4376 -0
  126. data/public/javascripts/modalbox.js +502 -0
  127. data/public/javascripts/prototype.js +4320 -0
  128. data/public/javascripts/reconcileJQueryAndPrototype.js +19 -0
  129. data/public/robots.txt +7 -0
  130. data/public/stylesheets/blank.gif +0 -0
  131. data/public/stylesheets/fancy_close.png +0 -0
  132. data/public/stylesheets/fancy_loading.png +0 -0
  133. data/public/stylesheets/fancy_nav_left.png +0 -0
  134. data/public/stylesheets/fancy_nav_right.png +0 -0
  135. data/public/stylesheets/fancy_shadow_e.png +0 -0
  136. data/public/stylesheets/fancy_shadow_n.png +0 -0
  137. data/public/stylesheets/fancy_shadow_ne.png +0 -0
  138. data/public/stylesheets/fancy_shadow_nw.png +0 -0
  139. data/public/stylesheets/fancy_shadow_s.png +0 -0
  140. data/public/stylesheets/fancy_shadow_se.png +0 -0
  141. data/public/stylesheets/fancy_shadow_sw.png +0 -0
  142. data/public/stylesheets/fancy_shadow_w.png +0 -0
  143. data/public/stylesheets/fancy_title_left.png +0 -0
  144. data/public/stylesheets/fancy_title_main.png +0 -0
  145. data/public/stylesheets/fancy_title_over.png +0 -0
  146. data/public/stylesheets/fancy_title_right.png +0 -0
  147. data/public/stylesheets/fancybox.css +333 -0
  148. data/public/stylesheets/modalbox.css +110 -0
  149. data/public/stylesheets/scaffold.css +36 -0
  150. data/public/stylesheets/spinner.gif +0 -0
  151. data/script/about +4 -0
  152. data/script/console +3 -0
  153. data/script/cucumber +10 -0
  154. data/script/dbconsole +3 -0
  155. data/script/destroy +3 -0
  156. data/script/generate +3 -0
  157. data/script/performance/benchmarker +3 -0
  158. data/script/performance/profiler +3 -0
  159. data/script/performance/request +3 -0
  160. data/script/plugin +3 -0
  161. data/script/process/inspector +3 -0
  162. data/script/process/reaper +3 -0
  163. data/script/process/spawner +3 -0
  164. data/script/runner +3 -0
  165. data/script/server +3 -0
  166. data/vendor/plugins/asset_packager/CHANGELOG +122 -0
  167. data/vendor/plugins/asset_packager/README +178 -0
  168. data/vendor/plugins/asset_packager/Rakefile +22 -0
  169. data/vendor/plugins/asset_packager/about.yml +8 -0
  170. data/vendor/plugins/asset_packager/init.rb +2 -0
  171. data/vendor/plugins/asset_packager/install.rb +1 -0
  172. data/vendor/plugins/asset_packager/lib/jsmin.rb +205 -0
  173. data/vendor/plugins/asset_packager/lib/synthesis/asset_package.rb +212 -0
  174. data/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb +39 -0
  175. data/vendor/plugins/asset_packager/tasks/asset_packager_tasks.rake +23 -0
  176. data/vendor/plugins/asset_packager/test/asset_package_helper_development_test.rb +100 -0
  177. data/vendor/plugins/asset_packager/test/asset_package_helper_production_test.rb +140 -0
  178. data/vendor/plugins/asset_packager/test/asset_packager_test.rb +92 -0
  179. data/vendor/plugins/asset_packager/test/asset_packages.yml +20 -0
  180. data/vendor/plugins/asset_packager/test/assets/javascripts/application.js +2 -0
  181. data/vendor/plugins/asset_packager/test/assets/javascripts/bar.js +4 -0
  182. data/vendor/plugins/asset_packager/test/assets/javascripts/controls.js +815 -0
  183. data/vendor/plugins/asset_packager/test/assets/javascripts/dragdrop.js +913 -0
  184. data/vendor/plugins/asset_packager/test/assets/javascripts/effects.js +958 -0
  185. data/vendor/plugins/asset_packager/test/assets/javascripts/foo.js +4 -0
  186. data/vendor/plugins/asset_packager/test/assets/javascripts/prototype.js +2006 -0
  187. data/vendor/plugins/asset_packager/test/assets/stylesheets/bar.css +16 -0
  188. data/vendor/plugins/asset_packager/test/assets/stylesheets/foo.css +16 -0
  189. data/vendor/plugins/asset_packager/test/assets/stylesheets/header.css +16 -0
  190. data/vendor/plugins/asset_packager/test/assets/stylesheets/screen.css +16 -0
  191. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/bar.css +16 -0
  192. data/vendor/plugins/asset_packager/test/assets/stylesheets/subdir/foo.css +16 -0
  193. metadata +265 -0
@@ -0,0 +1,502 @@
1
+ /*
2
+ ModalBox - The pop-up window thingie with AJAX, based on prototype and script.aculo.us.
3
+
4
+ Copyright Andrey Okonetchnikov (andrej.okonetschnikow@gmail.com), 2006-2007
5
+ All rights reserved.
6
+
7
+ VERSION 1.6.1
8
+ Last Modified: 04/13/2008
9
+ */
10
+
11
+ if (!window.Modalbox)
12
+ var Modalbox = new Object();
13
+
14
+ Modalbox.Methods = {
15
+ overrideAlert: false, // Override standard browser alert message with ModalBox
16
+ focusableElements: new Array,
17
+ currFocused: 0,
18
+ initialized: false,
19
+ active: true,
20
+ options: {
21
+ title: "ModalBox Window", // Title of the ModalBox window
22
+ overlayClose: true, // Close modal box by clicking on overlay
23
+ width: 500, // Default width in px
24
+ height: 90, // Default height in px
25
+ overlayOpacity: .65, // Default overlay opacity
26
+ overlayDuration: .25, // Default overlay fade in/out duration in seconds
27
+ slideDownDuration: .5, // Default Modalbox appear slide down effect in seconds
28
+ slideUpDuration: .5, // Default Modalbox hiding slide up effect in seconds
29
+ resizeDuration: .25, // Default resize duration seconds
30
+ inactiveFade: true, // Fades MB window on inactive state
31
+ transitions: true, // Toggles transition effects. Transitions are enabled by default
32
+ loadingString: "Please wait. Loading...", // Default loading string message
33
+ closeString: "Close window", // Default title attribute for close window link
34
+ closeValue: "×", // Default string for close link in the header
35
+ params: {},
36
+ method: 'get', // Default Ajax request method
37
+ autoFocusing: true, // Toggles auto-focusing for form elements. Disable for long text pages.
38
+ aspnet: false // Should be use then using with ASP.NET costrols. Then true Modalbox window will be injected into the first form element.
39
+ },
40
+ _options: new Object,
41
+
42
+ setOptions: function(options) {
43
+ Object.extend(this.options, options || {});
44
+ },
45
+
46
+ _init: function(options) {
47
+ // Setting up original options with default options
48
+ Object.extend(this._options, this.options);
49
+ this.setOptions(options);
50
+
51
+ //Creating the overlay
52
+ this.MBoverlay = new Element("div", { id: "MB_overlay", style: "opacity: 0" });
53
+
54
+ //Creating the modal window
55
+ this.MBwindow = new Element("div", {id: "MB_window", style: "display: none; overflow: hidden"}).update(
56
+ this.MBframe = new Element("div", {id: "MB_frame"}).update(
57
+ this.MBheader = new Element("div", {id: "MB_header"}).update(
58
+ this.MBcaption = new Element("div", {id: "MB_caption"})
59
+ )
60
+ )
61
+ );
62
+ this.MBclose = new Element("a", {id: "MB_close", title: this.options.closeString, href: "#"}).update("<span>" + this.options.closeValue + "</span>");
63
+ this.MBheader.insert({'bottom':this.MBclose});
64
+
65
+ this.MBcontent = new Element("div", {id: "MB_content"}).update(
66
+ this.MBloading = new Element("div", {id: "MB_loading"}).update(this.options.loadingString)
67
+ );
68
+ this.MBframe.insert({'bottom':this.MBcontent});
69
+
70
+ // Inserting into DOM. If parameter set and form element have been found will inject into it. Otherwise will inject into body as topmost element.
71
+ // Be sure to set padding and marging to null via CSS for both body and (in case of asp.net) form elements.
72
+ var injectToEl = this.options.aspnet ? $(document.body).down('form') : $(document.body);
73
+ injectToEl.insert({'top':this.MBwindow});
74
+ injectToEl.insert({'top':this.MBoverlay});
75
+
76
+ // Initial scrolling position of the window. To be used for remove scrolling effect during ModalBox appearing
77
+ this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
78
+ this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
79
+
80
+ //Adding event observers
81
+ this.hideObserver = this._hide.bindAsEventListener(this);
82
+ this.kbdObserver = this._kbdHandler.bindAsEventListener(this);
83
+ this._initObservers();
84
+
85
+ this.initialized = true; // Mark as initialized
86
+ },
87
+
88
+ show: function(content, options) {
89
+ if(!this.initialized) this._init(options); // Check for is already initialized
90
+
91
+ this.content = content;
92
+ this.setOptions(options);
93
+
94
+ if(this.options.title) // Updating title of the MB
95
+ $(this.MBcaption).update(this.options.title);
96
+ else { // If title isn't given, the header will not displayed
97
+ $(this.MBheader).hide();
98
+ $(this.MBcaption).hide();
99
+ }
100
+
101
+ if(this.MBwindow.style.display == "none") { // First modal box appearing
102
+ this._appear();
103
+ this.event("onShow"); // Passing onShow callback
104
+ }
105
+ else { // If MB already on the screen, update it
106
+ this._update();
107
+ this.event("onUpdate"); // Passing onUpdate callback
108
+ }
109
+ },
110
+
111
+ hide: function(options) { // External hide method to use from external HTML and JS
112
+ if(this.initialized) {
113
+ // Reading for options/callbacks except if event given as a pararmeter
114
+ if(options && typeof options.element != 'function') Object.extend(this.options, options);
115
+ // Passing beforeHide callback
116
+ this.event("beforeHide");
117
+ if(this.options.transitions)
118
+ Effect.SlideUp(this.MBwindow, { duration: this.options.slideUpDuration, transition: Effect.Transitions.sinoidal, afterFinish: this._deinit.bind(this) } );
119
+ else {
120
+ $(this.MBwindow).hide();
121
+ this._deinit();
122
+ }
123
+ } else throw("Modalbox is not initialized.");
124
+ },
125
+
126
+ _hide: function(event) { // Internal hide method to use with overlay and close link
127
+ event.stop(); // Stop event propaganation for link elements
128
+ /* Then clicked on overlay we'll check the option and in case of overlayClose == false we'll break hiding execution [Fix for #139] */
129
+ if(event.element().id == 'MB_overlay' && !this.options.overlayClose) return false;
130
+ this.hide();
131
+ },
132
+
133
+ alert: function(message){
134
+ var html = '<div class="MB_alert"><p>' + message + '</p><input type="button" onclick="Modalbox.hide()" value="OK" /></div>';
135
+ Modalbox.show(html, {title: 'Alert: ' + document.title, width: 300});
136
+ },
137
+
138
+ _appear: function() { // First appearing of MB
139
+ if(Prototype.Browser.IE && !navigator.appVersion.match(/\b7.0\b/)) { // Preparing IE 6 for showing modalbox
140
+ window.scrollTo(0,0);
141
+ this._prepareIE("100%", "hidden");
142
+ }
143
+ this._setWidth();
144
+ this._setPosition();
145
+ if(this.options.transitions) {
146
+ $(this.MBoverlay).setStyle({opacity: 0});
147
+ new Effect.Fade(this.MBoverlay, {
148
+ from: 0,
149
+ to: this.options.overlayOpacity,
150
+ duration: this.options.overlayDuration,
151
+ afterFinish: function() {
152
+ new Effect.SlideDown(this.MBwindow, {
153
+ duration: this.options.slideDownDuration,
154
+ transition: Effect.Transitions.sinoidal,
155
+ afterFinish: function(){
156
+ this._setPosition();
157
+ this.loadContent();
158
+ }.bind(this)
159
+ });
160
+ }.bind(this)
161
+ });
162
+ } else {
163
+ $(this.MBoverlay).setStyle({opacity: this.options.overlayOpacity});
164
+ $(this.MBwindow).show();
165
+ this._setPosition();
166
+ this.loadContent();
167
+ }
168
+ this._setWidthAndPosition = this._setWidthAndPosition.bindAsEventListener(this);
169
+ Event.observe(window, "resize", this._setWidthAndPosition);
170
+ },
171
+
172
+ resize: function(byWidth, byHeight, options) { // Change size of MB without loading content
173
+ var oWidth = $(this.MBoverlay).getWidth();
174
+ var wHeight = $(this.MBwindow).getHeight();
175
+ var wWidth = $(this.MBwindow).getWidth();
176
+ var hHeight = $(this.MBheader).getHeight();
177
+ var cHeight = $(this.MBcontent).getHeight();
178
+ var newHeight = ((wHeight - hHeight + byHeight) < cHeight) ? (cHeight + hHeight) : (wHeight + byHeight);
179
+ var newWidth = wWidth + byWidth;
180
+ this.options.width = newWidth;
181
+ if(options) this.setOptions(options); // Passing callbacks
182
+ if(this.options.transitions) {
183
+ new Effect.Morph(this.MBwindow, {
184
+ style: "width:" + newWidth + "px; height:" + newHeight + "px; left:" + ((oWidth - newWidth)/2) + "px",
185
+ duration: this.options.resizeDuration,
186
+ beforeStart: function(fx){
187
+ fx.element.setStyle({overflow:"hidden"}); // Fix for MSIE 6 to resize correctly
188
+ },
189
+ afterFinish: function(fx) {
190
+ fx.element.setStyle({overflow:"visible"});
191
+ this.event("_afterResize"); // Passing internal callback
192
+ this.event("afterResize"); // Passing callback
193
+ }.bind(this)
194
+ });
195
+ } else {
196
+ this.MBwindow.setStyle({width: newWidth + "px", height: newHeight + "px"});
197
+ setTimeout(function() {
198
+ this.event("_afterResize"); // Passing internal callback
199
+ this.event("afterResize"); // Passing callback
200
+ }.bind(this), 1);
201
+ }
202
+
203
+ },
204
+
205
+ resizeToContent: function(options){
206
+
207
+ // Resizes the modalbox window to the actual content height.
208
+ // This might be useful to resize modalbox after some content modifications which were changed ccontent height.
209
+
210
+ var byHeight = this.options.height - $(this.MBwindow).getHeight();
211
+ if(byHeight != 0) {
212
+ if(options) this.setOptions(options); // Passing callbacks
213
+ Modalbox.resize(0, byHeight);
214
+ }
215
+ },
216
+
217
+ resizeToInclude: function(element, options){
218
+
219
+ // Resizes the modalbox window to the camulative height of element. Calculations are using CSS properties for margins and border.
220
+ // This method might be useful to resize modalbox before including or updating content.
221
+
222
+ var el = $(element);
223
+ var elHeight = el.getHeight() + parseInt(el.getStyle('margin-top'), 0) + parseInt(el.getStyle('margin-bottom'), 0) + parseInt(el.getStyle('border-top-width'), 0) + parseInt(el.getStyle('border-bottom-width'), 0);
224
+ if(elHeight > 0) {
225
+ if(options) this.setOptions(options); // Passing callbacks
226
+ Modalbox.resize(0, elHeight);
227
+ }
228
+ },
229
+
230
+ _update: function() { // Updating MB in case of wizards
231
+ $(this.MBcontent).update($(this.MBloading).update(this.options.loadingString));
232
+ this.loadContent();
233
+ },
234
+
235
+ loadContent: function () {
236
+ if(this.event("beforeLoad") != false) { // If callback passed false, skip loading of the content
237
+ if(typeof this.content == 'string') {
238
+ var htmlRegExp = new RegExp(/<\/?[^>]+>/gi);
239
+ if(htmlRegExp.test(this.content)) { // Plain HTML given as a parameter
240
+ this._insertContent(this.content.stripScripts(), function(){
241
+ this.content.extractScripts().map(function(script) {
242
+ return eval(script.replace("<!--", "").replace("// -->", ""));
243
+ }.bind(window));
244
+ }.bind(this));
245
+ } else // URL given as a parameter. We'll request it via Ajax
246
+ new Ajax.Request( this.content, { method: this.options.method.toLowerCase(), parameters: this.options.params,
247
+ onSuccess: function(transport) {
248
+ var response = new String(transport.responseText);
249
+ this._insertContent(transport.responseText.stripScripts(), function(){
250
+ response.extractScripts().map(function(script) {
251
+ return eval(script.replace("<!--", "").replace("// -->", ""));
252
+ }.bind(window));
253
+ });
254
+ }.bind(this),
255
+ onException: function(instance, exception){
256
+ Modalbox.hide();
257
+ throw('Modalbox Loading Error: ' + exception);
258
+ }
259
+ });
260
+
261
+ } else if (typeof this.content == 'object') {// HTML Object is given
262
+ this._insertContent(this.content);
263
+ } else {
264
+ Modalbox.hide();
265
+ throw('Modalbox Parameters Error: Please specify correct URL or HTML element (plain HTML or object)');
266
+ }
267
+ }
268
+ },
269
+
270
+ _insertContent: function(content, callback){
271
+ $(this.MBcontent).hide().update("");
272
+ if(typeof content == 'string') { // Plain HTML is given
273
+ this.MBcontent.update(new Element("div", { style: "display: none" }).update(content)).down().show();
274
+ } else if (typeof content == 'object') { // HTML Object is given
275
+ var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it
276
+ // If clonable element has ID attribute defined, modifying it to prevent duplicates
277
+ if(content.id) content.id = "MB_" + content.id;
278
+ /* Add prefix for IDs on all elements inside the DOM node */
279
+ $(content).select('*[id]').each(function(el){ el.id = "MB_" + el.id; });
280
+ this.MBcontent.update(_htmlObj).down('div').show();
281
+ if(Prototype.Browser.IE) // Toggling back visibility for hidden selects in IE
282
+ $$("#MB_content select").invoke('setStyle', {'visibility': ''});
283
+ }
284
+
285
+ // Prepare and resize modal box for content
286
+ if(this.options.height == this._options.height) {
287
+ Modalbox.resize((this.options.width - $(this.MBwindow).getWidth()), $(this.MBcontent).getHeight() - $(this.MBwindow).getHeight() + $(this.MBheader).getHeight(), {
288
+ afterResize: function(){
289
+ setTimeout(function(){ // MSIE fix
290
+ this._putContent(callback);
291
+ }.bind(this),1);
292
+ }.bind(this)
293
+ });
294
+ } else { // Height is defined. Creating a scrollable window
295
+ this._setWidth();
296
+ this.MBcontent.setStyle({overflow: 'auto', height: $(this.MBwindow).getHeight() - $(this.MBheader).getHeight() - 13 + 'px'});
297
+ setTimeout(function(){ // MSIE fix
298
+ this._putContent(callback);
299
+ }.bind(this),1);
300
+ }
301
+ },
302
+
303
+ _putContent: function(callback){
304
+ this.MBcontent.show();
305
+ this.focusableElements = this._findFocusableElements();
306
+ this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
307
+ if(callback != undefined)
308
+ callback(); // Executing internal JS from loaded content
309
+ this.event("afterLoad"); // Passing callback
310
+ },
311
+
312
+ activate: function(options){
313
+ this.setOptions(options);
314
+ this.active = true;
315
+ $(this.MBclose).observe("click", this.hideObserver);
316
+ if(this.options.overlayClose)
317
+ $(this.MBoverlay).observe("click", this.hideObserver);
318
+ $(this.MBclose).show();
319
+ if(this.options.transitions && this.options.inactiveFade)
320
+ new Effect.Appear(this.MBwindow, {duration: this.options.slideUpDuration});
321
+ },
322
+
323
+ deactivate: function(options) {
324
+ this.setOptions(options);
325
+ this.active = false;
326
+ $(this.MBclose).stopObserving("click", this.hideObserver);
327
+ if(this.options.overlayClose)
328
+ $(this.MBoverlay).stopObserving("click", this.hideObserver);
329
+ $(this.MBclose).hide();
330
+ if(this.options.transitions && this.options.inactiveFade)
331
+ new Effect.Fade(this.MBwindow, {duration: this.options.slideUpDuration, to: .75});
332
+ },
333
+
334
+ _initObservers: function(){
335
+ $(this.MBclose).observe("click", this.hideObserver);
336
+ if(this.options.overlayClose)
337
+ $(this.MBoverlay).observe("click", this.hideObserver);
338
+ if(Prototype.Browser.Gecko)
339
+ Event.observe(document, "keypress", this.kbdObserver); // Gecko is moving focus a way too fast
340
+ else
341
+ Event.observe(document, "keydown", this.kbdObserver); // All other browsers are okay with keydown
342
+ },
343
+
344
+ _removeObservers: function(){
345
+ $(this.MBclose).stopObserving("click", this.hideObserver);
346
+ if(this.options.overlayClose)
347
+ $(this.MBoverlay).stopObserving("click", this.hideObserver);
348
+ if(Prototype.Browser.Gecko)
349
+ Event.stopObserving(document, "keypress", this.kbdObserver);
350
+ else
351
+ Event.stopObserving(document, "keydown", this.kbdObserver);
352
+ },
353
+
354
+ _setFocus: function() {
355
+ /* Setting focus to the first 'focusable' element which is one with tabindex = 1 or the first in the form loaded. */
356
+ if(this.focusableElements.length > 0 && this.options.autoFocusing == true) {
357
+ var firstEl = this.focusableElements.find(function (el){
358
+ return el.tabIndex == 1;
359
+ }) || this.focusableElements.first();
360
+ this.currFocused = this.focusableElements.toArray().indexOf(firstEl);
361
+ firstEl.focus(); // Focus on first focusable element except close button
362
+ } else if($(this.MBclose).visible())
363
+ $(this.MBclose).focus(); // If no focusable elements exist focus on close button
364
+ },
365
+
366
+ _findFocusableElements: function(){ // Collect form elements or links from MB content
367
+ this.MBcontent.select('input:not([type~=hidden]), select, textarea, button, a[href]').invoke('addClassName', 'MB_focusable');
368
+ return this.MBcontent.select('.MB_focusable');
369
+ },
370
+
371
+ _kbdHandler: function(event) {
372
+ var node = event.element();
373
+ switch(event.keyCode) {
374
+ case Event.KEY_TAB:
375
+ event.stop();
376
+
377
+ /* Switching currFocused to the element which was focused by mouse instead of TAB-key. Fix for #134 */
378
+ if(node != this.focusableElements[this.currFocused])
379
+ this.currFocused = this.focusableElements.toArray().indexOf(node);
380
+
381
+ if(!event.shiftKey) { //Focusing in direct order
382
+ if(this.currFocused == this.focusableElements.length - 1) {
383
+ this.focusableElements.first().focus();
384
+ this.currFocused = 0;
385
+ } else {
386
+ this.currFocused++;
387
+ this.focusableElements[this.currFocused].focus();
388
+ }
389
+ } else { // Shift key is pressed. Focusing in reverse order
390
+ if(this.currFocused == 0) {
391
+ this.focusableElements.last().focus();
392
+ this.currFocused = this.focusableElements.length - 1;
393
+ } else {
394
+ this.currFocused--;
395
+ this.focusableElements[this.currFocused].focus();
396
+ }
397
+ }
398
+ break;
399
+ case Event.KEY_ESC:
400
+ if(this.active) this._hide(event);
401
+ break;
402
+ case 32:
403
+ this._preventScroll(event);
404
+ break;
405
+ case 0: // For Gecko browsers compatibility
406
+ if(event.which == 32) this._preventScroll(event);
407
+ break;
408
+ case Event.KEY_UP:
409
+ case Event.KEY_DOWN:
410
+ case Event.KEY_PAGEDOWN:
411
+ case Event.KEY_PAGEUP:
412
+ case Event.KEY_HOME:
413
+ case Event.KEY_END:
414
+ // Safari operates in slightly different way. This realization is still buggy in Safari.
415
+ if(Prototype.Browser.WebKit && !["textarea", "select"].include(node.tagName.toLowerCase()))
416
+ event.stop();
417
+ else if( (node.tagName.toLowerCase() == "input" && ["submit", "button"].include(node.type)) || (node.tagName.toLowerCase() == "a") )
418
+ event.stop();
419
+ break;
420
+ }
421
+ },
422
+
423
+ _preventScroll: function(event) { // Disabling scrolling by "space" key
424
+ if(!["input", "textarea", "select", "button"].include(event.element().tagName.toLowerCase()))
425
+ event.stop();
426
+ },
427
+
428
+ _deinit: function()
429
+ {
430
+ this._removeObservers();
431
+ Event.stopObserving(window, "resize", this._setWidthAndPosition );
432
+ if(this.options.transitions) {
433
+ Effect.toggle(this.MBoverlay, 'appear', {duration: this.options.overlayDuration, afterFinish: this._removeElements.bind(this) });
434
+ } else {
435
+ this.MBoverlay.hide();
436
+ this._removeElements();
437
+ }
438
+ $(this.MBcontent).setStyle({overflow: '', height: ''});
439
+ },
440
+
441
+ _removeElements: function () {
442
+ $(this.MBoverlay).remove();
443
+ $(this.MBwindow).remove();
444
+ if(Prototype.Browser.IE && !navigator.appVersion.match(/\b7.0\b/)) {
445
+ this._prepareIE("", ""); // If set to auto MSIE will show horizontal scrolling
446
+ window.scrollTo(this.initScrollX, this.initScrollY);
447
+ }
448
+
449
+ /* Replacing prefixes 'MB_' in IDs for the original content */
450
+ if(typeof this.content == 'object') {
451
+ if(this.content.id && this.content.id.match(/MB_/)) {
452
+ this.content.id = this.content.id.replace(/MB_/, "");
453
+ }
454
+ this.content.select('*[id]').each(function(el){ el.id = el.id.replace(/MB_/, ""); });
455
+ }
456
+ /* Initialized will be set to false */
457
+ this.initialized = false;
458
+ this.event("afterHide"); // Passing afterHide callback
459
+ this.setOptions(this._options); //Settings options object into intial state
460
+ },
461
+
462
+ _setWidth: function () { //Set size
463
+ $(this.MBwindow).setStyle({width: this.options.width + "px", height: this.options.height + "px"});
464
+ },
465
+
466
+ _setPosition: function () {
467
+ $(this.MBwindow).setStyle({left: (($(this.MBoverlay).getWidth() - $(this.MBwindow).getWidth()) / 2 ) + "px"});
468
+ },
469
+
470
+ _setWidthAndPosition: function () {
471
+ $(this.MBwindow).setStyle({width: this.options.width + "px"});
472
+ this._setPosition();
473
+ },
474
+
475
+ _getScrollTop: function () { //From: http://www.quirksmode.org/js/doctypes.html
476
+ var theTop;
477
+ if (document.documentElement && document.documentElement.scrollTop)
478
+ theTop = document.documentElement.scrollTop;
479
+ else if (document.body)
480
+ theTop = document.body.scrollTop;
481
+ return theTop;
482
+ },
483
+ _prepareIE: function(height, overflow){
484
+ $$('html, body').invoke('setStyle', {width: height, height: height, overflow: overflow}); // IE requires width and height set to 100% and overflow hidden
485
+ $$("select").invoke('setStyle', {'visibility': overflow}); // Toggle visibility for all selects in the common document
486
+ },
487
+ event: function(eventName) {
488
+ if(this.options[eventName]) {
489
+ var returnValue = this.options[eventName](); // Executing callback
490
+ this.options[eventName] = null; // Removing callback after execution
491
+ if(returnValue != undefined)
492
+ return returnValue;
493
+ else
494
+ return true;
495
+ }
496
+ return true;
497
+ }
498
+ };
499
+
500
+ Object.extend(Modalbox, Modalbox.Methods);
501
+
502
+ if(Modalbox.overrideAlert) window.alert = Modalbox.alert;