/** * JCE Utilities 2.2.4 * * @version $Id: jceutilities.js 389 2009-10-08 15:18:30Z happynoodleboy $ * @package JCE Utilites * @copyright Copyright (C) 2006-2009 Ryan Demmer. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * */ /** * Based on the Mootools Tips class with additional options - position, opacity * Tooltip div is created when the first tooltip is initialized, not on page load * Changes to locate function allow tooltip to be positioned relative to the mouse pointer * @param {Object} tip */ var JCETips = new Class({ getOptions: function(){ return { onShow: function(tip){ tip.setStyle('visibility', 'visible'); }, onHide: function(tip){ tip.setStyle('visibility', 'hidden'); }, speed: 150, position: 'br', opacity: 0.8, className: 'tooltip', offsets: { 'x': 16, 'y': 16 }, fixed: false } }, /** * Initilize the class * @param {Array} elements Array of elements * @param {Object} options Options object */ initialize: function(elements, options){ this.setOptions(this.getOptions(), options); $$(elements).each(function(el){ el.addEvents({ 'mouseenter': this.start.bindWithEvent(this, el), 'mousemove': this.locate.bindWithEvent(this), 'mouseleave': this.end.bindWithEvent(this, el) }); }.bind(this)); }, /** * Create the tooltip div */ create : function() { if (!this.toolTip) { this.toolTip = new Element('div', { 'class': this.options.className, 'styles': { 'position': 'absolute', 'top': '0', 'left': '0', 'visibility': 'hidden' } }).injectInside($E('body')); } }, /** * Show the tooltip and build the tooltip text * @param {Object} e Event * @param {Object} el Target Element */ start: function(e, el){ this.create(); var text = el.title || '', title = ''; if(/::/.test(text)){ var parts = text.split('::'); title = parts[0].trim(); text = parts[1].trim(); } // Inherit parent classes var cls = el.className.replace(/(jce_?)tooltip/gi, ''); // Store original title and remove this.toolTip.title = el.title; $(el).setProperty('title', ''); this.toolTip.empty(); if (title){ this.title = new Element('h4').inject(this.toolTip).setHTML(title); } if (text){ this.text = new Element('p').inject(this.toolTip).setHTML(text); } $clear(this.timer); this.timer = this.show.delay(this.options.showDelay, this); }, end: function(event, el){ $clear(this.timer); el.setProperty('title', this.toolTip.title); this.timer = this.hide.delay(this.options.hideDelay, this); }, /** * Position the tooltip * @param {Object} e Event trigger */ locate : function(e){ this.create(); var o = this.options.offsets; var page = e.page; var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight}; var pos = {'x': page.x + o.x, 'y': page.y + o.y}; var ah = 0; switch(this.options.position){ case 'tl': pos.x = (page.x - tip.x) - o.x; pos.y = (page.y - tip.y) - (ah + o.y); break; case 'tr': pos.x = page.x + o.x; pos.y = (page.y - tip.y) - (ah + o.y); break; case 'tc': pos.x = (page.x - Math.round((tip.x / 2))) + o.x; pos.y = (page.y - tip.y) - (ah + o.y); break; case 'bl': pos.x = (page.x - tip.x) - o.x; pos.y = (page.y + Math.round((tip.y/2))) - (ah + o.y); break; case 'br': pos.x = page.x + o.x; pos.y = page.y + o.y; break; case 'bc': pos.x = (page.x - (tip.x/2)) + o.x; pos.y = page.y + ah + o.y; break; } $(this.toolTip).setStyles({ top: pos.y + 'px', left: pos.x + 'px' }); }, /** * Position the tooltip * @param {Object} element */ position: function(element){ var pos = element.getPosition(); this.toolTip.setStyles({ 'left': pos.x + this.options.offsets.x, 'top': pos.y + this.options.offsets.y }); }, /** * Execute the onShow function */ show: function(){ if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this); this.fireEvent('onShow', [this.toolTip]); }, /** * Execute the onHide function */ hide: function(){ this.fireEvent('onHide', [this.toolTip]); } }); JCETips.implement(new Events, new Options); /** * JCE Utilities Base Class */ var JCEUtilities = new Class({ getOptions : function(){ return { popup : { legacy : 0, //convert : 0, overlay : 1, overlayopacity : 0.8, overlaycolor : '#000000', resize : 1, icons : 1, fadespeed : 500, scalespeed : 500, hideobjects : 1, scrollpopup : 1, onclose : Class.empty }, tooltip : { className : 'tooltip', speed : 150, offsets : {x: 16, y : 16}, position : 'br', opacity : 0.8, background : '#000000', color : '#ffffff' }, theme : 'standard', themecustom : '', themepath : 'plugins/system/jceutilities/themes', //pngfix : 1, //wmode : 0, imgpath : 'plugins/system/jceutilities/img' }; }, /** * Get the site url from javascript source file * @return Site URL */ getSite : function(){ /*var s = $E('script[src*=jceutilities.js]').src; /* $ES('script[src*jceutilities.js').each(function(el){ if (/jceutilities\.js/.test(el.src)) { s = el.src; } });*/ /*s = s.substring(0, s.lastIndexOf('plugins/system/jceutilities/js')) || ''; if (/:\/\//.test(s)) { s = s.match(/.*:\/\/[^\/]+(.*)/)[1]; } var site = document.location.href; var parts = site.split(':\/\/'); var port = parts[0]; var url = parts[1]; return port + '://' + url.substr(0, url.indexOf(s)) + s;*/ }, /** * Initialise the Class * @param {Object} options Class options */ initialize : function(options){ this.setOptions(this.getOptions(), options); this.popup(); this.tooltip(); /*if(this.options.pngfix == 1 && window.ie6){ this._pngFix(); } if(options.wmode == 1){ this._wmodeFix(); }*/ return this; }, /** * Get client window width */ _getWidth: function(){ return document.documentElement.clientWidth || document.body.clientWidth || this.innerWidth || 0; }, /** * Get client window height */ _getHeight: function(){ return document.documentElement.clientHeight || document.body.clientHeight || this.innerHeight || 0; }, /** * Get client window scroll height */ _getScrollHeight: function(){ return document.documentElement.scrollHeight || document.body.scrollHeight || 0; }, /** * Get client window scroll width */ _getScrollWidth: function(){ return document.documentElement.scrollWidth || document.body.scrollWidth || 0; }, /** * Get client window scroll top */ _getScrollTop: function(){ return document.documentElement.scrollTop || this.pageYOffset || document.body.scrollTop || 0; }, /** * IE png fix */ _pngFix : function(){ var s, bg, site = this.getSite(); // Images $ES('img[src$=.png]', $E('body')).each( function(el) { $(el).setStyle('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + el.src + "', sizingMethod='')"); el.src = site + 'plugins/system/jceutilities/img/blank.gif'; }); // CSS Background Images $ES('*', $E('body')).each(function(el){ s = $(el).getStyle('background-image'); if(s && /\.png/i.test(s)){ bg = /url\("(.*)"\)/.exec(s)[1]; $(el).setStyle('background-image', 'none'); $(el).setStyle('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + bg + "',sizingMethod='')"); } }); }, /** * IE Wmode Fix */ _wmodeFix : function(){ $ES('object').each(function(el){ if(el.classid.toLowerCase() == 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' || el.type.toLowerCase() == 'application/x-shockwave-flash'){ if(!el.wmode || el.wmode.toLowerCase() == 'window'){ el.wmode = 'opaque'; if(typeof el.outerHTML == 'undefined'){ $(el).replaceWith($(el).clone(true)); }else{ el.outerHTML = el.outerHTML; } } } }); $ES('embed[type=application/x-shockwave-flash]').each(function(el){ var wm = $(el).getProperty('wmode'); if(!wm || wm.toLowerCase() == 'window'){ $(el).setProperty('wmode', 'opaque'); if(typeof el.outerHTML == 'undefined'){ $(el).replaceWith($(el).clone(true)); }else{ el.outerHTML = el.outerHTML; } } }); }, /** * Create a new tooltip using JCETips Class */ tooltip : function(){ new JCETips($ES('.jcetooltip, .jce_tooltip'), this.options.tooltip); }, /** * Convert legacy popups to new format */ convert : function(){ //this.site = this.getSite(); this.site = 'http://www.footefrancis.com.au/'; $ES('a[href*=com_jce]').each(function(el){ var p, s; s = this._cleanEvent($(el).getProperty('onclick')).replace(/&/g,'&').replace(/'/g,"'").split("'").filter(function(item, index){ return /\&/.test(item); }); p = this._params(s[0]); img = p['img'] || ''; title = p['title'] || ''; if(img) { if(!/http:\/\//.test(img)){ if(img.charAt(0) == '/'){ img = img.substr(1); } img = this.site.replace(/http:\/\/([^\/]+)/, '') + img; } el.setProperties({ 'href': img, 'title': title.replace(/_/, ' '), 'onclick': '' }).addClass('jcepopup').removeProperty('onclick'); } }.bind(this)); }, /** * Get the file type from the url, type attribute or className * @param {Object} el */ _getType : function(el) { if (/(youtube|videoplay|googleplayer|metacafe|vimeo|\.swf)/i.test(el.href)) { return 'flash'; } // Image if (/\.(jpg|jpeg|png|gif|bmp|tif)$/i.test(el.href)) { return 'image'; } if (/(director|windowsmedia|mplayer|quicktime|real|divx|flash)/.test(el.type)) { return /(director|windowsmedia|mplayer|quicktime|real|divx|flash)/.exec(el.type)[1]; } // Other from classname if (/(director|windowsmedia|mplayer|quicktime|real|divx|flash|iframe|ajax|image)/.test(el.className)) { return /(director|windowsmedia|mplayer|quicktime|real|divx|flash|iframe|ajax|image)/.exec(el.className)[1]; } return el.type || 'iframe'; }, /** * Get the page scrollbar width */ _getScrollbarWidth: function() { if (this.scrollbarWidth) { return this.scrollbarWidth; } var inner = new Element('div').setStyles({ width : '100%', height : 200, border : 0, margin : 0, padding : 0 }); var outer = new Element('div').setStyles({ position : 'absolute', visibility : 'hidden', width : 200, height : 200, border : 0, margin : 0, padding : 0, overflow : 'hidden' }).injectInside(document.body).adopt(inner); var w1 = parseInt(inner.offsetWidth); outer.style.overflow = 'scroll'; var w2 = parseInt(inner.offsetWidth); if(w1 == w2){ w2 = parseInt(outer.clientWidth); } outer.remove(); return (w1 - w2); }, /** * Clean an onclick event * Private function - Regular expression syntax from TinyMCE DOMUtils.js getAttrib function. Copyright (c) 2004-2008, Moxiecode Systems AB * @param {Object} s */ _cleanEvent : function(s) { return s.replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1'); }, /** * Process a parameter string into an object * @param {Object} s */ _params : function(s){ var a = [], x = []; if($type(s) == 'array') { x = s; } else { if (s.indexOf('&') != -1) { x = s.split(/&(amp;)?/g); } else { x = s.split(/;/g); } } x.each(function(n){ if (n) { n = n.replace(/^([^\[]+)(\[|=|:)([^\]]*)(\]?)$/, function(a, b, c, d){ if (d) { if (!/[^0-9]/.test(d)) { return '"' + b + '":' + parseInt(d); } return '"' + b + '":"' + d + '"'; } return ''; }); if (n) { a.push(n); } } }); return Json.evaluate('{' + a.join(',') + '}'); }, /** * Returns a styles object from a parameter * @param {Object} o */ _styles : function(o){ var v, s, x = []; if(!o) return {}; o.split(';').each(function(s){ s = s.replace(/(.*):(.*)/, function(a, b, c){ return "'" + b + "':'" + c + "'"; }); x.push(s); }); return Json.evaluate('{'+ x.join(',') +'}'); }, /** * IE6 PNG Fix * @param {Object} el */ _png : function(el){ var s; // If its an image if(el.nodeName == 'IMG'){ s = el.src; if(/\.png$/i.test(s)){ $(el).setProperty('src', this.site + 'plugins/system/jceutilities/img/blank.gif').setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + s + '\''); } }else{ s = $(el).getStyle('background-image'); if(/\.png/i.test(s)){ var bg = /url\("(.*)"\)/.exec(s)[1]; $(el).setStyles({'background-image': 'none', 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + bg + "')"}); } } }, /** * Create a popup zoom icon * @param {Object} el */ _zoom : function(el){ var s, m, x, y; var child = $E('img', el); var zoom = new Element('span'); if(child){ var w = $(child).getProperty('width') || $(child).getStyle('width') || 0; var h = $(child).getProperty('height') || $(child).getStyle('height') || 0; var align = $(child).getProperty('align'); var vspace = $(child).getProperty('vspace'); var hspace = $(child).getProperty('hspace'); var styles = { width : parseInt(w), height : parseInt(h) }; // Correct from deprecated align attribute if(align){ $extend(styles, { 'float' : /left|right/.test(align) ? align : '', 'text-align' : /top|middle|bottom/.test(align) ? align : '' }); } // Correct from deprecated vspace attribute if(vspace){ $extend(styles, { 'margin-top' : vspace + 'px', 'margin-bottom' : vspace + 'px' }); } // Correct from deprecated hspace attribute if(hspace){ $extend(styles, { 'margin-left' : hspace + 'px', 'margin-right' : hspace + 'px' }); } // Private internal function function _buildIcon(el, zoom, child, styles){ var lft, top, w = styles.width, h = styles.height; // Clone image as object element var span = new Element('span').setStyles($(child).style.cssText).setStyles(styles).adopt(child).adopt(zoom); // Remove (deprecated) attributes that may affect layout $each(['style', 'align', 'border', 'hspace', 'vspace'], function(s){ child.removeProperty(s); }); // Insert border if 0 if(parseInt(span.getStyle('border-width')) == 0) child.setStyle('border', 0); m = el.className.match(/icon-(top-right|top-left|bottom-right|bottom-left|left|right)/) || ['icon-right', 'right']; switch(m[1]){ case 'top-right': lft = w - 20; top = -h; break; case 'top-left': lft = 0; top = -h; break; default: case 'right': case 'bottom-right': lft = w - 20; top = - 20; break; case 'left': case 'bottom-left': lft = 0; top = -20; break; } $(zoom).setStyles({'margin-left': lft, 'margin-top': top}).addClass('zoom-image'); el.adopt(span); } // No dimensions? if(/^(0|auto)/.test(w) || /^(0|auto)/.test(h)){ x = new Image(); x.src = $(child).src; x.onload = function(){ $extend(styles, { width : parseInt(x.width), height : parseInt(x.height) }); _buildIcon(el, zoom, child, styles); } }else{ _buildIcon(el, zoom, child, styles); } }else{ $(zoom).addClass('zoom-link'); if(/icon-left/.test(el.className)){ $(zoom).injectTop(el); }else{ $(zoom).injectInside(el); } } if(window.ie6){ s = $(zoom).getStyle('background-image'); if(s && /\.png/i.test(s)){ s = /url\("(.+)"\)/.exec(s)[1]; $(zoom).setStyle('background-image', 'none'); $(zoom).setStyle('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + s + "')"); } }else{ $(zoom).setStyle('position', 'relative'); } }, /** * Create popups from links with trigger class */ popup : function(){ var t = this, auto = false; this.popups = [], this.popuptheme = '', this.site = 'http://www.footefrancis.com.au/'; // Converts a legacy (window) popup into an inline popup if(this.options.popup.legacy == 1){ this.convert(); } $ES('.jcebox, .jcelightbox, .jcepopup').each(function(el, i){ if(!el.hasClass('nopopup')){ // Create zoom icon if(this.options.popup.icons == 1 && el.nodeName == 'A' && !/(noicon|icon-none|noshow)/.test(el.className) && el.style.display != 'none'){ this._zoom(el); } // Hide popup link if specified in class if (el.hasClass('noshow')) { el.setStyle('display', 'none'); } var group = '', p = ''; // Auto popup on page load if (!auto && el.id) { //auto = el.hasClass('autopopup'); if(c = el.className.match(/autopopup-(single|multiple)/)) { auto = c[0]; } } // Fix title and rel and move parameters var title = el.title || ''; var rel = el.rel || ''; // Process title attribute if(title && /(\w+\[.*\])/.test(title)){ // get parameters p = this._params(title); $(el).setProperty('title', p.title || ''); group = p.group || ''; } // Process rel attribute if(rel && /(\w+\[.*\])/.test(rel)){ var args = []; rel = rel.replace(/\b((\w+)\[(.*?)\])(;?)/g, function(a, b, c){ args.push(b); return ''; }); // get parameters p = this._params(args); $(el).setProperty('rel', rel || p.rel || ''); group = p.group || ''; } else { var rx = 'alternate|stylesheet|start|next|prev|contents|index|glossary|copyright|chapter|section|subsection|appendix|help|bookmark|nofollow|licence|tag|friend'; var lb = '(lightbox(\[(.*?)\])?)'; var lt = '(lyte(box|frame|show)(\[(.*?)\])?)'; group = rel.replace(new RegExp('\s*(' + rx + '|' + lb + '|' + lt + ')\s*'), '', 'gi'); } // Get AREA parameters from URL if not set if(el.nodeName == 'AREA') { if (!p) { p = this._params(el.href); } // Set AREA group group = group || 'AREA_ELEMENT'; } // Popup object var o = { 'href' : el.href, 'title' : p.title || title, 'group' : el.hasClass('nogroup') ? '' : group, 'type' : p.type || t._getType(el), 'params' : p || {}, 'id' : el.id || '', 'auto' : auto }; // Add to global popups array this.popups.push(o); $(el).addEvent('click', function(e){ e = new Event(e); e.stop(); return this._start(o, i); }.bind(this)); // Reset auto popup value auto = false; } }.bind(this)); // Load the popup theme var theme = this.options.theme == 'custom' ? this.options.themecustom : this.options.theme; new Ajax(this.site + this.options.themepath + '/' + theme + '/popup.html', { method : 'get', onComplete : function(data){ var re = /([\s\S]*?)/; if(re.test(data)){ data = re.exec(data)[1]; } this.popuptheme = data; // Process auto popups this._auto(); }.bind(this) }).request(); }, /** * Public Function : Open a popup Example : jcepopup.open('http://www.joomlacontenteditor.net', 'JCE', 'joomla_sites', 'iframe', {width:800}); * @param {String} url * @param {String} title * @param {String} group * @param {String} type * @param {Object} params */ open : function(url, title, group, type, params){ var link = { 'href' : url, 'title' : title, 'group' : group, 'type' : type, 'params' : params }; this.popups.push(link); return this._start(link); }, /** * Process autopopups */ _auto : function() { this.popups.each(function(el){ if(el.auto) { if(el.auto == 'autopopup-single') { var cookie = Cookie.get('jceutilities_autopopup_' + el.id); if (!cookie) { Cookie.set('jceutilities_autopopup_' + el.id, 1); this._start(el); } } else if(el.auto == 'autopopup-multiple') { this._start(el); } } }.bind(this)); }, /** * Build Popup structure */ _build : function(){ var t = this; this.page = new Element('div', { id : 'jcepopup-page' }).injectInside(document.body); if(this.options.popup.overlay == 1){ this.overlay = new Element('div', { 'id' : 'jcepopup-overlay', styles : { opacity : '0', 'background-color': this.options.popup.overlaycolor }, events : { click : function(){ this.close(); }.bind(this) } }).injectInside(this.page); } this.frame = new Element('div', { id : 'jcepopup-frame' }).injectInside(this.page); if(window.ie6 || !this.options.popup.scrollpopup){ $(this.overlay).setStyle('height', this._getScrollHeight()); $(this.page).setStyle('position', 'absolute').setStyle('top', this._getScrollTop()); } // Default theme layout if(!this.popuptheme){ this.popuptheme = '
' + title + '
'; if (/::/.test(title)) { var parts = title.split('::'); caption = '' + parts[1] + '
'; } } $(this.caption).setHTML(caption).setStyle('display', ''); } // Optional Element //if(this.nav){ var html = '', i, len = this.items.length; if(len > 1){ for(i=0; i