/[drupal]/contributions/modules/craqbox/craqbox.js
ViewVC logotype

Contents of /contributions/modules/craqbox/craqbox.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Apr 12 09:50:14 2007 UTC (2 years, 7 months ago) by unconed
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5
Changes since 1.1: +117 -92 lines
File MIME type: text/javascript
- Code clean-up
- Feature: auto-attach to image nodes (added support for link redirects to Craqbox.js)
- Feature: get Craqbox title from image tag inside link if link has none.
- Hide empty auto-attach settings fieldset
1 // $Id: craqbox.js,v 1.1 2007/04/12 08:16:15 stevemckenzie Exp $
2
3 // Avoid colliding with a global '$' variable.
4 (function($) {
5 /**
6 * Chainable jQuery method $(...).craqbox(...).
7 */
8 $.fn.craqbox = function(o) {
9 $.craqbox(this, o);
10 return this;
11 };
12
13 /**
14 * Static jQuery method $.craqbox(...) that returns the Craqbox object.
15 */
16 $.craqbox = function(a, o) {
17 a = $(a).get(0);
18
19 return a.craqbox || (a.craqbox = new $._craqbox(a, o));
20 };
21
22 /**
23 * Private constructor for the Craqbox object.
24 */
25 $._craqbox = function(a, o) {
26 var cb = this;
27
28 // Configurable options for craqbox.
29 var defaults = {
30 attachEvent: 'click',
31 animation: { opacity: 'toggle' }, // TODO: implement.
32 cacheKey: null,
33 closeButtonLabel: 'x',
34 closeButtonTitle: 'Close',
35 closeButtonClass: 'close_button',
36 closeButtonContainerClass: 'close_button_container',
37 completeCallback: function() { },
38 content: null,
39 contentClass: 'content',
40 craqboxId: 'craqbox',
41 dragable: true,
42 ease: 'easein', // TODO: implement.
43 heading: 3,
44 hiderClass: 'craqbox_hider',
45 hiderOpacity: 0.5,
46 hiderSpeed: 'fast',
47 horizontalAlign: true,
48 iframeBorder: 0,
49 iframeClass: 'frame_class',
50 iframeScroll: 'no',
51 inSpeed: 'normal',
52 links: {},
53 outSpeed: 'fase',
54 padding: 10,
55 removeCallback: function() { },
56 title: null,
57 titleBar: true,
58 titleBarClass: 'title_bar',
59 type: 'iframe', // iframe / image / dom / html
60 url: null,
61 width: 700,
62 verticalAlign: false
63 };
64
65 // Create options object.
66 cb.o = $.extend(defaults, o || {});
67
68 /**
69 * Absolute position of an element.
70 */
71 cb.absolutePosition = function(el) {
72 var left = 0;
73 var top = 0;
74 el = $(el)[0];
75 while (el.offsetParent) {
76 left += el.offsetLeft;
77 top += el.offsetTop;
78 el = el.offsetParent;
79 }
80 left += el.offsetLeft;
81 top += el.offsetTop;
82 return { x:left, y:top };
83 };
84
85 /**
86 * Build the content for the appropriate type.
87 */
88 cb.build = function(newOptions) {
89 // Update options.
90 cb.o = $.extend(cb.o, newOptions || {});
91 // Setup content cache.
92 cb.cache = cb.cache || [];
93 // Build our content.
94 var content = '';
95 // The key to use for caching the content.
96 var key;
97 switch (cb.o.type) {
98 case 'iframe':
99 key = cb.o.cacheKey || cb.o.url || a.href;
100 var src = cb.o.url || cb.o.links[a.href] || a.href;
101 if (!src) {
102 return false;
103 }
104 if (!cb.cache[key]) {
105 content = $('<iframe>').attr({
106 src: src,
107 iframeborder: cb.o.iframeBorder,
108 scrolling: cb.o.iframeScroll,
109 className: cb.o.iframeClass
110 });
111 cb.cache[key] = content;
112 }
113 else {
114 content = cb.cache[key];
115 }
116 break;
117 case 'image':
118 key = cb.o.cacheKey || cb.o.url || a.href;
119 console.log('key: '+ key);
120 var src = cb.o.url || cb.o.links[a.href] || a.href;
121 if (!src) {
122 return false;
123 }
124 cb.o.title = cb.o.title || ($(a).attr('title') || $('img[@title]', a).attr('title'));
125 console.log('title: '+ cb.o.title);
126 if (!cb.cache[key]) {
127 content = $('<img>').attr({ src: src, alt: a.title || key });
128 cb.cache[key] = content;
129 }
130 else {
131 content = cb.cache[key];
132 }
133 break;
134 case 'dom':
135 if (cb.o.cacheKey && !cb.cache[cb.o.cacheKey]) {
136 content = $(cb.o.content);
137 cb.cache[cb.o.content] = content;
138 }
139 else if (cb.o.cacheKey && cb.cache[cb.o.cacheKey]) {
140 content = $(cb.cache[cb.o.content]);
141 }
142 else {
143 content = $(cb.o.content);
144 }
145 content = $(cb.o.content);
146 break;
147 case 'html':
148 key = cb.o.cacheKey || a.href;
149 if (!cb.cache[key]) {
150 if (cb.o.url) {
151 $('#'+ cb.o.craqboxId +' .'+ cb.o.contentClass).addClass('craqbox_spinner');
152 $.get(cb.o.url, function(data) {
153 $('#'+ cb.o.craqboxId +' .'+ cb.o.contentClass).removeClass('craqbox_spinner');
154 content = $('<div>').html(data);
155 cb.cache[key] = content;
156 cb.show(content);
157 });
158 }
159 else if (cb.o.content) {
160 content = cb.o.content;
161 cb.cache[key] = content;
162 }
163 else {
164 return false;
165 }
166 }
167 else {
168 content = cb.cache[key];
169 }
170 break;
171 }
172 // Display a craqbox if we have content.
173 if (content) {
174 cb.show(content);
175 }
176
177 return cb;
178 };
179
180 /**
181 * Center the craqbox.
182 */
183 cb.center = function(x, y) {
184 var c = $('#'+ cb.o.craqboxId);
185 if (!x) {
186 x = 0;
187 }
188 if (!y) {
189 y = 0;
190 }
191 if (cb.o.verticalAlign) {
192 var h = self.innerHeight || document.documentElement.clientHeight || $('body')[0].clientHeight || 0;
193 c.css('top', ((h - $('#'+ cb.o.craqboxId).height()) / 2 + y) +'px');
194 }
195 else {
196 c.css('top', (cb.o.padding) +'px');
197 }
198 if (cb.o.horizontalAlign) {
199 c.css('left', (($(document.body).width() - cb.o.width) / 2 + x) +'px');
200 }
201 else {
202 c.css('left', (cb.o.padding) +'px');
203 }
204 // Reset the hiders size.
205 cb.hider();
206 };
207
208 /**
209 * Background shader.
210 */
211 cb.hider = function(toggle) {
212 var yScroll;
213 var xScroll;
214
215 // Handle finding the proper document.body size so we can "hide" the content.
216 // All the cool browsers.
217 if (window.innerHeight && window.scrollMaxY || window.innerWidth && window.scrollMaxX) {
218 yScroll = window.innerHeight + window.scrollMaxY;
219 xScroll = window.innerWidth + window.scrollMaxX;
220 var deff = document.documentElement;
221 var wff = (deff && deff.clientWidth) || document.body.clientWidth || window.innerWidth || self.innerWidth;
222 var hff = (deff && deff.clientHeight) || document.body.clientHeight || window.innerHeight || self.innerHeight;
223 xScroll -= (window.innerWidth - wff);
224 yScroll -= (window.innerHeight - hff);
225 }
226 // All other Explorers.
227 else if (document.body.scrollHeight > document.body.offsetHeight || document.body.scrollWidth > document.body.offsetWidth) {
228 yScroll = document.body.scrollHeight;
229 xScroll = document.body.scrollWidth;
230 }
231 // Explorer 6 Strict.
232 else {
233 yScroll = document.body.offsetHeight;
234 xScroll = document.body.offsetWidth;
235 }
236 // Hide the hider.
237 if (toggle == 'hide') {
238 $('#'+ cb.o.craqboxId +'_hider').fadeOut(cb.hiderSpeed, function() {
239 $('#'+ cb.o.craqboxId +'_hider').removeClass('visible');
240 });
241 }
242 // Display the hider.
243 else {
244 // Make the site fade out a little.
245 if ($('#'+ cb.o.craqboxId +'_hider').length > 0) {
246 // Remove old click event to get new removeCallback() in cb.remove.
247 $('#'+ cb.o.craqboxId +'_hider')
248 .unbind('click')
249 .bind('click', cb.remove)
250 .css({ width: xScroll +'px', height: (document.body.offsetHeight) +'px' });
251 // Fade back in if not visible.
252 if (!$('#'+ cb.o.craqboxId +'_hider').is('.visible')) {
253 $('#'+ cb.o.craqboxId +'_hider').fadeTo(cb.o.hiderSpeed, cb.o.hiderOpacity, function() {
254 $('#'+ cb.o.craqboxId +'_hider').addClass('visible');
255 });
256 }
257 }
258 else {
259 // Create the hider.
260 $('<div>')
261 .attr('id', cb.o.craqboxId +'_hider')
262 .css({opacity: 0, width: xScroll +'px', height: (document.body.offsetHeight) +'px' })
263 .click(cb.remove)
264 .appendTo(document.body)
265 .fadeTo(cb.o.hiderSpeed, cb.o.hiderOpacity, function() { $(this).addClass('visible') });
266 }
267 }
268 };
269
270 /**
271 * Fix browser issues.
272 * - embeds / objects / selects in IE 6 have zIndex issues.
273 * - selects in Firefox do weird things with multiple = true;
274 */
275 cb.hiderFixes = function(state) {
276 $('object, embed, select').css('display', (state == 'off') ? 'block' : 'none');
277 };
278
279 /**
280 * Remove a craqbox.
281 */
282 cb.remove = function(event) {
283 $(window).unbind('scroll', cb.scroll).unbind('resize', cb.scroll);
284 $('#'+ cb.o.craqboxId).fadeOut(cb.o.outSpeed, function() {
285 // Remove old content.
286 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).children().remove();
287 // Remove browser fixes for hider.
288 cb.hiderFixes('off');
289 // Process removeCallback().
290 cb.o.removeCallback();
291 });
292 cb.hider('hide');
293
294 return false;
295 };
296
297 /**
298 * Make craqbox scroll with the window scrollbar.
299 */
300 cb.scroll = function(event) {
301 var yScrollTop;
302 var xScrollLeft;
303
304 // Handle grabbing the proper scroll values for each browser.
305 // All the cool browsers.
306 if (self.pageYOffset || self.pageXOffset) {
307 yScrollTop = self.pageYOffset;
308 xScrollLeft = self.pageXOffset;
309 }
310 // Explorer 6 Strict.
311 else if (document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft ) {
312 yScrollTop = document.documentElement.scrollTop;
313 xScrollLeft = document.documentElement.scrollLeft;
314 }
315 // All other Explorers.
316 else if (document.body) {
317 yScrollTop = document.body.scrollTop;
318 xScrollLeft = document.body.scrollLeft;
319 }
320
321 // Position craqbox.
322 cb.center(xScrollLeft, yScrollTop);
323 };
324
325 /**
326 * Display the content.
327 */
328 cb.show = function(content) {
329 // Do a few fixes because of weird browser issues with zIndex.
330 cb.hiderFixes();
331 // Display the hider.
332 cb.hider();
333 // Only redraw our Craqbox if we need to.
334 if ($('#'+ cb.o.craqboxId).length > 0) {
335 // Set the title.
336 if (cb.o.title) {
337 $('#'+ cb.o.craqboxId + ' h'+ cb.o.heading).html(cb.o.title);
338 }
339 // Reset the close button event to get the proper removeCallback().
340 $('#'+ cb.o.craqboxId +' .'+ cb.o.closeButtonClass).unbind('click').bind('click', cb.remove);
341 if ($('#'+ cb.o.craqboxId +'_hider').is('.visible')) {
342 // Fade out the old content first.
343 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).fadeOut(cb.o.outSpeed, function() {
344 // TODO: this is currently used to fix a bug with jQuery calling the completeCallback on this fadeOut twice.
345 var faded = $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).attr('faded');
346 if (!faded || faded == 0) {
347 // Remove old content.
348 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).children().remove();
349 // Show new content.
350 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass)
351 .append(content)
352 .fadeIn(cb.o.inSpeed, function() {
353 cb.center();
354 cb.o.completeCallback();
355 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).attr('faded', 0);
356 });
357
358 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).attr('faded', 1);
359 }
360 });
361 }
362 else {
363 $('#'+ cb.o.craqboxId).fadeTo(cb.o.inSpeed, 1.0);
364 // Show new content.
365 $('#'+ cb.o.craqboxId + ' .'+ cb.o.contentClass).append(content).fadeIn(cb.o.inSpeed, function() {
366 cb.center();
367 cb.o.completeCallback();
368 });
369 }
370
371 }
372 // Create Craqbox UI.
373 else {
374 // Hide the site a bit with a "shader".
375 cb.hider();
376
377 // Create a close button.
378 var closeButton = $('<a>')
379 .attr({ title: cb.o.closeButtonTitle, className: cb.o.closeButtonClass, href: '#close' })
380 .html(cb.o.closeButtonLabel)
381 .click(function() { cb.remove(); return false; });
382
383 // Add a title bar.
384 if (cb.o.titleBar) {
385 var titleBar = $('<div>')
386 .addClass(cb.o.titleBarClass)
387 .append($('<div>').addClass(cb.o.closeButtonContainerClass).append(closeButton));
388
389 // Add drag and drop support.
390 if (cb.o.dragable) {
391 var mouseMove = function(event) {
392 // Only support dragging on holding the title bar.
393 if (event.target == $('#'+ cb.o.craqboxId +' .'+ cb.o.titleBarClass)[0]) {
394 /* TODO: get this working.
395 var craqbox = $('#'+ cb.o.craqboxId);
396 var p = cb.absolutePosition(craqbox);
397 craqbox.css({top: (event.clientY - p.y) +'px', left: (event.clientX - p.x) +'px' });
398 */
399 }
400
401 return false;
402 };
403 var mouseDown = function() { $(document).bind('mousemove', mouseMove); };
404
405 $(document)
406 .bind('mousedown', mouseDown)
407 .bind('mouseup', function(event) { $(document).unbind('mousemove', mouseMove); });
408 }
409
410 if (cb.o.title) {
411 $('<h'+ cb.o.heading +'>').addClass('title').html(cb.o.title).appendTo(titleBar);
412 }
413 }
414
415 // Display the container.
416 $('<div>')
417 .attr('id', cb.o.craqboxId)
418 .css({ width: cb.o.width +'px' })
419 .append(titleBar ? $(titleBar) : closeButton)
420 .hide()
421 .appendTo(document.body);
422
423 // Display the content.
424 $('<div>')
425 .addClass(cb.o.contentClass)
426 .append(content).hide().appendTo($('#'+ cb.o.craqboxId)).fadeIn(cb.o.inSpeed, function() {
427 cb.o.completeCallback();
428 });
429 // Center and display our results to the screen.
430 cb.center();
431 $('#'+ cb.o.craqboxId).fadeTo(cb.o.inSpeed, 1.0);
432 }
433 // Bind the scroll event to the window.
434 $(window).bind('scroll', cb.scroll).bind('resize', cb.scroll);
435 };
436
437 // Attach the Craqbox.
438 if (cb.o.attachEvent) {
439 $(a).bind(cb.o.attachEvent, function() { cb.build(); return false; });
440 }
441
442 return cb;
443 };
444 })(jQuery);

  ViewVC Help
Powered by ViewVC 1.1.2