var Modalbox = new Class({
Implements: [Options, Events],
options: {
customclass: 'ig-modaltype-default',
width: null,
height: null,
position: {
'absolute': {}
},
title: '',
titleClass:'',
showtitle: true,
closetext: "",
top: 0,
left: 0,
zindex: null,
modalpadding: 10,
adopt: null,
adoptclone: null,
ismodal: true,
draggable: false,
fadein: true,
fadeout: true,
blanketcolor: '#000',
blanketopacity: 0.6,
shadowcolor: '#000000',
shadowopacity: 0.7,
shadowwidth: 4,
defaultfocus: null,
preventScrolling: false,
onOpen: Class.empty,
onClose: Class.empty,
onBeforeClose: Class.empty,
onAdopt: Class.empty,
onBeforeAdopt: Class.empty,
onSetContents: Class.empty,
onBeforeSetContents: Class.empty,
onAdoptClone: Class.empty,
onBeforeAdoptClone: Class.empty,
onBeforeDrag: Class.empty,
onStartDrag: Class.empty,
onDrag: Class.empty,
onDragComplete: Class.empty,
reusable: false
},
initialize: function(options) {
var self = this;
this.setOptions(options);
this.randguid = Math.floor(Math.random() * 1000000000);
this.displayed = false;
// Absolute position modals
if (options.position && options.position.absolute) {
this.options.position = options.position;
this.options.preventScrolling = false;
this.toppos = null;
}
/* disable window scrolling! */
if (this.options.preventScrolling) {
this.bodyoverflow = $(document.body).getStyle('overflow');
$(document.body).setStyle('overflow', 'hidden');
}
if (this.options.closetext == "") {
this.options.closetext = window.translations('media-js-Close');
}
// create the popup container. This is an invisible div at the bottom of the
this.mymodalcontainer = new Element('div', {
'class': 'mymodalcontainer'
});
this.mymodalcontainer.inject(document.body, 'bottom');
/* create the main modal element */
this.mymodal = new Element('div', {
'id': this.randguid + 'mymodal',
'class': 'modalcontainer'
}).inject(this.mymodalcontainer, 'bottom');
if (this.options.zindex) {
this.mymodal.setStyle('z-index', this.options.zindex);
}
if (!Igloo.thismodal) {
Igloo.thismodal = new Hash();
}
Igloo.thismodal[this.randguid + 'mymodal'] = this;
/* create the "front" element, so called because it is in front of the shadow */
this.mymodalfront = new Element('div', {
'id': this.randguid + 'mymodalfront',
'class': 'modalfront'
});
if (this.options.width) {
this.mymodalfront.setStyle('width', this.options.width);
}
if (this.options.height) {
this.mymodalfront.setStyle('height', this.options.height);
}
this.mymodalfront.addClass(this.options.customclass);
this.mymodalfront.setStyle('opacity', 0);
this.mymodalfront.inject(this.mymodal, 'top');
/* create the "shadow" element */
this.mymodalshad = new Element('div', {
'id': this.randguid + 'mymodalshad',
'class': 'modalshadow'
});
this.mymodalshad.inject(this.mymodal, 'top');
this.mymodalshad.setStyle('opacity', 0);
if (this.options.shadowcolor) {
this.mymodalshad.setStyle('background-color', this.options.shadowcolor);
}
/* create the "title" element */
if (this.options.showtitle) {
this.titlepart = new Element('div', { 'id': this.randguid + 'titlepart', 'class': 'modaltitle ' + this.options.titleClass });
/* create the "close" element */
/* create the "title message" element */
this.titlemessage = new Element('h1', {
'id': this.randguid + 'titlemessage',
'class': 'heading2'
}).inject(this.titlepart);
this.titlemessagespan = new Element('span', {
'id': this.randguid + 'title'
}).set('html', this.options.title).inject(this.titlemessage);
this.closebuttonspan = new Element('span', {
'class': 'meta'
}).inject(this.titlemessage);
this.closebutton = new Element('a', {
'id': this.randguid + 'closebutton',
'class':'closebutton'
}).set('html', this.options.closetext).inject(this.closebuttonspan);
this.titlepart.inject(this.mymodalfront);
this.closebutton.addEvent('click', function(e) {
self.close();
delete self.mymodal;
return false;
});
} else {
this.closebuttonspan = new Element('span',{'class':'meta'});
//this.closebuttonspan.inject(this.titlemessage);
this.closebutton = new Element('a',{
'id':this.randguid + 'closebutton',
'class':'modalclose closebutton'
}).set('html',this.options.closetext);
this.closebutton.inject(this.closebuttonspan);
this.closebuttonspan.inject(this.mymodalfront);
this.closebutton.addEvent('click', function(){
self.close();
delete self.mymodal;
return false;
});
}
//the esc key handler for closing the modal
document.addEvent('keyup', function(event){
if (event.key == 'esc' && self.displayed){
var targetTag = ($(event.target).tagName) ? $(event.target).tagName.toLowerCase() : "";
if (targetTag != 'input' && targetTag != 'textarea'){ //if it's not an input...
if(self.close){
self.close(); //close the modal
delete self.mymodal;
}
return false;
} else {
$(event.target).blur(); //lose focus from the input
return false;
}
}
});
/* create the "body" element */
this.bodypart = new Element('div', {
'id': this.randguid + 'bodypart',
'class': 'modalbody'
});
this.bodypart.inject(this.mymodalfront, 'bottom');
if (this.options.ismodal) {
if ($('blanket')) {
// there already is a blanket. no need to create another.
this.blanket = $('blanket');
// a blanket exists
if (this.blanket.boxes) {
this.blanket.boxes++;
} else {
this.blanket.boxes = 1;
}
} else {
this.blanket = new Element('div', {
'id': 'blanket',
'class': 'modalblanket'
}).setStyle('opacity', 0);
/* set the blanket color */
if (this.options.blanketcolor) {
this.blanket.setStyle('background-color', this.options.blanketcolor);
}
/* inject the blanket*/
this.blanket.inject(this.mymodalcontainer, 'top');
// set up an array, so the blanket knows how many boxes are keeping it "on".
// an array? Really? We never access anything in the array, so we just need an int counter.
this.blanket.boxes = 1;
if (this.options.fadein) {
var fadefxblanket = new Fx.Tween(this.blanket, {
duration: 200
}).start('opacity', this.options.blanketopacity);
// Sets the height for the blanket to work on computers and mobile
var pageHeight = $('page').getSize();
this.blanket.setStyles({ 'height': pageHeight.y + screen.height , 'width': '105%' });
fadefxblanket = {};
} else {
this.blanket.setStyle('opacity', 1);
}
}
}
if (this.options.fadein) {
var fadefxfront = new Fx.Tween(this.mymodalfront, {
duration: 210
});
var fadefxshad = new Fx.Tween(this.mymodalshad, {
duration: 200
});
fadefxfront.addEvent('complete', function() {
self.displayed = true;
});
fadefxshad.start('opacity', self.options.shadowopacity).chain(function() {
if (self.options.defaultfocus) {
if (self.bodypart.getElement(self.options.defaultfocus)) {
self.bodypart.getElement(self.options.defaultfocus).select();
}
}
});
fadefxfront.start('opacity', 1);
} else {
this.mymodalfront.setStyle('opacity', 1);
this.mymodalshad.setStyle('opacity', this.options.blanketopacity);
self.displayed = true;
}
/* draggable */
if (this.options.draggable) {
// if there is a title part, it is the handle
if (this.options.showtitle) {
this.mymodal.makeDraggable({ 'handle': this.titlepart });
this.titlepart.setStyle('cursor', 'move');
} else {
this.mymodal.makeDraggable({ 'handle': this.mymodal });
this.mymodal.setStyle('cursor', 'move');
}
}
if (this.options.adoptclone) {
this.adoptclone(this.options.adoptclone);
}
if (this.options.adopt) {
this.adopt(this.options.adopt);
}
this.adjustposition();
this.fireEvent('onOpen');
},
close: function() {
var self = this;
this.displayed = false;
this.fireEvent('onBeforeClose');
document.fireEvent('modalClose');
// see if we should be removing the blanket
var killblanket = false;
if (this.blanket) {
if (this.blanket.boxes) {
this.blanket.boxes--;
// after removing this one, are there any left?
if (this.blanket.boxes == 0) {
killblanket = true;
}
}
}
if (this.options.fadeout && !Browser.ie8) {
this.fadefxfront = new Fx.Tween(this.mymodalfront, {
duration: 200
});
if ($('blanket')) {
if (killblanket) {
var fadefxblanket = new Fx.Tween($('blanket'), {
duration: 200
}).start('opacity', 0);
}
}
this.fadefxfront.start('opacity', 0);
if (this.options.adopt) {
this.mymodalcontainer.adopt(this.options.adopt);
this.options.adopt.addClass('hide');
}
this.fireEvent('onClose');
} else {
if (!this.isclone && this.options.adopt) {
this.options.adopt.inject(this.mymodalcontainer, 'top');
this.options.adopt.addClass('hide');
}
this.fireEvent('onClose');
}
if ($('blanket') && killblanket) {
$('blanket').destroy();
delete this.blanket;
}
if (!this.options.reusable) {
if ($(this.mymodal)) {
$(this.mymodal).destroy();
}
if ($(this.mymodalcontainer)) {
$(this.mymodalcontainer).destroy();
}
} else {
if ($(this.mymodal)) {
$(this.mymodal).addClass('hide');
}
if ($(this.mymodalcontainer)) {
$(this.mymodalcontainer).addClass('hide');
}
}
if (this.options.preventScrolling) {
$(document.body).setStyle('overflow', this.bodyoverflow);
}
window.removeEvents('keyup'); // this removes the keyup listened for "esc"
delete self;
if (Igloo.thismodal[this.randguid + 'mymodal']) {
delete Igloo.thismodal[this.randguid + 'mymodal'];
}
// if there were any validation popups, we need to make sure they go away.
var valPops = $$('.ig-form-validation-popup');
if (valPops.length > 0) {
valPops.each(function (pop) {
pop.destroy();
});
}
},
setcontents: function(content) {
this.fireEvent('onBeforeSetContents');
if(typeOf(content) == 'element') {
// it's an element.
this.bodypart.adopt(content);
} else {
// it is probably a string. This is mostly for backwards compatability.
this.bodypart.innerHTML = content;
}
this.adjustposition();
this.fireEvent('setContents');
},
settitle: function(title) {
if (this.titlemessagespan) {
this.titlemessagespan.set('html', title);
}
},
adopt: function(elem) {
elem = $(elem);
this.isclone = false;
elem.removeClass('hide');
this.fireEvent('onBeforeAdopt');
this.bodypart.empty();
this.bodypart.adopt(elem);
this.adjustposition();
this.fireEvent('onAdopt');
},
adoptclone: function(elem) {
elem = $(elem);
this.isclone = true;
this.fireEvent('onBeforeAdoptClone');
var inic = elem;
// clone the adopt node, with events attached
var clone = inic.clone();
clone.removeClass('hide');
if (inic.id) {
clone.id = this.randguid + inic.id;
}
var ein = inic.getElementsByTagName('*');
var eout = clone.getElementsByTagName('*');
for (var i = 0; i < ein.length; i++) {
// set the id of the clone to something predictably different from the original
if (ein[i].id) {
var tempid = ein[i].id;
eout[i].id = this.randguid + tempid;
}
if (ein[i].attributes.getNamedItem('for')) {
var tempfor = ein[i].attributes.getNamedItem('for').value;
var forAttribute = document.createAttribute('for')
forAttribute.value = this.randguid + tempfor;
eout[i].attributes.setNamedItem(forAttribute);
}
eout[i].onclick = ein[i].onclick;
eout[i].onmouseover = ein[i].onmouseover;
eout[i].onmouseout = ein[i].onmouseout;
eout[i].onfocus = ein[i].onfocus;
eout[i].onsubmit = ein[i].onsubmit;
eout[i].onblur = ein[i].onblur;
eout[i].onkeyup = ein[i].onkeyup;
eout[i].className = ein[i].className;
eout[i].dataobj = ein[i].dataobj;
if (eout[i].isvalid) {
eout[i].isvalid.length = 0;
}
}
clone.inject(this.bodypart, 'top');
// apply the validation functions to elements that need them
if (typeof (applyvalidators) == 'function') { applyvalidators(clone); }
// and finally, apply behaviours to the form
if (typeof (applyformvalidation) == 'function') { applyformvalidation(clone); }
if (typeof (Utils.jstrimspace) == 'function') {
Utils.jstrimspace();
}
this.adjustposition();
this.fireEvent('onAdoptClone');
},
adjustposition: function() {
if (!this.mymodal) {
return false;
}
var containerbounds = {
'width': Window.getWidth(),
'height': Window.getHeight(),
'top': Window.getScrollTop(),
'left': Window.getScrollLeft(),
'right': Window.getScrollLeft() + Window.getWidth(),
'bottom': Window.getScrollTop() + Window.getHeight()
}
if (this.options.height) {
containerbounds['height'] = this.options.height;
}
if (this.options.position.absolute) {
// this centers the modal on the page
$(this.mymodal).setStyles({
'position':'absolute',
'left':(Window.getWidth() / 2)+'px',
'margin-left':'-'+($(this.mymodalfront).getSize()['x'] / 2)+'px'
});
// make sure the top never goes above the top of the screen
var modalheight = $(this.mymodalfront).getSize()['y']; // the height of our modal with all it's contents
var windowheight = Window.getHeight(); // the height of the browser window
var toppos = Window.getScrollTop(); // we always wanna keep in mind the position of the scrollbar
if (this.options.position.absolute.top) {
toppos += this.options.position.absolute.top;
} else {
if (modalheight < windowheight) { // but if the modal can comfortably fit inside the window, without scrolling
toppos += (Math.floor(windowheight / 2) - Math.floor(modalheight / 2)); // then we can position the modal in the center of the window
} else { // otherwise
toppos += 60; // we'll position the modal this far from the top of the window
}
}
this.toppos = toppos;
var modalwidth = ($(this.mymodalfront).getSize()['x'] + this.options.shadowwidth);
$(this.mymodal).setStyles({
'top':this.toppos,
'width':modalwidth
});
}
if (this.options.position.screen) {
// this centers the modal on the page
$(this.mymodal).setStyle('left', (Math.floor(Window.getWidth() / 2) - ($(this.mymodalfront).getSize()['x'] / 2)));
// make sure the top never goes above the top of the screen
var toppos = (Math.floor(Window.getHeight() / 2) - ($(this.mymodalfront).getSize()['y'] / 2));
var modalheight = ($(this.mymodalfront).getSize()['y'] + this.options.shadowwidth);
var modalwidth = ($(this.mymodalfront).getSize()['x'] + this.options.shadowwidth);
$(this.mymodal).setStyles({
'top': toppos <= this.options.shadowwidth ? this.options.shadowwidth : toppos,
'width':modalwidth
});
// make sure the top never goes above the top of the screen
if (modalheight > containerbounds['height']) {
$(this.mymodalfront).setStyle('height', containerbounds['height'] - this.options.shadowwidth * 2);
this.bodypart.setStyle('height', containerbounds['height'] - this.options.shadowwidth * 2 - this.titlepart.getSize()['y'] - this.options.modalpadding * 2);
this.bodypart.setStyle('overflow', 'auto');
} else {
$(this.mymodal).setStyle('height', modalheight);
}
}
if (this.options.position.align) {
var alignelement = this.options.position.align.element;
var alignelementbounds = alignelement.getCoordinates();
// this is a really dumbed-down attempt which will later be replaced by some more robust alignment options
$(this.mymodal).setStyles({
'position':'absolute',
'width':($(this.mymodalfront).getSize()['x'] + this.options.shadowwidth),
'height':($(this.mymodalfront).getSize()['y'] + this.options.shadowwidth)
});
var popupsize = $(this.mymodal).getCoordinates();
if (popupsize['width'] > (containerbounds['width'] - alignelementbounds['right'])) {
if (popupsize['height'] > (containerbounds['height'] - (alignelementbounds['bottom'] - Window.getScrollTop()))) {
$(this.mymodal).setStyles({
'left':alignelementbounds['left'] - popupsize['width'] + this.options.shadowwidth
});
$(this.mymodal).setStyle('top', alignelementbounds['bottom'] - popupsize['height'] + this.options.shadowwidth);
} else {
$(this.mymodal).setStyles({
'left':alignelementbounds['left'] - popupsize['width'] + this.options.shadowwidth,
'top':alignelementbounds['top'] + this.options.shadowwidth
});
$(this.mymodal).setStyle();
}
} else {
if (popupsize['height'] > (containerbounds['height'] - (alignelementbounds['top'] - Window.getScrollTop()))) {
$(this.mymodal).setStyles({
'left':alignelementbounds['right'] + this.options.shadowwidth,
'top':alignelementbounds['bottom'] - popupsize['height']
});
} else {
$(this.mymodal).setStyles({
'left':alignelementbounds['right'] + this.options.shadowwidth,
'top':alignelementbounds['top'] + this.options.shadowwidth
});
}
}
}
// set the shadow size
$(this.mymodalshad).setStyles({
'width':(this.mymodalfront.getSize()['x']) + (this.options.shadowwidth * 2),
'height':(this.mymodalfront.getSize()['y']) + (this.options.shadowwidth * 2),
'top':(this.options.shadowwidth * -1),
'left':(this.options.shadowwidth * -1)
});
}
});
// Create a new Document object. If no arguments are specified,
//* the document will be empty. If a root tag is specified, the document
//* will contain that single root tag. If the root tag has a namespace
//* prefix, the second argument must specify the URL that identifies the
//*namespace.
IglooXML = {
toString:function(xmldoc){
if (xmldoc.xml){
return xmldoc.xml;
}else{
var s = new XMLSerializer();
var doc = xmldoc;
var str = s.serializeToString(doc);
return str;
}
},
newDocument:function(rootTagName, namespaceURL) {
if (!rootTagName) rootTagName = "";
if (!namespaceURL) namespaceURL = "";
if (document.implementation && document.implementation.createDocument) {
// This is the W3C standard way to do it
return document.implementation.createDocument(namespaceURL,
rootTagName, null);
}
else { // This is the IE way to do it
// Create an empty document as an ActiveX object
// If there is no root element, this is all we have to do
var doc = new ActiveXObject("MSXML2.DOMDocument");
// If there is a root tag, initialize the document
if (rootTagName) {
// Look for a namespace prefix
var prefix = "";
var tagname = rootTagName;
var p = rootTagName.indexOf(':');
if (p != -1) {
prefix = rootTagName.substring(0, p);
tagname = rootTagName.substring(p+1);
}
// If we have a namespace, we must have a namespace prefix
// If we don't have a namespace, we discard any prefix
if (namespaceURL) {
if (!prefix) prefix = "a0"; // What Firefox uses
}
else prefix = "";
// Create the root element (with optional namespace) as a
// string of text
var text = "<" + (prefix?(prefix+":"):"") + tagname +
(namespaceURL
?(" xmlns:" + prefix + '="' + namespaceURL +'"')
:"") +
"/>";
// And parse that text into the empty document
doc.loadXML(text);
}
return doc;
}
},
parse:function(text) {
if (typeof DOMParser != "undefined") {
// Mozilla, Firefox, and related browsers
return (new DOMParser()).parseFromString(text, "application/xml");
}else if (typeof ActiveXObject != "undefined") {
// Internet Explorer.
var doc = IglooXML.newDocument(); // Create an empty document
doc.loadXML(text); // Parse text into it
return doc; // Return it
}else {
alert('this isn\'t going to work for you');
}
},
// Creates a JSON object from and XML string or XML doc.
// Autodetects what the passed XML is.
toJson: function(xmlin) {
var obj = {};
if (typeOf(xmlin) == 'string') {
xmlin = this.parse(xmlin);
}
if (xmlin.nodeType == 1) {
if (xmlin.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xmlin.attributes.length; j++) {
var attribute = xmlin.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xmlin.nodeType == 3) { // text
obj = xmlin.nodeValue;
} else if (xmlin.nodeType === 4) {
obj = xmlin.nodeValue;
}
if (xmlin.hasChildNodes()) {
for(var i = 0; i < xmlin.childNodes.length; i++) {
var textNodeIdentifier = "#text";
var item = xmlin.childNodes.item(i);
var nodeName = item.nodeName;
var content = "";
if (nodeName === textNodeIdentifier) {
if ((xmlin.nextSibling === null) || (xmlin.nextSibling.localName != xmlin.localName)) {
content = xmlin.textContent;
} else if (xmlin.nextSibling.localName === xmlin.localName) {
content = (xmlin.parentElement.childNodes[0] === xmlin) ? [xmlin.textContent] : xmlin.textContent;
}
return content;
} else {
if (typeof(obj[nodeName]) == "undefined") {
obj[nodeName] = IglooXML.toJson(item);
} else {
if (typeof(obj[nodeName].length) == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(IglooXML.toJson(item));
}
}
}
}
return obj;
},
// Creates an XML string from a JSON object.
// if the @attributes objects exist, it will use them to add the appropriate attributes
strFromJson: function(obj) {
var toXml = function(value, name) {
var xml = "";
if (typeOf(value) == 'array') {
for (var i=0, n=value.length; i" : "/>";
if (hasChild) {
for (var m in value) {
if (m == "#text") {
xml += value[m];
} else if (m == "#cdata") {
xml += "";
} else if (m.charAt(0) != "@") {
xml += toXml(value[m], m);
}
}
xml += "" + name + ">";
}
} else {
xml += "<" + name + ">" + value.toString() + "" + name + ">";
}
return xml;
}, xml="";
for (var node in obj) {
xml += toXml(obj[node], node);
return xml.replace(/\t|\n/g, "");
}
},
// creates an XML doc from a JSON object
fromJson: function(obj) {
return IglooXML.parse(IglooXML.strFromJson(obj));
},
decode: function(xmlString) {
var escaped_to_xml = {
'&': '&',
'"': '"',
'<': '<',
'>': '>'
};
return xmlString.replace(/("|<|>|&)/g, function(str, item) {
return escaped_to_xml[item];
});
}
}
if (Igloo != undefined) {
if (!Igloo.uploadCapabilities) {
Igloo.uploadCapabilities = {
HTML5:'1',
HTML5_NOCHUNK:'2',
FLASH:'3',
NOFLASH:'4'
}
}
/* This is *NOT* the best way for us to do this, but platform can't give use the enum string, so we are duplicating it here.
This enum will allow you to translate the integer returned by the /search/content api call into the string that the object type represents.*/
if (!Igloo.cSearchType) {
Igloo.cSearchType = {
0: 'unknown',
1: 'blog',
2: 'wiki',
3: 'document',
4: 'forum',
5: 'gallery',
6: 'calendar',
7: 'pages',
8: 'people',
9: 'space',
10: 'microblog'
}
}
if (!Igloo.apiLanguageMap) {
Igloo.apiLanguageMap = {
'en': 1,
'ca': 2,
'de': 3,
'el': 4,
'es': 5,
'fr': 6,
'it': 7,
'pb': 8,
'zh': 9,
'ru': 10,
'ja': 11
}
}
if (!Igloo.userLanguage) {
Igloo.userLanguage = {
'en': 'en',
'ca': 'ca',
'de': 'de',
'el': 'es-mx',
'es': 'es',
'fr': 'fr',
'it': 'it',
'pb': 'pt-br',
'zh': 'zh-cn',
'ru': 'ru',
'ja': 'ja'
}
}
Igloo.mimeTypeMap = {
'avi': 'mime-video',
'asf': 'mime-video',
'bmml': 'mime-bmml',
'bmp': 'mime-bmp',
'css': 'mime-css',
'doc': 'mime-doc',
'docx': 'mime-doc',
'eps': 'mime-eps',
'exe': 'mime-exe',
'flv': 'mime-flash',
'gif': 'mime-gif',
'html': 'mime-html',
'jpg': 'mime-jpg',
'jpeg': 'mime-jpg',
'mdb': 'mime-acc',
'accdb': 'mime-acc',
'acc': 'mime-acc',
'mpc': 'mime-proj',
'mpg': 'mime-video',
'mpeg': 'mime-video',
'mp3': 'mime-mp3',
'mp4': 'mime-mp4',
'mov': 'mime-video',
'movie': 'mime-video',
'one': 'mime-note',
'pdf': 'mime-pdf',
'png': 'mime-png',
'ppt': 'mime-ppt',
'pptx': 'mime-ppt',
'psd': 'mime-psd',
'pub': 'mime-pub',
'qt': 'mime-video',
'rar': 'mime-zip',
'swf': 'mime-flash',
'svg': 'mime-xml',
'tif': 'mime-jpg',
'vsd': 'mime-visio',
'vst': 'mime-visio',
'vsw': 'mime-visio',
'txt': 'mime-txt',
'wav': 'mime-wav',
'wma': 'mime-audio',
'wmv': 'mime-wmv',
'xml': 'mime-xml',
'xls': 'mime-xls',
'xlsx': 'mime-xls',
'zip': 'mime-zip',
'none': 'mime-unknown'
}
// this is a global setting for the tinymce comment box height.
Igloo.TinyMceCommentHeight = 150;
}
var Utils = {
keyCode: {
BACKSPACE: 8,
TAB: 9,
ENTER: 13,
ESC: 27,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
COMMA: 188
},
intersect: function(obj1, obj2) {
// tests if two elements intersect
// obj1 and obj2 are values returned from getCoordinates() for two elements
if (!obj1) { return false; }
if (!obj2) { return false; }
// return (obj1.left < obj2.right && obj1.right > obj2.left && obj1.top < obj2.bottom && obj1.bottom > obj2.top);
if (obj1.left > obj2.right) { return false; }
if (obj1.right < obj2.left) { return false; }
if (obj1.top > obj2.bottom) { return false; }
if (obj1.bottom < obj2.top) { return false; }
return true;
},
escapeDoubleQuotes: function(str) {
str = str.replace(/\"/, '\\"');
return str;
},
htmldecode: function(str) {
if (!str) {
return "";
} else {
str = new Element('div', { 'html': str }).get('text');
str = str.replace(/#39;/g, "'").replace(/"/g, '"');
return str;
}
},
htmlencode: function(str) {
if (!str) {
return "";
} else {
str = new Element('div', { 'text': str }).get('html');
str = str.replace(/\'/g, ''').replace(/\"/g, '"');
return str;
}
},
texttohtml: function(str) {
str = str.replace(//g, '>').replace(/\n/g, '
');
return str;
},
htmltotext: function(str) {
str = str.replace(/
/g, '\r\n');
return str;
},
htmlstriptags: function(str, tag) { //this strips all tags that match "tag"
var randomnewelement = new Element('div', { 'html': str });
var thetags = randomnewelement.getElements(tag);
thetags.each(function(ele) { ele.destroy(); });
var ret = randomnewelement.innerHTML;
//randomnewelement.textContent || randomnewelement.innerText;
//console.log(ret);
return ret;
},
removeLineBreaks: function(str) {
return str.replace(/(\r\n|\n|\r)/gm, "");
},
outerHTML: function(elem) {
if (elem.outerHTML) {
return elem.outerHTML;
}
var parent = elem.parentNode;
var el = document.createElement(parent.tagName);
el.appendChild(elem);
var shtml = el.innerHTML;
parent.appendChild(elem);
return shtml;
},
alertObject: function(obj) {
var msg = [];
for (var i in obj) {
msg.push(i + ': ' + obj[i]);
}
alert(msg.join('\n'));
},
alphatize: function(str) {
// returns a string which is only alphanum|~|_. used for constructing friendly urls (even more strict than urlencoding)
return str.toLowerCase().replace(/ /g, "_").replace(/[^~0-9a-zA-Z_]*/g, "");
// platform validates against this regex: ^[0-9a-zA-Z_]+([~][1-9][0-9]*)?$
},
modalAlert: function(message, title, isError) {
var t = title ? title : window.translations('media-js-Error');
var shadowColor = '';
var btnColor = '';
if (isError) {
shadowColor = '#ff0000';
btnColor = 'ig-button_gray';
}
var alertModal = new Modalbox({
'title': t,
'shadowcolor': shadowColor
});
var alertContainer = new Element('div', { 'class': 'ig-modal-pad' });
var alertContainerForm = new Element('form', { 'class': 'ig-form' });
var alertContainerMsg = new Element('p').set('html', message).inject(alertContainer, 'bottom');
var alertContainerItemDiv2 = new Element('div', { 'class': 'ig-formitem buttons ig-clearfix nomargin' }).inject(alertContainer, 'bottom');
var randNum = Number.random(100, 100000000000);
while ($(randNum + '_modalcontinue')) {
randNum = Number.random(100, 100000000000);
}
var alertContainerContinueButton = new Element('input', {
'class': 'ig-button ig-bold ' + btnColor,
'type': 'button',
'id': randNum + '_modalcontinue',
'value': window.translations('media-js-continue')
}).inject(alertContainerItemDiv2, 'bottom');
alertContainerContinueButton.addEvent('click', function() {
alertModal.close();
alertModal.fireEvent('onClose');
});
alertModal.adopt(alertContainer);
return alertModal;
},
//injects a busy blanket, returns the container of the busy_blanket
busy_blanket: function(elem, mode, zindex) {
//first, get the coordinates of elem.
var coords = elem.getCoordinates();
//create the blanket
var blanket_container = new Element('div', { 'class': 'ig-busyblanket' });
//set the styles and coordinates
var offset_top = (mode == 1) ? coords.top : elem.getStyle('margin-top').toInt(); // defaults to 0
blanket_container.setStyles({ 'width': coords.width, 'height': coords.height, 'top': offset_top });
if (zindex) {
blanket_container.setStyle('z-index', zindex);
}
var blanket_spinny = new Element('div', { 'class': 'ig-loader-medium ig-automargin' }).setStyles({ 'position': 'relative', 'top': (coords.height - 36) / 2 }).inject(blanket_container);
blanket_container.inject(elem, 'after');
return blanket_container;
},
item_url_available: function(options) {
var parentId = options.parentId;
var urlTitle = options.urlTitle;
var navItemId = options.navItemId || null;
var onSuccess = options.onSuccess || null;
var onUnsuccess = options.onUnsuccess || null;
var onFailure = options.onFailure || null;
var addRequest = new ApiClient({
'apimethod': 'nav/item_url_available',
'method': 'get',
'queryparams': {
'parentId': parentId,
'urlTitle': urlTitle,
'navItemId': navItemId
},
onRequest: function() {
//alert('sent request to api');
},
onSuccess: function(text, xml) {
var returnjson = JSON.decode(text, true);
if (returnjson != null) {
var itemjson = returnjson.response.value;
if (itemjson.toLowerCase() == 'false') {
onUnsuccess();
} else {
onSuccess();
}
}
},
onFailure: function() {
//alert(window.translations('media-js-api_error'));
onFailure(arguments);
}
});
},
jsonParseTime: function(jsonDate) {
var offset = new Date().getTimezoneOffset() * 60000;
var parts = /\/Date\((-?\d+)([+-]\d{2})?(\d{2})?.*/.exec(jsonDate);
if (parts[2] == undefined) parts[2] = 0;
if (parts[3] == undefined) parts[3] = 0;
return new Date(+parts[1] + offset + parts[2] * 3600000 + parts[3] * 60000);
},
// IglooApiResponse Parse
// - arguments xml
// - returns object {'apihtml':'...', 'apixml':'...'}
// originally written by Ian, refactored in Utils by Ned
IARParse: function(xml) {
// because javascript has crappy support for XPATH, we need to do some stupid looping
var apihtml = '';
var apixml = '';
var objects = xml.getElementsByTagName('object');
for (var i = 0; i < objects.length; i++) {
var objnames = objects[i].getElementsByTagName('name');
var objname = objnames[0];
if (objname && objname.firstChild && objname.firstChild.nodeValue) {
if (objname.firstChild.nodeValue == 'widgetHtml') {
// Firefox truncates node values at 4K so we can't just do .firstChild.nodeValue because there could be more children...
//apihtml = objects[i].getElementsByTagName('value')[0].firstChild.nodeValue;
for (var j = 0; j < objects[i].getElementsByTagName('value')[0].childNodes.length; j++) {
apihtml += objects[i].getElementsByTagName('value')[0].childNodes[j].nodeValue;
}
}
if (objname.firstChild.nodeValue == 'widgetXml') {
// Firefox truncates node values at 4K so we can't just do .firstChild.nodeValue because there could be more children...
//apixml = objects[i].getElementsByTagName('value')[0].firstChild.nodeValue;
for (var j = 0; j < objects[i].getElementsByTagName('value')[0].childNodes.length; j++) {
apixml += objects[i].getElementsByTagName('value')[0].childNodes[j].nodeValue;
}
}
} else {
// problem. the xml returned has nothing in it we expect
}
}
return { 'apihtml': apihtml, 'apixml': apixml };
},
AttachDataObj: function(elem) {
if ((matches = elem.className.match(/(\{.*\})/))) {
var dataobj = decodeURIComponent(matches[1]);
dataobj = JSON.decode(dataobj);
// do a nice combine of the dataobjs
if (!elem.dataobj || typeOf(elem.dataobj) != 'hash') {
elem.dataobj = new Hash(elem.dataobj || dataobj);
}
elem.dataobj.combine(dataobj);
}
},
Utf8: {
// public method for url encoding
encode: function(str) {
str = str.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < str.length; n++) {
var c = str.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// public method for url decoding
decode: function(utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
},
decimal: function(str) {
var strdec = '';
return strdec;
}
},
formatBytes: function(bytes, precision) {
/**
* precision:
* 0: 1.09 -> 1
* 1: 1.09 -> 1.1
* 2: 1.09 -> 1.09
*/
if (!precision) {
precision = 0;
}
var units = [
window.translations('media-js-filesize_bytes'),
window.translations('media-js-filesize_kilobyte_abbr'),
window.translations('media-js-filesize_megabyte_abbr'),
window.translations('media-js-filesize_gigabyte_abbr')
];
bytes = Math.max(bytes, 0);
var exp = Math.floor((bytes ? Math.log(bytes) : 0) / Math.log(1024));
exp = Math.min(exp, units.length - 1);
bytes /= Math.pow(1024, exp);
return bytes.round(precision) + units[exp];
},
sprintf: function(instring, argarry) {
return instring.replace(/{(\d+)}/g, function(match, number) {
return typeof argarry[number] != 'undefined' ? argarry[number] : match;
});
},
timeSince: function(milliseconds) {
var diff = 0;
var diffString = '';
if (milliseconds > 31556926000) {
// 31556926000 ms = 1 year (365.24 days)
diff = Math.round(milliseconds / 31556926000);
diffString = this.sprintf((diff == 1 ? diff + ' ' + window.translations('funct-date-year_ago') : window.translations('funct-date-years_ago')), [diff]);
} else if (milliseconds > 2629743000) {
// 2629743000 ms = 1 month (30.44 days)
diff = Math.round(milliseconds / 2629743000);
diffString = this.sprintf((diff == 1 ? diff + ' ' + window.translations('funct-date-month_ago') : window.translations('funct-date-months_ago')), [diff]);
} else if (milliseconds > 604800000) {
// 604800000 ms = 1 week
diff = Math.round(milliseconds / 604800000);
diffString = this.sprintf((diff == 1 ? diff + ' ' + window.translations('funct-date-week_ago') : window.translations('funct-date-weeks_ago')), [diff]);
} else if (milliseconds > 86400000) {
// 86400000 ms = 1 day
diff = Math.round(milliseconds / 86400000);
diffString = this.sprintf((diff == 1 ? diff + ' ' + window.translations('funct-date-day_ago') : window.translations('funct-date-days_ago')), [diff]);
} else if (milliseconds > 3600000) {
// 3600000 ms = 1 hour
diff = Math.round(milliseconds / 3600000);
diffString = this.sprintf((diff == 1 ? diff + ' ' + window.translations('funct-date-hour_ago') : window.translations('funct-date-hours_ago')), [diff]);
} else if (milliseconds > 60000) {
// 60000 ms = 1 minute
diff = Math.round(milliseconds / 60000);
diffString = this.sprintf((diff == 1 ? window.translations('funct-date-minute_ago') : window.translations('funct-date-minutes_ago')), [diff]);
} else {
diffString = window.translations('funct-date-moments_ago');
}
return diffString;
},
debounce: function(callback, delay) {
if (this.toDebounce[callback]) {
clearTimeout(this.toDebounce[callback]);
}
this.toDebounce[callback] = setTimeout(callback, delay);
},
toDebounce: [],
zeroPad: function(num, count) {
var numZeropad = num + '';
while (numZeropad.length < count) {
numZeropad = "0" + numZeropad;
}
return numZeropad;
},
isNotNullOrUndefined: function(variable) {
if (typeof variable == "undefined") {
return false;
} else if (variable === null) {
return false;
}
return true;
},
// Use this to check for and return a boolean based on a string.
// It's good to use when we have an input with a "true" or "false" value that
// we need to check against.
inputIsNotFalse: function(variable) {
if (Utils.isNotNullOrUndefined(variable)) {
var something = typeof (variable);
if (typeOf(variable) == "boolean" && variable === false) {
return false;
} else if (typeOf(variable) == "string" && variable.toLowerCase() === 'false') {
return false;
} else {
return true;
}
} else {
return false;
}
},
fixFlash: function() {
var idnum = 100;
var idExceptions = [
'swiff',
'flashpaper',
'slideshow',
'pdfobject',
'flashplayer'
];
var classExceptions = [
'ig-embeddedobject'
];
var allObjects = $$('object');
Array.each(allObjects, function(thisflashobject) {
var objidlowercase = thisflashobject.id.toString().toLowerCase();
var isException = false;
if (objidlowercase) {
Array.each(idExceptions, function(except) {
if (objidlowercase.contains(except)) {
isException = true;
}
});
}
if (!isException) {
if ($(thisflashobject)) {
Array.each(classExceptions, function(except) {
if (typeOf(thisflashobject.hasClass) == 'function' && $(thisflashobject).hasClass(except)) {
isException = true;
}
if ($(thisflashobject).className && $(thisflashobject).className.toString().contains(except)) {
isException = true;
}
});
}
}
if (!isException) {
var tempElem = new Element('span', {
'id': 'newFlashContainer'
});
var swfo = thisflashobject.getAttribute('swfo')
if (swfo === null) {
var swfId = (thisflashobject.getAttribute('id')) ? thisflashobject.getAttribute('id') : 'swfobjectembedded_' + idnum;
var existingParams = $(thisflashobject).getElementsByTagName('param');
var alreadyModified = false;
var flashvars = {};
var params = {};
var attributes = {
'id': swfId
};
var slideshowParam = false;
for (var i = 0; i < existingParams.length; i++) {
var thisParam = $(existingParams[i]);
params[thisParam.getAttribute('name')] = thisParam.getAttribute('value');
if (thisParam.getAttribute('name') == "movie" && thisParam.getAttribute('value').ciContains('embeded_slideshow')) {
slideshowParam = true;
}
}
if (!slideshowParam) {
if (thisflashobject.parentElement) {
thisflashobject.parentElement.appendChild(tempElem);
thisflashobject.parentElement.removeChild(thisflashobject);
} else {
thisflashobject.parentNode.appendChild(tempElem);
thisflashobject.parentNode.removeChild(thisflashobject);
}
swfobject.embedSWF(thisflashobject.getAttribute('data'), 'newFlashContainer', thisflashobject.getAttribute('width'), thisflashobject.getAttribute('height'), "9.0.115", "/cmedia/swf/expressinstall.swf", flashvars, params, attributes);
idnum++;
}
}
}
});
},
getIgPaneObject: function(elem) { //method to get an igSlidepane by passing in the menu object
elem = $(elem);
return window.igPaneObjects.get(elem.get('id'));
},
uploadCapabilities: function() {
var sliceException = (Browser.firefox);
if (Igloo.flashEnabled === undefined) {
this.checkForFlash();
}
if ((typeof (File) !== 'undefined') && (typeof (Blob) !== 'undefined') && (typeof (FileList) !== 'undefined')) {
if ((!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || Blob.prototype.slice) && !sliceException) {
//slice.
return Igloo.uploadCapabilities.HTML5;
} else {
//no slice.
return Igloo.uploadCapabilities.HTML5_NOCHUNK;
}
} else {
if (Igloo && Igloo.flashEnabled) {
//flash.
return Igloo.uploadCapabilities.FLASH;
} else {
//no flash.
return Igloo.uploadCapabilities.NOFLASH;
}
}
},
checkForFlash: function() {
Igloo.flashEnabled = false;
try {
var ieflash = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if (ieflash) {
Igloo.flashEnabled = true;
}
} catch (e) {
if (navigator.mimeTypes["application/x-shockwave-flash"] != undefined) {
if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) {
Igloo.flashEnabled = true;
}
}
}
},
//stolen from mootools-more
isVisible: function(el) {
return !!(!el || el.offsetHeight || el.offsetWidth);
},
preventDC: function(form) {
// get all the submit buttons
var subButtons = $(form).getElements('input[type=submit]');
// add a click event to them that will prevent double-click registering
$$(subButtons).each(function(sbutt) {
sbutt.addEvent('click', function(e) {
if (window.isSubmitting) {
this.disabled = true;
e.stop();
} else {
this.addClass('ig-button_disabled');
window.isSubmitting = true;
window.setTimeout(function() {
if (!$(form).retrieve('validform')) {
this.removeClass('ig-button_disabled');
window.isSubmitting = false;
}
} .bind(this), 200);
}
});
});
},
jstrimspace: function() {
var tas = $$('textarea.js-trimspace');
for (var i = 0; i < tas.length; i++) {
if (tas[i].value.trim() == '') {
tas[i].value = '';
}
}
},
// Used in both ajax-bookmarks and ajax-badge to perform field validation for multiple events.
validateAndDisable: function(self, functionName, submitButton) {
if (typeOf(self[functionName]) == 'function') {
if (self[functionName]()) {
/* You will need to create a new validity Hash() in the initialize
of the class using this function or this will fail */
if (!self.validity.hasValue(false)) {
submitButton.removeProperty('disabled');
submitButton.removeClass('ig-button_disabled');
}
} else {
submitButton.set('disabled', 'disabled');
submitButton.addClass('ig-button_disabled');
}
}
}
}
Element.implement({
// this TOTAL HACK fixes an element redraw problem in Chrome.
// fixes bug: documented in ticket #10662
// for more info: http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript
redraw: function(){
var elem = this;
var display = elem.getStyle('display');
elem.style.display = 'none';
var redrawFix = elem.offsetHeight;
elem.style.display = display;
return this;
}
});
Array.implement({
// case insensitve array contains
ciContains: function(instring) {
var lcArray = [];
Array.each(this, function(aElement) {
lcArray.push(aElement.toString().toLowerCase());
}.bind(this));
return lcArray.contains(instring.toString().toLowerCase());
}
});
String.implement({
// case insensitive string compare.
ciCompare: function(instring) {
return (this.toLowerCase() === instring.toString().toLowerCase());
},
// case insensitive string contains.
ciContains: function(instring) {
return (this.toLowerCase()).contains(instring.toString().toLowerCase());
}
});
Date.implement({
getDaysInMonth: function(utc) {
var m = utc ? this.getUTCMonth() : this.getMonth();
// If feb.
if (m == 1) {
var y = utc ? this.getUTCFullYear() : this.getFullYear();
return !(y % 4) && (y % 100) || !(y % 400) ? 29 : 28;
}
// If Apr, Jun, Sep or Nov return 30; otherwise 31
return (m == 3 || m == 5 || m == 8 || m == 10) ? 30 : 31;
}
});
window.mousex = 0;
window.mousey = 0;
window.mouse = {};
window.addEvent('load',function(){
document.addEvent('mousemove',function(event){
if(event && event.page){
window.mousex = event.page.x;
window.mousey = event.page.y;
window.mouse.left= event.page.x;
window.mouse.right = event.page.x;
window.mouse.top = event.page.y;
window.mouse.bottom = event.page.y;
}
});
});
//global onload
window.addEvent('domready', function(){
if (window.Igloo != undefined) {
Utils.checkForFlash();
}
if (!Browser.ie8) {
Utils.fixFlash();
}
Object.each($$('form'), function(thisform) {
if ($(thisform) && $(thisform).hasClass('prevent_double_submit')) {
Utils.preventDC(thisform);
}
});
Utils.jstrimspace();
});
window.translations = function(key) {
return Utils.htmldecode(window.translationObj[key]);
}
// Userbar hover tips
// we only want one instance of this.
if (!$$('ig-tooltip')) {
var userbarTips = new toolTip($$('.ig-tooltip'), {
maxTitleChars: 50
});
}// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
---
description: Graphing/chart tool for mootools 1.2
license: Apache License, Version 2.0
authors:
- Brett Dixon
requires:
core/1.2.5:Core
provides: [MilkChart.Column, MilkChart.Bar, MilkChart.Line, MilkChart.Scatter, MilkChart.Pie]
...
*/
// Add our namespace
var MilkChart;
// Simple Point class
var Point=new Class({
initialize: function(x,y) {
this.x=x||0;
this.y=y||0;
}
});
MilkChart=new Class({
Implements: [Options,Events],
options: {
width: 184,
height: 184,
colors: ['#999'],
padding: 12,
font: "Verdana",
fontColor: "#000000",
fontSize: 10,
background: "#f0f0f0",
chartLineColor: "#878787",
chartLineWeight: 1,
border: false,
borderWeight: 1,
borderColor: "#878787",
titleSize: 12,
titleFont: "Verdana",
titleColor: "#000000",
showRowNames: false,
showValues: false,
showKey: true,
useZero: true,
copy: false,
data: {}
},
initialize: function(el,options) {
this.setOptions(options);
this.element=document.id(el);
this.width=this.options.width;
this.height=this.options.height;
this.container=new Element('div').inject(this.element.getParent());
this.container.setStyles({ width: this.width,height: this.height })
this._canvas=new Element('canvas',{ width: this.options.width,height: this.options.height }).inject(this.container);
this.ctx=this._canvas.getContext('2d');
this.colNames=[];
this.rowNames=[];
this.rowCount=this.element.getElement('thead').getChildren()[0].getChildren().length;
// Hacky, oh the shame!
this.minY=(this.options.useZero)?0:10000000000;
this.maxY=0;
this.rows=[];
this.options.title=false||this.element.title;
this.bounds=[new Point(),new Point(this.width,this.height)];
this.chartWidth=0;
this.chartHeight=0;
this.keyPadding=this.width*.2;
this.rowPadding=this.height*.1;
this.colors=this.__getColors(this.options.colors);
this.shapes=[];
// This could be done in a list, but an object is more readable
MilkChart.Shapes.each(function(shape) {
this.shapes.push(shape);
} .bind(this));
},
prepareCanvas: function() {
if(!this.options.copy) {
this.element.setStyle('display','none');
}
// Fill our canvas' bg color
this.ctx.fillStyle=this.options.background;
this.ctx.fillRect(0,0,this.width,this.height);
this.ctx.font=this.options.fontSize+"px "+this.options.font;
if(this.options.border) {
this.ctx.lineWeight=this.options.borderWeight;
this.ctx.strokeRect(0.5,0.5,this.width-1,this.height-1);
}
if(this.options.showValues) {
// Accomodate the width of the values column
//this.bounds[0].x+=this.getValueColumnWidth();
}
this.bounds[0].x+=this.options.padding;
this.bounds[0].y+=this.options.padding;
this.bounds[1].x-=this.options.padding*2;
this.bounds[1].y-=this.options.padding*2;
if(this.options.showKey) {
// Apply key padding
var longestName="";
this.colNames.each(function(col) {
if(col.length>longestName.length) {
longestName=String(col);
}
});
var colorSquareWidth=14
this.keyPadding=this.ctx.measureText(longestName).width+colorSquareWidth;
this.bounds[1].x-=this.keyPadding;
// Set key bounds
var chartKeyPadding=1.02;
this.keyBounds=[
new Point(this.bounds[1].x*chartKeyPadding,this.bounds[0].y),
new Point(this.keyPadding,this.bounds[1].y)
];
}
if(this.options.title) {
titleHeight=this.bounds[0].y+this.height*.1;
this.bounds[0].y=titleHeight;
this.titleBounds=[new Point(this.bounds[0].x,0),new Point(this.bounds[1].x,titleHeight)];
this.drawTitle();
}
if(this.options.showRowNames) {
this.ctx.font=this.options.fontSize+"px "+this.options.font;
this.rowPadding=(this.ctx.measureText(this.longestRowName).width>((this.bounds[1].x-this.bounds[0].x)/this.rows.length))?this.ctx.measureText(this.longestRowName).width:this.height*0.1;
this.bounds[1].y-=this.rowPadding;
}
else {
this.rowPadding=0;
}
this.chartWidth=this.bounds[1].x-this.bounds[0].x;
this.chartHeight=this.bounds[1].y-this.bounds[0].y;
},
wAxes: function() {
/**********************************
* Draws X & Y axes
*********************************/
this.ctx.beginPath();
this.ctx.strokeStyle=this.options.chartLineColor;
// The +.5 is to put lines between pixels so they draw sharply
this.ctx.moveTo(this.bounds[0].x+.5,this.bounds[0].y+.5);
this.ctx.lineTo(this.bounds[0].x+.5,this.bounds[1].y+.5);
this.ctx.moveTo(this.bounds[0].x+.5,this.bounds[1].y+.5);
this.ctx.lineTo(this.bounds[1].x+.5,this.bounds[1].y+.5);
this.ctx.stroke();
},
drawValueLines: function() {
/**********************************
* Draws horizontal value lines
*
* Finds the line values based on Array dist, and sets the numbers of lines
* to use. This formula is similar how excel handles it. Not sure if there
* is a cleaner way of creating this type of list.
*
* Next it draws in the lines and the values. Also sets the ratio to apply
* to the values in the table.
*********************************/
var dist=[1,2,5,10,20,50,100,150,500,1000,1500,2000,2500,5000,10000];
var maxLines=9;
var i=0;
this.chartLines=1;
delta=Math.floor((this.maxY-this.minY));
while(Math.floor((delta/dist[i]))>maxLines) {
i++;
}
this.chartLines=Math.floor((delta/dist[i]))+2;
var mult=dist[i];
var negativeScale=(this.minY<0)?(mult+this.minY):0;
// Set the bounds ratio
this.ratio=(this.chartHeight)/((this.chartLines-1)*mult);
this.ctx.font=this.options.fontSize+"px "+this.options.font;
this.ctx.textAlign="right";
this.ctx.fillStyle=this.options.fontColor;
var boundsHeight=this.bounds[1].y-this.bounds[0].y;
var lineHeight=Math.floor(boundsHeight/(this.chartLines-1));
for(i=0;ithis.height)?this.height*.9:keyHeight;
var keyOrigin=(this.height-keyHeight)/2;
this.ctx.font=this.options.fontSize+"px "+this.options.font;
this.rowNames.each(function(item) {
this.ctx.fillStyle=this.options.fontColor;
this.ctx.textAlign="left";
this.ctx.fillText(MilkChart.escape(item),this.keyBounds[0].x+14,keyOrigin+8);
this.ctx.fillStyle=this.colors[colorID];
this.ctx.fillRect(Math.ceil(this.keyBounds[0].x),Math.ceil(keyOrigin),10,10);
colorID++;
keyOrigin+=keyNameHeight;
} .bind(this))
}
});
// Shapes for tick marks
MilkChart.Shapes=new Hash({
/*********************************************
* This object is here for easy reference. Feel
* free to add any additional shapes here.
********************************************/
square: function(ctx,x,y,size,color) {
ctx.fillStyle=color;
ctx.fillRect(x-(size/2),y-(size/2),size,size);
},
circle: function(ctx,x,y,size,color) {
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(x,y,size/2,0,(Math.PI/180)*360,true);
ctx.closePath();
ctx.fill();
},
triangle: function(ctx,x,y,size,color) {
ctx.fillStyle=color;
ctx.beginPath();
x-=size/2;
y-=size/2;
lr=new Point(x+size,y+size);
ctx.moveTo(x,lr.y);
ctx.lineTo(x+(size/2),y);
ctx.lineTo(lr.x,lr.y);
ctx.closePath();
ctx.fill();
},
cross: function(ctx,x,y,size,color) {
x-=size/2;
y-=size/2;
ctx.strokeStyle=color;
ctx.lineWidth=1;
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x+size,y+size);
ctx.moveTo(x,y+size);
ctx.lineTo(x+size,y);
ctx.closePath();
ctx.stroke();
},
diamond: function(ctx,x,y,size,color) {
x-=size/2;
y-=size/2;
ctx.fillStyle=color;
ctx.beginPath();
ctx.moveTo(x+(size/2),y);
ctx.lineTo(x+size,y+(size/2));
ctx.lineTo(x+(size/2),y+size);
ctx.lineTo(x,y+(size/2));
ctx.closePath();
ctx.fill();
}
})
MilkChart.escape=function(str) {
str=String(str);
var patterns=[
[/\&/g,'&'],
[/\</g,'<'],
[/\>/g,'>']
]
patterns.each(function(item) {
str=str.replace(item[0],item[1]);
})
return str
}
/*------ IGLOO Tool Tip ------*/
var toolTip = new Class({
Extends: Tips,
options: {
showDelay: 100,
hideDelay: 50,
className: null,
offset: {x: 0, y: 30},
fixed: true
},
initialize: function() {
var params = Array.link(arguments, {
options: Object.type, elements: function(obj) {
return obj != null;
}
});
this.setOptions(params.options || null);
this.tip = new Element('div', {
'class': 'ig-tooltip'
}).inject(document.body);
if (this.options.className) {
this.tip.addClass(this.options.className);
}
var top = new Element('div', {
'class': 'ig-floatmenu-tip'
}).inject(this.tip);
this.container = new Element('div', {
'class': 'ig-tooltip-body'
}).inject(this.tip);
this.tip.setStyles({
'position': 'absolute',
top: 0,
left: 0,
'display': 'none'
});
if (params.elements) {
this.attach(params.elements);
}
},
attach: function(elements) {
$$(elements).each(function(element) {
var title = element.retrieve('tip:title', element.get('title'));
element.addEvent('mouseenter', function(e) {
element.retrieve(
'tip:enter', this.elementEnter(this, element)
);
}.bind(this));
element.addEvent('mouseleave', function(e) {
element.retrieve(
'tip:leave', this.elementLeave(this, element)
);
}.bind(this));
if (!this.options.fixed) {
element.addEvent('mousemove', function(e) {
element.retrieve(
'tip:move',
this.elementMove(this, element)
);
}.bind(this));
}
element.store('tip:native', element.get('title'));
element.erase('title');
}, this);
return this;
},
elementEnter: function(event, element) {
if (!element.hasClass('active')) {
this.timer = clearTimeout(this.timer);
this.timer = (function(){
$A(this.container.childNodes).each(Element.dispose);
var title = element.retrieve('tip:title');
if (title){
this.titleElement = new Element('div', {
'class': 'tip-title'
}).inject(this.container);
this.fill(this.titleElement, title);
}
var text = element.retrieve('tip:text');
if (text){
this.textElement = new Element('div', {
'class': 'tip-text'
}).inject(this.container);
this.fill(this.textElement, text);
}
this.position((!this.options.fixed) ? event : {
page: element.getPosition()
});
this.show(element);
}).delay(this.options.showDelay, this);
// Removes tooltip on trigger click
element.addEvent('click', function (event) {
$(document.body).getElement('div.ig-tooltip').setStyle('display', 'none');
});
}
}
});
/* Creates a help menu*/
var helpPopup = new Class({
Implements: [Options, Events],
options: {
'text':'placeholder',
'image':'/cmedia/img/icons/help_v2.png',
'title':'Help',
'persistent':'true'
},
initialize: function(trigger, options) {
if (!$(trigger)) {
return false;
}
this.properties = {};
var self = this;
this.trigger = $(trigger);
this.setOptions(options || {});
// make the span include an image
if (this.options.image != '') {
this.helpIcon = new Element('img', {
'id':this.trigger.id+'-trigger_icon',
'class':'ig-help-trigger_icon',
'src':this.options.image
});
} else {
this.helpIcon = new Element('div', {
'id':this.trigger.id+'-trigger_icon',
'class':'ig-help-trigger_icon'
});
}
this.trigger.adopt(this.helpIcon);
this.trigger.addEvent('click', function(event) {
event.preventDefault();
self.clickCoordinates = {
'clientX':event.client.x,
'clientY':event.client.y,
'pageX':event.page.x,
'pageY':event.page.y
};
self.togglePopup();
});
//setup a window click event that will cause the popup to close when we click outside of the popup
if (!self.options.persistent) {
document.addEvent('click', function(event) {
if (!$(event.target).hasClass('ig-help-popup-element') && $(event.target) != self.trigger.firstChild) {
self.closePopup()
}
});
}
},
togglePopup: function() {
if (this.popupwindow) {
this.closePopup();
} else {
this.openPopup();
}
},
openPopup: function() {
var self = this;
if (!this.popupwindow) {
this.popuptitlebar = new Element('div', {
'id':this.trigger.id+'-popup_title',
'class':'ig-help-popup-titlebar ig-help-popup-element'
});
this.closeIcon = new Element('img', {
'src':'/cmedia/img/icons/cross_gray_sm2.png',
'id':this.trigger.id+'-popup_title_close',
//DO NOT add 'ig-help-popup-element' class to the close icon or it won't function anymore
'class':'ig-help-popup-titlebar-close'
}).addEvent('click', function() {
self.closePopup();
}).inject(this.popuptitlebar);
this.popuptitletext = new Element('span', {
'html':this.options.title,
'class':'ig-help-popup-titlebar-text ig-help-popup-element'
}).inject(this.popuptitlebar);
this.popupbody = new Element('div', {
'html':this.options.text,
'class':'ig-help-popup-body ig-help-popup-element'
});
this.popupwindow = new Element('div',{
'class':'ig-help-popup-container ig-help-popup-element',
'id':this.trigger.id+'_popup'
}).inject(document.body, 'top');
this.popuptitlebar.inject(this.popupwindow);
this.popupbody.inject(this.popupwindow);
var iconWidth = $(this.trigger.id+'-trigger_icon').getSize();
var horizontalCorrection = (iconWidth.x + 5) * -1;
//do we have the room to the right?
if ((document.getWidth() - this.clickCoordinates.clientX) <= ((horizontalCorrection* -1) + this.popupwindow.getWidth())) {
// go left, young man
horizontalCorrection = this.popupwindow.getWidth() + iconWidth.x + 5;
}
var popupTopHalf = this.popupwindow.getHeight()/2;
var popupTopMargin = this.clickCoordinates.pageY - popupTopHalf;
var py = this.clickCoordinates.pageY;
var gsx = window.getScroll().y;
if (this.clickCoordinates.pageY - window.getScroll().y < popupTopHalf) {
popupTopMargin = window.getScroll().y;
}
this.popupwindow.setStyles({
'margin-left':this.clickCoordinates.clientX - horizontalCorrection,
'margin-top':popupTopMargin
}).removeClass('hide');
}
},
closePopup: function() {
if (this.popupwindow){
this.popupwindow.destroy();
delete this.popupwindow;
}
}
});
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_helppopup) {
var help;
Object.each(Igloo.asset_helppopup, function(object, id) {
help = new helpPopup(id, object);
});
}
});
// This script handles a change of channel by the user in Add/Edit "Object"
window.addEvent('domready', function() {
if (Igloo && Igloo.asset_changeChannel) {
Object.each(Igloo.asset_changeChannel, function(object, id) {
var elem = $(id);
if (elem) {
elem.dataobj = object;
// when channel dropdown is changed
elem.addEvent('change', function() {
var selectedChannel = elem.value;
// update button text for moderation (add only for now)
if (elem.dataobj.action == 'AddChild') {
var strBtnText = window.translations('system-add-Publish');
if (selectedChannel !== '') {
if (elem.dataobj.channelData[selectedChannel].isModerated)
strBtnText = window.translations('system-add-Send_to_Moderator');
}
$('ig-publish').value = strBtnText;
}
//update the labels requirement input
if ($('js-labels_are_required') && selectedChannel !== '') {
$('js-labels_are_required').set('value', elem.dataobj.channelData[selectedChannel].labelsRequired);
}
// update forum topic list when applicable
if (elem.dataobj.objectType == 'ForumChannel') {
var typesDropdown = $('topicStatus');
var currSelectedType = typesDropdown.value;
var channelTypes = (selectedChannel !== '') ? elem.dataobj.channelData[selectedChannel].types : 15;
if (channelTypes == 0) { channelTypes = 15; }
/*
Discussions = 1
Questions = 2
Ideas = 4
Issues = 8
All = 15
*/
// empty topic dropdown and repopulate accordingly
typesDropdown.empty();
// Discussions/All
if ((channelTypes & 1) != 0) {
new Element('option', { 'value': 1, 'text': window.translations('apps-forums-Add_Topic-Discussion') }).inject(typesDropdown);
}
// Questions/All
if ((channelTypes & 2) != 0) {
new Element('option', { 'value': 2, 'text': window.translations('apps-forums-Add_Topic-Question') }).inject(typesDropdown);
}
// Ideas/All
if ((channelTypes & 4) != 0) {
new Element('option', { 'value': 4, 'text': window.translations('apps-forums-Add_Topic-Idea') }).inject(typesDropdown);
}
// Issues/All
if ((channelTypes & 8) != 0) {
new Element('option', { 'value': 8, 'text': window.translations('apps-forums-Add_Topic-Issue') }).inject(typesDropdown);
}
// keep original selected topic type when available
$$('#topicStatus option').each(function(option) {
if (option.value == currSelectedType) {
option.selected = true;
}
});
}
});
}
});
}
});
var changeLocation = new Class({
Implements: [Options, Events],
options: {
sitemapSource: null,
allowedScope: 'Community,Page,Space',
checkPerms: true,
pageInfo:{},
edit: false,
currentObjectIsSpace: false,
baseid:""
},
initialize: function(trigger, options){
this.setOptions(options || {});
this.elements = {};
this.elements.changeLink = $(trigger);
this.elements.form = this.elements.changeLink.getParent('form');
this.elements.origBaseURL = this.elements.form.getElement('.js-help-url');
this.elements.segmentURL = this.elements.form.getElement('.js-navItem-url');
this.elements.parentId = this.elements.form.getElement('.js-navItem-parent');
this.elements.parentGuid = this.elements.form.getElement('.js-navItem-parent-guid');
this.arrays = {};
this.arrays.allowedScope = this.options.allowedScope.split(',');
this.values = {};
this.values.origBaseURL = this.elements.origBaseURL.get('html');
this.attachEvents();
},
attachEvents: function() {
var self = this;
this.elements.changeLink.addEvent('click',function(event){
event.preventDefault();
self.initializeValues();
self.buildSiteMap();
});
},
showWait: function() {
this.elements.changeLink.addClass('ajaxloading');
},
hideWait: function() {
this.elements.changeLink.removeClass('ajaxloading');
},
buildSiteMap: function() {
this.showWait();
this.buildSiteData();
},
buildSiteData: function() {
if (!this.data && typeOf(this.data) != "object") {
if (this.options.sitemapsource && $(this.options.sitemapSource)) {
this.elements.sitemapSource = $(this.options.sitemapSource);
this.data.sitemap = JSON.decode(this.elements.sitemapSource.value);
this.hideWait();
this.drawSitemap();
} else {
var self = this;
var queryParams = {};
if (this.options.baseid != "") {
queryParams['baseId'] = this.options.baseid;
}
var siteMapApi = new ApiClient({
'apimethod': 'nav/sitemapSerialized',
'method':'get',
'queryparams':queryParams,
onSuccess: function(txt) {
var sitemapJson = JSON.decode(this.response.text, true);
self.data = {};
self.data.sitemap = JSON.decode(sitemapJson);
self.drawSitemap();
},
onFailure: function() {
Utils.modalAlert(window.translations('media-js-error_general'));
},
onComplete: function() {
self.hideWait();
}
});
}
} else {
this.drawSitemap();
this.hideWait();
}
},
initializeValues: function(){
var self = this;
self.values.segmentURL = self.elements.segmentURL.value;
self.values.parentId = self.elements.parentId.value;
},
drawSitemap: function(){
var self = this;
var sitemap = new Element('ul', {
'class':'ig-page-choose-location ig-page-choose-location-restrict'
}).setStyles({
'overflow':'auto',
'height': (Window.getHeight()*0.75).round() + (-64) //64 = -18px padding/margin + 28px modaltitle
});
self.recurseSitemap(self.data.sitemap, true, false).inject(sitemap);
sitemap.getElements('li:last-child').addClass('ig-li-last-child');
var halfHeight = (Window.getHeight()*0.75).round();
var changeModal = new Modalbox({
title:window.translations('media-js-change_location'),
height:halfHeight,
adopt:sitemap,
onAdopt:function(){
this.bodypart.getElements('a').addEvent('click', function(event){
var newBaseURL = this.get('url') ? this.get('url') : '';
self.elements.parentId.value = this.get('parent-id');
self.elements.parentGuid.set('value',this.get('parent-guid'));
self.elements.segmentURL.fireEvent('revalidate','keyup');
self.elements.segmentURL.baseURL = newBaseURL.toLowerCase().replace(/ /g, "_");
self.elements.segmentURL.fireEvent('keyup');
changeModal.close();
event.stop();
});
}
});
},
recurseSitemap: function(object, isRoot, isSpaceChild){
var self = this;
if(!object){ return null; }
var rootNode = new Element('li');
var rootAnchor;
var encodedName = Utils.htmlencode(object.property.name);
if (isRoot){
rootAnchor = new Element('a', {
'href':'#',
'class': 'ig-community',
'title':window.translations('media-js-widget-change_location')+' '+object.property.url+'/'+self.values.segmentURL
}).set('text', Utils.htmldecode(object.property.name)).inject(rootNode, 'bottom');
} else if (self.options.edit && object.property.url == self.values.origBaseURL) {
// Skip the whole tree (can't move into itself)
return null;
} else {
switch (object.type){
case 'BlogFolder':
case 'ForumFolder':
case 'MicroBlogFolder':
rootAnchor = new Element('span', {
'class': 'ig-disabled ig-application'
}).set('html', encodedName).inject(rootNode, 'bottom');
break;
case 'Space':
if (self.arrays.allowedScope.contains('Space') && object.property.perms && object.property.perms.can_addChild.toString().toLowerCase() == 'true') {
rootAnchor = new Element('a', {
'href':'#',
'class': 'ig-application',
'title':window.translations('media-js-widget-change_location')+' '+object.property.url+'/'+self.values.segmentURL
}).set('html', encodedName).inject(rootNode, 'bottom');
} else {
rootAnchor = new Element('span', {
'class': 'ig-disabled ig-application'
}).set('html', encodedName).inject(rootNode, 'bottom');
}
break;
case 'Page':
// are we allowed to add pages?
var pageChildAllowed = false;
var hasSpaceParent = false;
if (self.options.pageInfo[object.property.object_id]) {
var allowedType = self.options.pageInfo[object.property.object_id].toString().toLowerCase();
if (allowedType == "unknown" || allowedType.contains("space") || allowedType.contains("page") || !object.children) {
pageChildAllowed = true;
}
}
if (this.options.currentObjectIsSpace && (object.property.parent_space_id && object.property.parent_space_id != "")) { // this is space and the object we are examining does not have the parent_space_id property
hasSpaceParent = true;
}
if ((self.options.checkPerms && object.property.perms.can_addChild.toString().toLowerCase() == 'true' || !self.options.checkPerms) && self.arrays.allowedScope.contains('Page') && pageChildAllowed && !hasSpaceParent) {
rootAnchor = new Element('a', {
'href':'#',
'title':window.translations('media-js-widget-change_location')+' '+object.property.url+'/'+self.values.segmentURL
}).set('html', encodedName).inject(rootNode, 'bottom');
} else {
rootAnchor = new Element('span', {
'class': 'ig-disabled'
}).set('html', encodedName).inject(rootNode, 'bottom');
}
break;
case 'BlogChannel':
case 'Calendar':
case 'FolderChannel':
case 'ForumChannel':
case 'MemberDirectory':
case 'MicroBlogChannel':
case 'Pulse':
case 'Wiki':
rootAnchor = new Element('span', {
'class': 'ig-disabled ig-channel'
}).set('html', encodedName).inject(rootNode, 'bottom');
break;
default:
rootAnchor = new Element('span', {
'class': 'ig-disabled'
}).set('html', encodedName).inject(rootNode, 'bottom');
}
}
rootAnchor.set('url', (object.property.url ? object.property.url : ''));
rootAnchor.set('parent-id', object.property.id);
rootAnchor.set('parent-guid', object.property.object_id);
if(object.property.id == self.values.parentId){
rootAnchor.addClass('ig-active');
}
if(object.property.show_in_nav && object.property.show_in_nav.toLowerCase() == "false" && !isRoot){
var hiddenText = new Element('span', {
'class':'ig-meta-light'
}).set('html', ' ' + window.translations('media-js-hidden'));
hiddenText.inject(rootAnchor, 'after');
}
if(object.children){
var childNodes = new Element('ul').inject(rootNode, 'bottom');
var isSpace = (object.type=='Space');
object.children.each(function(child){
var elem = self.recurseSitemap(child, false, isSpace);
if (elem) {
elem.inject(childNodes, 'bottom');
}
});
}
return rootNode;
}
});
document.addEvent('domready',function(){
if(Igloo && Igloo.asset_change_location){
var changeLink;
Object.each(Igloo.asset_change_location, function(object, id){
changeLink = new changeLocation(id, object);
});
}
});
window.addEvent('bootstrap4finished', function(){
if (window.dependents['change_location']) {
var changeLink;
window.dependents['change_location'].each(function(elem) {
changeLink = new changeLocation(elem.id, elem.dataobj['change_location']);
});
}
});
window.addEvent('domready', function() {
if (Igloo.asset_checkboxToggleShowHide) {
Object.each(Igloo.asset_checkboxToggleShowHide, function(object, id) {
var elem = $(id);
container = object.container;
isEnabled = object.isEnabled;
checkOption(elem, container);
if (isEnabled == 'True') {
$(container).removeClass('hide');
}
});
}
});
window.addEvent('bootstrap4finished', function() {
if (window.dependents['checkboxToggleShowHide']) {
window.dependents['checkboxToggleShowHide'].each(function(elem) {
container = elem.dataobj.checkboxToggleShowHide.container;
isEnabled = elem.dataobj.checkboxToggleShowHide.isEnabled;
checkOption(elem, container);
if (isEnabled == 'True') {
$(container).removeClass('hide');
}
});
}
});
function checkOption(elem, container) {
var el = elem;
el.addEvent('click', function() {
do_check = $(this).checked;
if (do_check) {
$(container).removeClass('hide');
} else {
$$('#'+container+' .uncheck-me').set('checked', do_check)
$(container).addClass('hide');
}
});
}
/*
Retyper
changes the user's input as they type, so it conforms to a limited character set.
intended for use in fields where the user is entering a URL
created by Ian Ring
for IGLOO Software
February 2010
*/
var Retyper = new Class({
Implements: [Options, Events],
options: {
elem: null,
allowed: '0-9a-z_@\-',
replace: [
{ 'before': ' ', 'after': '_' }
],
lowercase: true
},
initialize: function(options) {
var self = this;
this.setOptions(options);
var elem = this.options.elem;
elem.addEvent('keyup', function(e) { self.scrub(elem) });
elem.addEvent('mouseup', function(e) { self.scrub(elem) });
elem.addEvent('mouseup', function(e) { self.scrub(elem) });
elem.addEvent('change', function(e) { self.scrub(elem) });
elem.addEvent('focus', function(e) { self.scrub(elem) });
elem.addEvent('blur', function(e) { self.scrub(elem) });
if (document.body.onContextMenu) {
document.body.addEvent('ContextMenu', function() {
alert('cmenu');
});
}
if (elem.onpaste) {
elem.addEvent('paste', function(e) {
self.scrub(elem)
});
}
if (elem.onbeforepaste) {
elem.addEvent('beforepaste', function(e) {
self.scrub(elem)
});
}
if (elem.oninput) {
elem.addEvent('input', function(e) {
self.scrub(elem)
});
}
},
scrub: function(elem) {
var self = this;
if (elem.value != self.transform(elem.value)) {
var pos = self.getpos(elem);
// lower
if (this.options.lowercase) {
elem.value = elem.value.toLowerCase();
}
// replace space
this.options.replace.each(function(p) {
var from = p.before;
var to = p.after;
var pattern = from.escapeRegExp();
var modifiers = 'g'
var reg = new RegExp(pattern, modifiers);
elem.value = elem.value.replace(reg, to);
});
// remove
var pattern = '[^' + this.options.allowed + ']';
var modifiers = 'g'
var reg = new RegExp(pattern, modifiers);
var m = elem.value.match(reg);
if (m) {
pos = pos - m.length;
}
elem.value = elem.value.replace(reg, "");
// console.log(pos);
self.setpos(elem, pos);
}
this.fireEvent('scrub');
},
getpos: function(oField) {
var iCaretPos = 0;
if (document.selection) {
oField.focus();
var oSel = document.selection.createRange();
oSel.moveStart('character', -oField.value.length);
iCaretPos = oSel.text.length;
}
else if (oField.selectionStart || oField.selectionStart == '0') {
iCaretPos = oField.selectionStart;
}
return (iCaretPos);
},
setpos: function(oField, pos) {
// alert(pos);
if (document.selection) {
// alert('IE?');
//oField.focus ();
//var oSel = document.selection.createRange();
if (oField.createRange) {
var oSel = oField.createRange();
//oSel.moveStart ('character', -oField.value.length);
oSel.moveStart('character', pos);
oSel.moveEnd('character', pos);
oSel.select();
}
}
else if (oField.selectionStart || oField.selectionStart == '0') {
// alert('FF?');
oField.focus();
//oField.setSelectionRange(pos,pos);
oField.selectionStart = pos;
oField.selectionEnd = pos;
}
},
transform: function(str) {
var pat = new RegExp("[^" + this.options.allowed + "]*", "g");
var s = str.toLowerCase().replace(/ /g, "_").replace(pat, "");
return s;
}
});
//Retyper.implement(new Events, new Options);
/*
-----------------------------------------------------
* Class Name: ajaxCheckEmail
*
* Description: This class handles checking which setting for email enabled has been set and
validating that the entry provided for a custom email is correct.
*
* Dependent On: ApiClient, Retyper
*
* Notes: Are you not entertained? Is this not why you're here?
------------------------------------------------------
*/
var ajaxCheckEmail = new Class({
Implements: [Options, Events],
initialize: function(object, id) {
this.elem = $(id);
if (object.submitbuttons) {
this.submitButtons = $$('.'+object.submitbuttons);
}
this.defaultEmailAddress = $('email_community');
this.initialEmailValue = this.elem.get('value').trim();
this.customEmailAddress = $('email_on');
this.disableEmailAddress = $('email_off');
this.addEvents();
this.toggleLabelWarning();
var emailRetyper = new Retyper({
elem: this.elem,
allowed: '0-9a-z_\.\-', // note there's no @ in this, and we added the dot
replace: [
{ 'before': ' ', 'after': '_' }
],
lowercase: true
});
},
addEvents: function() {
var self = this;
this.defaultEmailAddress.addEvent('click', function() {
self.toggleLabelWarning();
destroypopup(self.elem);
self.enableSubmit();
});
this.customEmailAddress.addEvent('click', function() {
self.toggleLabelWarning();
self.elem.focus();
});
this.disableEmailAddress.addEvent('click', function() {
self.toggleLabelWarning();
destroypopup(self.elem);
self.enableSubmit();
});
this.elem.addEvent('blur', function() {
if (self.customEmailAddress.checked && (!self.initialEmailValue.ciCompare(self.elem.get('value')) || self.elem.get('value').trim() == "")) {
self.validateEmail(false);
}
});
this.form = $(this.elem.getParent('form'));
this.form.addEvent('submit', function(event) {
if (event) {
event.stop();
}
if (self.customEmailAddress.checked && (!self.initialEmailValue.ciCompare(self.elem.get('value')) || self.elem.get('value').trim() == "")) {
self.validateEmail(true);
} else {
self.form.submit();
}
});
},
toggleLabelWarning: function() {
var labelWarning = $('ig-emailwarning');
var showWarning = this.disableEmailAddress.checked;
if (showWarning) {
if (labelWarning) {
labelWarning.addClass('hide');
}
} else {
if (labelWarning) {
labelWarning.removeClass('hide');
}
}
},
disableSubmit: function() {
if (this.submitButtons) {
Array.each(this.submitButtons, function(button) {
$(button).addClass('ig-button_disabled');
$(button).set('disabled', 'disabled');
});
}
},
enableSubmit: function() {
if (this.submitButtons) {
Array.each(this.submitButtons, function(button) {
$(button).removeClass('ig-button_disabled');
$(button).removeProperty('disabled', 'disabled');
});
}
},
validateEmail: function(formSubmit) {
var emailAddress = this.elem.value.toString();
if (emailAddress.trim().length == 0) {
injectpopup(this.elem, window.translations('system-edit-Required_Field'));
} else {
// does the email exist in the community?
var self = this;
emailAddress = emailAddress + this.elem.getParent().getElement('.domain').innerHTML;
var emailCheck = new ApiClient({
'apimethod': 'community/addressedObjects/hasAddress',
'method': 'get',
'queryparams': {
'address': emailAddress
},
onSuccess: function(response) {
var returnjson = JSON.decode(response, true);
if (returnjson.response.name == "addressExists") {
if (returnjson.response.value) {
injectpopup(self.elem, window.translations('system-edit-address_already_used'));
} else {
destroypopup(self.elem);
if (formSubmit) {
self.form.submit();
}
}
}
},
onFailure: function(response) {
// error out.
var returnjson = JSON.decode(response, true);
injectpopup(self.elem, window.translations('apps-forums-error_invalidEmail'));
}
});
}
}
});
window.addEvent('domready', function() {
if (Igloo && Igloo.asset_checkemailexists) {
Object.each(Igloo.asset_checkemailexists, function(object, id) {
var checkEmail = new ajaxCheckEmail(object, id);
});
}
});
window.addEvent('bootstrap4finished',function(){
window.setTimeout(function(){apply_confirm(window.dependents['confirm']);},1);
});
window.addEvent('domready', function(){
var elements = [];
if(Igloo && Igloo.asset_confirm){
Object.each(Igloo.asset_confirm, function(object, id){
var elem = $(id);
if(!elem.dataobj || typeOf(elem.dataobj)!='hash'){
elem.dataobj = new Hash(elem.dataobj || object);
}
elem.dataobj.combine(object);
elements.push(elem);
});
apply_confirm(elements);
}
});
function apply_confirm(confirm_elements) {
if (!confirm_elements) { return; }
confirm_elements.each(function(elem){
if (elem.dataobj){
var dataobj = JSON.decode(elem.dataobj) || elem.dataobj;
if (dataobj['confirm']){
if (elem.tagName == "FORM"){
// we confirm on submit
elem.onsubmit = function(){
if(dataobj['confirm']['use_title'] == 'true'){
// we put this in for some backward compatibility
// alert(this.title);
var text = this.title.replace(/\\r\\n/g,'\r\n');
}else{
var text = dataobj['confirm']['confirmtext'].replace(/\\r\\n/g,'\r\n');
}
return confirm(text);
}
}
if (elem.tagName == "INPUT"){
if (elem.type.toLowerCase() == "radio"){
elem.onfocus = function(){
if(dataobj['confirm']['use_title'] == 'true'){
// we put this in for some backward compatibility
// alert(this.title);
var text = this.title.replace(/\\r\\n/g,'\r\n');
}else{
var text = dataobj['confirm']['confirmtext'].replace(/\\r\\n/g,'\r\n');
}
if(!elem.checked){
if(!confirm(text)){
elem.blur();
return false;
}else{
elem.click();
return true;
}
}
};
}
}
if (elem.tagName == "A"){
// we confirm on click
elem.onclick=function(){
if(dataobj['confirm']['use_title'] == 'true'){
var text = this.title.replace(/\\r\\n/g,'\r\n');
}else{
var text = dataobj['confirm']['confirmtext'].replace(/\\r\\n/g,'\r\n');
}
// do an HTML Decode. Yes, this is a downright dirty trick, but it works, and is
// surprisingly performant.
var tempDiv = document.createElement('div');
tempDiv.innerHTML = text;
var text = tempDiv.firstChild.nodeValue;
return confirm(text);
}
}
}
}
});
}
window.addEvent('bootstrap4finished',function(){
window.setTimeout(function(){apply_defaultfocus(window.dependents['defaultfocus']);},1);
});
window.addEvent('domready', function(){
var defaults = [];
if(Igloo && Igloo.asset_defaultfocus){
Object.each(Igloo.asset_defaultfocus, function(object, id){
var elem = $(id);
if(elem){
if(!elem.dataobj || typeOf(elem.dataobj)!='hash'){
elem.dataobj = new Hash(elem.dataobj || object);
}
elem.dataobj.combine(object);
defaults.push(elem);
}
});
window.setTimeout(function(){apply_defaultfocus(defaults);},500);
}
});
function apply_defaultfocus(defaults){
if (Igloo.isResponsiveMobile) {
return false; // Disable this feature on mobile devices
}
var temparray = new Array();
var size = 0;
if (defaults) size = defaults.length;
for(var i=0;i 0){
var thisElement = $(temparray[temparray.length-1]);
if (thisElement && thisElement.isVisible()) {
if (thisElement.focus) {
thisElement.focus();
}
if (thisElement.select) {
thisElement.select();
}
}
}
}
function applyExternallinks(elements) {
if ( elements == null ) {
return;
}
elements.each(function(elem){
elem.addEvent('click', function(event){
event.preventDefault();
window.open(this.href);
});
});
}
window.addEvent('domready', function() {
if (Igloo && Igloo.asset_externallinks) {
var elements = [];
Object.each(Igloo.asset_externallinks, function(object, id) {
var elem = $(id);
if ( elem ) {
elements.push(elem);
}
});
applyExternallinks(elements);
}
});
window.addEvent('bootstrap4finished', function() {
var elements = window.dependents['externallinks'] || [];
applyExternallinks(elements);
});
var ToggleHide = new Class({
Implements: [Options],
options: {
element: null,
// Showing elements are the elements that fire the Show() function
showingElement: null, // Use this for ID (Single)
showingElements: null, // Use this for Class (Multiple)
// This is the container that is shown on page load (it's showing)
// Only provide if you wish to toggle its visibility when hidingElement and showingElement are clicked
showingContainer: null, // Use this for ID (Single)
showingContainers: null, // Use this for Class (Multiple)
// Hiding elements are the elements that fire the Hide() function
hidingElement: null, // Use this for ID (Single)
hidingElements: null, // Use this for Class (Multiple)
// This is the container that is hidden on page load (it's hiding)
// Only provide if you wish to toggle its visibility when hidingElement and showingElement are clicked
hidingContainer: null, // Use this for ID (Single)
hidingContainers: null, // Use this for Class (Multiple)
targetElement: null, // Only provide if the target element is different than the asset element
autoFocus: false // Set this to true if you want to automaitcally focus on the first TextField within the targetElement
},
initialize: function (trigger, options) {
var self = this;
self.setOptions(options || {});
self.elements = new Hash();
self.elements.showingElement = (self.options.showingElement) ? $(self.options.showingElement) : null;
self.elements.showingElements = (self.options.showingElements) ? $$('.' + self.options.showingElements) : null;
self.elements.showingContainer = (self.options.showingContainer) ? $(self.options.showingContainer) : null;
self.elements.showingContainers = (self.options.showingContainers) ? $$('.' + self.options.showingContainers) : null;
self.elements.hidingElement = (self.options.hidingElement) ? $(self.options.hidingElement) : null;
self.elements.hidingElements = (self.options.hidingElements) ? $$('.' + self.options.hidingElements) : null;
self.elements.hidingContainer = (self.options.hidingContainer) ? $(self.options.hidingContainer) : null;
self.elements.hidingContainers = (self.options.hidingContainers) ? $$('.' + self.options.hidingContainers) : null;
self.elements.targetElement = (self.options.targetElement) ? $(self.options.targetElement) : $(trigger);
self.elements.firstTextBox = null;
if (self.options.autoFocus) {
var allTextBoxes = self.elements.targetElement.getElements('input[type=text]');
if (allTextBoxes.length > 0) {
self.elements.firstTextBox = allTextBoxes[0];
}
}
// The toggle capability of this asset is still weak
// - Needs optional toggle text capability
var isToggle = (self.options.showingElement == self.options.hidingElement) ? true : false;
if (self.elements.targetElement) {
if (isToggle && self.elements.showingElement) {
self.elements.showingElement.addEvent('click',function(event) {
event.stop();
self.toggle();
});
} else {
if (self.elements.showingElement) {
self.elements.showingElement.addEvent('click',function(event) {
event.stop();
self.show();
});
}
if (self.elements.showingElements) {
self.elements.showingElements.each(function(elem) {
elem.addEvent('click',function(event) {
event.stop();
self.show();
});
});
}
if (self.elements.hidingElement) {
self.elements.hidingElement.addEvent('click',function(event) {
event.stop();
self.hide();
});
}
if (self.elements.hidingElements) {
self.elements.hidingElements.each(function(elem) {
elem.addEvent('click',function(event) {
event.stop();
self.hide();
});
});
}
}
}
},
show: function() {
var self = this;
self.toggleShow();
},
toggleShow: function() {
var self = this;
self.elements.targetElement.removeClass('ig-togglehide');
if (self.elements.firstTextBox) {
self.elements.firstTextBox.focus();
}
// Add 'hide'
if (self.elements.showingContainer) {
self.elements.showingContainer.addClass('ig-togglehide');
}
if (self.elements.showingContainers) {
self.elements.showingContainers.each(function(elem) {
elem.addClass('ig-togglehide');
});
}
// Remove 'hide'
if (self.elements.hidingContainer) {
self.elements.hidingContainer.removeClass('ig-togglehide');
}
if (self.elements.hidingContainers) {
self.elements.hidingContainers.each(function(elem) {
elem.removeClass('ig-togglehide');
});
}
},
hide: function() {
var self = this;
self.toggleHide();
},
toggleHide: function() {
var self = this;
self.elements.targetElement.addClass('ig-togglehide');
// Remove 'hide'
if (self.elements.showingContainer) {
self.elements.showingContainer.removeClass('ig-togglehide');
}
if (self.elements.showingContainers) {
self.elements.showingContainers.each(function(elem) {
elem.removeClass('ig-togglehide');
});
}
// Add 'hide'
if (self.elements.hidingContainer) {
self.elements.hidingContainer.addClass('ig-togglehide');
}
if (self.elements.hidingContainers) {
self.elements.hidingContainers.each(function(elem) {
elem.addClass('ig-togglehide');
});
}
},
toggle: function() {
var self = this;
if (self.elements.targetElement.hasClass('ig-togglehide')) {
self.elements.targetElement.removeClass('ig-togglehide');
} else {
self.elements.targetElement.addClass('ig-togglehide');
}
}
});
window.addEvent('domready', function(){
if (Igloo.asset_togglehide) {
var newToggleHide;
Object.each(Igloo.asset_togglehide, function (options, id) {
newToggleHide = new ToggleHide(id, options);
});
}
});
window.addEvent('bootstrap4finished', function() {
if (window.dependents['togglehide']) {
// the old bootstrap4 attaches dataobj as a string, not a Hash
// bootstrap4velo attaches the dataobj as a Hash, not a string. wheeee!
window.dependents['togglehide'].each(function(elem) {
var toggle = new ToggleHide(elem.id, elem.dataobj.togglehide);
});
}
});
var FolderTreeView = new Class({
Implements: Options,
options: {
data: {},
tableId: '',
expandClass: 'ig-expand',
loadingClass: 'ig-loading',
expandedClass: 'ig-expanded',
collapsedClass: 'ig-collapsed'
},
initialize: function(options) {
var self = this;
this.setOptions(options);
this.table = $(this.options.tableId);
if (!this.table) {
return false;
}
// This Pseudo selector returns elements that contain a span with class 'ig-expanded'
// Helps with performance when collapsing trees
Slick.definePseudo('igWorkareaExpanded', function() {
return this.getElement('.' + self.options.expandedClass);
});
this.table.addEvent('ig-collapse', this.recursiveCollapse.bind(this));
this.table.addEvent('click', function(event) {
var elem = $(event.target);
if (elem && elem.hasClass(this.options.expandClass)) {
var parentTR = elem.getParent('tr');
// Expand the tree
if (elem.hasClass(this.options.collapsedClass)) {
var parentId = parentTR.getProperty('id');
var children = parentTR.getAllNext('.' + parentId); // parentTR.getAllNext is ~17% faster than table.getElements in my test case. -NK
if (children.length) {
children.removeClass('hide');
elem.removeClass(this.options.collapsedClass);
elem.addClass(this.options.expandedClass);
} else {
this.getChildren(elem, parentId, parentTR);
}
}
// Collapse the tree
else if (elem.hasClass('ig-expanded')) {
this.table.fireEvent('ig-collapse', [parentTR]);
}
}
} .bind(this));
// it's good practice to return the created instance of the class so that it can be assigned to a variable for reference.
return this;
},
getChildren: function(elem, parentId, parentTR) {
var data = this.options.data;
data.objectId.value = parentId.replace('childId_', '');
// ~~~ BEGIN :: Util Function
var postdataJSON = {};
var paramList = [];
var paramTypes = [];
var queryparamsJSON = {};
Object.each(data, function(val, key) {
paramList.push(key);
paramTypes.push(val.type);
queryparamsJSON[key] = val.value;
});
postdataJSON.paramList = paramList.join(",");
postdataJSON.paramTypes = paramTypes.join(",");
// ~~~ END :: Util Function
var apiOptions = new ApiClient({
'headers': { 'Accept': 'application/xml' },
'apimethod': 'igloo/widgets/38/render',
'postdata': postdataJSON,
'queryparams': queryparamsJSON,
onRequest: function(instance) {
elem.removeClass(this.options.collapsedClass);
elem.addClass(this.options.loadingClass);
} .bind(this),
onSuccess: function(text, xml) {
var APIresponse = Utils.IARParse(xml);
var tempTable = new Element('table', { 'html': APIresponse.apihtml });
var TRs = tempTable.getElements('tr');
// Adding the class 'hide' (display:none) supresses the CSS redraw until all elements are added
TRs.addClass('hide');
var target = parentTR;
var archivedSummary;
var parentElem = $(parentId);
var parentClasses = parentElem.get('class');
var parentChildClasses = [];
if (parentClasses) {
parentClasses = parentClasses.trim().split(" ");
Array.each(parentClasses, function(classString) {
if (classString.ciContains('childId_')) {
parentChildClasses.include(classString)
}
});
}
TRs.each(function(TR) {
TR.addClass(parentId);
Array.each(parentChildClasses, function(className) {
TR.addClass(className);
});
// TODO: Need a more elegant solution to indenting TRs
// HACK
var parentPadding = parentTR.getElement('td.name').getStyle('padding-left').toInt();
TR.getElement('td.name').setStyle('padding-left', parentPadding + 20 + 'px');
TR.inject(target, 'after');
target = TR;
// Apply events for archive toggle
if (target.hasClass('js-archiveToggle')) {
// This is the target to Bootstrap
archivedSummary = target;
}
var likeBtn = TR.getElement('span.ig-meta-like');
if (likeBtn) {
bootstrap(likeBtn);
}
});
// Bootstrap JavaScript behaviours
if (archivedSummary) {
bootstrap(archivedSummary);
}
// Unhide the TRs and let the browser draw it all
TRs.removeClass('hide');
// Clean up
tempTable.destroy();
elem.removeClass(this.options.loadingClass);
elem.addClass(this.options.expandedClass);
this.table.fireEvent('ig-expand', [parentTR]);
} .bind(this),
onFailure: function(instance) {
//console.log(['failed', arguments]);
elem.removeClass(this.options.loadingClass);
elem.addClass(this.options.CollapsedClass);
} .bind(this)
});
},
// Recursive method to collapse a tree and any open sub-trees
recursiveCollapse: function(parentTR) {
parentTR = $(parentTR);
var elemId = parentTR.getProperty('id');
var children = parentTR.getAllNext('.' + elemId); // parentTR.getAllNext is ~23% faster than table.getElements in my test case. -NK
children.addClass('hide');
// Using 'filter' combined with the pseudo selector increased performance by an order of magnitude (886ms vs 78ms)
var expandedTRs = children.filter('tr:igWorkareaExpanded');
expandedTRs.each(function(elem) {
this.table.fireEvent('ig-collapse', [elem]);
} .bind(this));
var trigger = parentTR.getElement('.' + this.options.expandClass);
if (trigger) {
trigger.removeClass(this.options.expandedClass);
trigger.addClass(this.options.collapsedClass);
}
}
});
window.addEvent('domready', function(){
if( Igloo && Igloo.asset_folderTreeView ){
var FolderTreeViewInstance = [];
Object.each(Igloo.asset_folderTreeView, function(object, id){
if( $(id) && object.data ){
FolderTreeViewInstance.push( new FolderTreeView({'tableId':id, 'data':object.data}) );
}
});
}
// fix the add files link
if ($('folder-file-add')) {
var uploadAbility = Utils.uploadCapabilities();
var currentURI = new URI(document.URL);
if (uploadAbility === Igloo.uploadCapabilities.HTML5 || uploadAbility === Igloo.uploadCapabilities.HTML5_NOCHUNK) {
$('folder-file-add').set('href',currentURI.setData("action", "add_files"));
} else if (uploadAbility === Igloo.uploadCapabilities.FLASH) {
$('folder-file-add').set('href',currentURI.setData("action", "add_files_v1"));
} else {
$('folder-file-add').set('href',currentURI.setData("action", "add_file"));
}
}
});
/******************************************
jsTabs by Dacheng Cheng
This JS will implement the tabs interface for users. To use, tabs must be attached to
active tabs have class ig-activeTab, active panes have class ig-activePane
******************************************/
var jsTabs = new Class({
Implements: [Options, Events],
options: {
'tabs': null, //expecting the id of the htmlelement that has all the tabs inside as children
'panes': null, //expecting the id of the htmlelement that has all the panes inside as children
'tabsClass': null, // the class to look for within the container. Container MUST exist
'panesClass': null, // the class to look for panes within the container
'container': null,
'triggerEvent': 'click',
'paneless': null, //whether or not we'll be using paneless tabs, which requires the use of ids and triggers, which is far easier to handle. get it? painless? sample paneless:[{'tabId':'tabId','elems':[elem1,elem2,elem3...]},{...}...]
'locationchange': true, // disable this if you don't want the #tabname at the end of the URL
'disableHidden': false // disable all form fields on hidden panels when forms exist
},
initialize: function(id, menu, options) {
var self = this;
// set the options
this.setOptions(options || {});
self.elements = {};
// set the parameters
self.elements.container = $(self.options.container);
self.elements.tabs = $(self.options.tabs);
self.elements.panes = $(self.options.panes);
if (self.options.paneless != null) { //paneless tabs exist!
self.plts = [];
self.paneless = true;
//build out the objects with references to the actual elements instead of just Ids
self.options.paneless.each(function(panelessItem) {
if (panelessItem) {
var panelessObj = {};
panelessObj.tab = $(panelessItem.tabId);
panelessObj.elems = [];
panelessItem.elems.each(function(elem) {
panelessObj.elems.push($(elem));
});
self.plts.push(panelessObj);
}
});
} else if (!self.elements.tabs || !self.elements.panes) {
//if either the tabs specified or the panes specified does not exist, assume we're going to be extracting them via tabsClass and panesClass inside a container
if (self.elements.container) { //make sure the container exists
self.tablist = self.elements.container.getElements("." + self.options.tabsClass);
self.panelist = self.elements.container.getElements("." + self.options.panesClass);
}
} else {
//ok, tabs and panes both exist
self.tablist = self.elements.tabs.getChildren();
self.panelist = self.elements.panes.getChildren();
}
//if we are doing paneless, then this. otherwise, we go to the paneful method
if (self.paneless) {
//for each of the tab, add the event to change pane
self.plts.each(function(panelessObj) {
panelessObj.tab.addEvent('click', function(event) {
if (!self.options.locationchange) {
event.preventDefault();
}
self.activate(panelessObj);
});
});
} else if (self.tablist.length == self.panelist.length && self.tablist.length > 0) {
//great, now we have tablist and panelist, we have to assume that they are 1 to 1. why would you have two tabs respond to one pane?!?! go make your own js
//determine if we need to use onChange for select field of default functionality
if (self.options.triggerEvent == 'change') {
var selectBox = self.elements.container.getElement('select');
selectBox.addEvent('change', function(event) {
var ind = this.selectedIndex;
self.changePane(ind);
});
} else {
self.tablist.each(function(tab, ind) {
tab.addEvent('click', function(event) {
if (!self.options.locationchange) {
event.preventDefault();
}
self.changePane(ind);
});
});
}
//checking the window.location to see if we need to change the panes right away. yeah, dacheng is awesome like that.
if (self.options.locationchange) {
var currentlocation = window.location.hash;
if (currentlocation.length > 0) {
var locationhashname = currentlocation.substring(1);
self.tablist.each(function(tab, ind) {
var tabanchor = tab.getElement('.aname');
if (tabanchor) {
if (tabanchor.get('name') == locationhashname) {
self.changePane(ind);
}
}
});
} else {
//make sure we're on the first tab that isn't a default-panel
}
}
}
},
changePane: function(paneNum) {
//change the pane by hiding all the other ones and setting
var self = this;
if ($('activePanelCount')) {
$('activePanelCount').value = paneNum + 1;
}
self.tablist.each(function(tab, ind) {
var tab = self.tablist[ind];
var pane = self.panelist[ind];
if (ind != paneNum) {
tab.removeClass('ig-activeTab');
pane.addClass('hide').removeClass('ig-activePane');
if (self.options.disableHidden == true) {
if (pane.getElements('input')) {
pane.getElements('input').set('disabled', 'disabled');
}
if (pane.getElements('select')) {
pane.getElements('select').set('disabled', 'disabled');
}
}
} else {
tab.addClass('ig-activeTab');
pane.addClass('ig-activePane').removeClass('hide');
if (self.options.disableHidden == true) {
if (pane.getElements('input')) {
pane.getElements('input').removeProperty('disabled');
}
if (pane.getElements('select')) {
pane.getElements('select').removeProperty('disabled');
}
}
}
});
},
activate: function(plo) {
//elemArr is an array of elements that we're activating
var self = this;
self.plts.each(function(panelessObj) {
panelessObj.elems.each(function(elem) {
elem.addClass('hide');
});
panelessObj.tab.removeClass('ig-activeTab');
});
plo.tab.addClass('ig-activeTab');
plo.elems.each(function(elem) {
elem.removeClass('hide');
});
}
});
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_jsTabs) {
Igloo.tabs = (Igloo.tabs || new Hash());
Object.each(Igloo.asset_jsTabs, function(object, id){
Igloo.tabs.include(id, new jsTabs(id, null, object));
});
}
});
window.addEvent('domready', function(){
var readonlyclassname;
var theform;
Object.each(Igloo.asset_multicheckboxes, function(options, id){
theform = $(id);
if( theform && options.readonlyClassName){
/* some settings... */
readonlyclassname = options.readonlyClassName;
deleteprompt = (options.confirmtext) ? options.confirmtext : window.translations('apps-workarea-Delete_Prompt');;
/* we want the buttons to go disabled after click, to prevent double-click weirdness. */
theform.onsubmit = function(){
$$('.js-multicheckboxes-dependency-valid').each(function(but){
but.disabled = true;
});
}
}
});
if (theform) {
var thetable = theform.getElements('table')[0];
var thecheckboxheadercell;
var bulkselectcheckbox;
var thecheckboxes = new Array();
var thecheckboxcells = new Array();
var displayselectedcount = theform.getElements('span.counter');
var displayreadonlycount = theform.getElements('span.counter-readonly');
var displayreadonly = theform.getElements('span.highlight-readonly');
var buttonsenabledifany = $$('.js-multicheckboxes-dependency-any');
var buttonsenabledifvalid = theform.getElements('.js-multicheckboxes-dependency-valid');
var multiplecheckboxesdeselectreadonly = theform.getElements('.multiplecheckboxes-deselectreadonly');
var multicheckboxtooltrigger = $('multicheckboxtooltrigger');
var submitformelement = $('manageitems');
var injectelement = new Element('span',{'class':'ig-loader-small busy'}).setProperties({'id':'busy-icon'}).set('html'," ");
buttonsenabledifvalid.addEvent('click', function() {
injectelement.inject(this,'after');
injectelement.setStyles({'visibility':'visible', 'display':'inline','width':'16px'});
});
submitformelement.addEvent('submit', function(){
var busyicon = $('busy-icon');
if(busyicon) {
buttonsenabledifvalid.each(function(but) {
but.disabled = false;
});
if (confirm(deleteprompt)) {
return true;
} else {
injectelement.destroy();
return false;
}
}
});
if ( !multicheckboxtooltrigger ) { return; }
var isreadonly;
var trs = thetable.getElements('tr');
for (var i=0;i 0) {
var thisinput = thisinputarr[0];
if (isreadonly){
thisinput.isreadonly = true;
}else{
thisinput.isreadonly = false;
}
thisinput.parentcell = tds[0];
thisinput.parentrow = trs[i];
thecheckboxcells.push(tds[0]);
thecheckboxes.push(thisinput);
}
}
}
}
// remember, firefox keeps your form settings on reload and back.
// reset the highlighting and stats now
refresh();
multicheckboxtooltrigger.addEvent('click', function(){
theform.toggleClass('js-hidemulticheckboxes');
theform.getElements('.action').toggleClass('hide');
/*
thecheckboxheadercell.toggleClass('hide');
thecheckboxcells.each(function(elem){
elem.toggleClass('hide');
});
*/
});
thetable.addEvent('ig-expand', function(parentTR){
var children = thetable.getElements('.'+parentTR.id)
if( theform.hasClass('js-hidemulticheckboxes') ){
children.each(function(TR){
TR.getElement('td.action').addClass('hide');
});
}else{
children.each(function(TR){
TR.getElement('td.action').removeClass('hide');
});
}
});
multiplecheckboxesdeselectreadonly.each(function(item){
item.onclick = function(){
thecheckboxes.each(function(elem){
if (elem.isreadonly) {
elem.checked = false;
// elem.parentcell.removeClass('highlight-readonly');
}
})
refresh();
}
});
bulkselectcheckbox.onclick=function(){
if (bulkselectcheckbox.checked){
//var thecheckboxes = $$('.js-multicheckboxes');
thecheckboxes.each(function(elem){
elem.checked = true;
})
}else{
//var thecheckboxes = $$('.js-multicheckboxes');
thecheckboxes.each(function(elem){
elem.checked = false;
})
}
refresh();
};
document.addEvent('click', function(event){
if( !event.rightClick ){
var target = $(event.target);
if( target.hasClass('js-multicheckboxes') ){
refresh();
}
}
});
}
/*
thecheckboxes.each(function(elem){
elem.onclick=function(){
refresh();
}
})
*/
function refresh(){
var countchecked = 0;
var countreadonlychecked = 0;
var actionsenabled = true;
var allchecked = true;
//var thecheckboxes = $$('.js-multicheckboxes');
for (var i=0;i 0)?'inline':'none');
});
}
});
/*------ AUTOGROW TEXTAREA ------*/
var noteExpand = new Class({
Implements: [Options, Events],
options: {
interval: 333, // update interval in milliseconds
margin: 18, // gap (in px) to maintain between last line of text and bottom of textarea
minHeight: 18 // minimum height of textarea
},
initialize: function(textarea, options) {
this.textarea = $(textarea) ? $(textarea) : textarea;
this.options.minHeight = textarea.clientHeight;
this.setOptions(options);
this.noteGhost = new Element("div");
var thewidth = this.textarea.getSize().x - 18;
this.noteGhost.set('styles',{
"overflow-x" : "hidden",
"position" : "absolute",
"top" : "0px",
"left" : "-9999px",
"min-height" : "18px",
"word-wrap" : "break-word",
"width" : thewidth //Auto adjust to browser width of textarea
// We get the text area styles to keep everything consistant
});
this.noteGhost.setStyles(this.textarea.getStyles("font-size", "font-family", "line-height", "padding")).inject(document.body);
this.timer = this.resize.periodical(this.options.interval, this);
this.attachEvents();
},
attachEvents: function() {
var self = this;
this.textarea.addEvents({
'blur': self.validateTextArea.bind(self),
'keyup': self.validateTextArea.bind(self)
});
},
kill: function() {
clearInterval(this.timer);
},
resize: function() {
var html = this.textarea.get('value').replace(/\n|\r\n/g, '
X');
if (this.noteGhost.get("html").toLowerCase() != html.toLowerCase()){
this.noteGhost.set("html", html);
var triggerHeight = this.noteGhost.getSize().y;
if (this.textarea.clientHeight != triggerHeight) {
var newHeight = Math.max(this.options.minHeight, triggerHeight);
this.textarea.tween("height", newHeight);
}
}
},
validateTextArea: function() {
var textAreaSize = 0;
if (this.textarea && this.options.publishbutton && this.options.draftbutton) {
// IE8 reads the properties of textareas differently from Chrome & FF
if (this.textarea.innerText) {
textAreaSize = this.textarea.innerText.length;
} else {
textAreaSize = this.textarea.textLength;
}
if (textAreaSize > this.options.maxlength) {
//disable publish and draft buttons
$(this.options.draftbutton).addClass('ig-button_disabled');
$(this.options.draftbutton).set('disabled','disabled');
$(this.options.publishbutton).addClass('ig-button_disabled');
$(this.options.publishbutton).set('disabled','disabled');
injectpopup($(this.textarea),window.translations('media-js-file-Bad_Description'));
} else {
//enable publish and draft buttons
$(this.options.draftbutton).removeClass('ig-button_disabled');
$(this.options.draftbutton).set('disabled',null);
$(this.options.publishbutton).removeClass('ig-button_disabled');
$(this.options.publishbutton).set('disabled',null);
destroypopup($(this.textarea));
}
}
}
});
var resetField = new Class({
Implements: [Options, Events],
options:{
'triggerId': null,
'fieldId': null,
'resetValue': null
},
initialize:function(trigger, options){
var self = this;
// set the options
self.setOptions(options || {});
// Mandatory
self.elements = {};
if (self.options.triggerId) {
self.elements.trigger = $(self.options.triggerId);
} else {
self.elements.trigger = $(trigger);
}
self.elements.field = $(self.options.fieldId);
// Optional
if (self.options.resetValue) {
self.resetValue = self.options.resetValue;
} else {
self.resetValue = "";
}
self.elements.trigger.addEvent('click',function( event ){
event.stop();
self.resetField();
});
},
resetField:function(){
var self = this;
self.elements.field.value = self.resetValue;
}
});
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_resetField) {
var resetFieldInstance;
Object.each(Igloo.asset_resetField, function(object, id){
resetFieldInstance = new resetField(id, object);
});
}
});
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_smoothScroller) {
var myTransition = new Fx.Transition(Fx.Transitions.Sine);
var myFx = new Fx.Scroll(window, {
duration: 300,
transition: myTransition.easeOut,
onComplete: function(){
window.location.href = newLocation;
}
});
var elem;
Object.each(Igloo.asset_smoothScroller, function(object, id){
elem = $(id);
if (elem) {
var scrollToId = elem.href.split('#')[1];
var scrollToElem = $(scrollToId);
if (scrollToElem) {
var xPos = 0;
var yPox = scrollToElem.getPosition().y;
elem.addEvent('click', function(event){
event.preventDefault();
//window.location.href = '#'+scrollToId;
newLocation = '#'+scrollToId;
myFx.start(xPos, yPox);
});
}
}
});
}
});
window.addEvent('domready',function(){
//Toggle click functionality
$$('.comp-editsection .toggle').addEvent('click', function(e){
edittoggle($(this));
});
$$('.comp-editsection .panel').each(function(panelElem){
var isthiscookiehidden = Cookie.read(panelElem.id) == 'hidden';
if (isthiscookiehidden) {
panelElem.addClass('hide');
panelElem.getParent('div').getChildren('.toggle')[0].removeClass('toggleflip');
};
});
});
function edittoggle(e){
if($('comp-minimodalshadow')){
$('comp-minimodalshadow').destroy();
$('minimodalform').destroy();
}
var panel = e.getParent('div').getChildren('.panel')[0];
var ishidden = panel.hasClass('hide');
var cookiename = panel.id;
if(ishidden){
panel.removeClass('hide');
e.addClass('toggleflip');
Cookie.write(cookiename,'null',{'path':'/'});
}else{
panel.addClass('hide');
e.removeClass('toggleflip');
Cookie.dispose(cookiename);
Cookie.write(cookiename,'hidden',{'path':'/'});
}
}
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_toggleslider) {
// this script is accomplishing a one-to-many slider toggle
// var slidertoggles = $$('.js-toggleslider-trigger');
var slidertoggles = [];
Object.each(Igloo.asset_toggleslider, function(object, id){
var elem = $(id);
if(!elem.dataobj || typeOf(elem.dataobj)!='hash'){
elem.dataobj = new Hash(elem.dataobj || object);
}
elem.dataobj.combine(object);
slidertoggles.push(elem)
});
var slidersliders = $$('.js-toggleslider-slider');
var toggleslider=[];
var togglesliderfx=[];
for (var i=0;i originalPosition + this.options.offsets[this.move] && paused != true) {
this.setPosition(moveBy - originalPosition + 18); // 18 buffer from top
} else {
this.setPosition(this.options.offsets[this.move]);
}
}.bind(this);
window.addEvent('scroll', action);
window.addEvent('load', action);
window.addEvent('resize', action);
window.addEvent('verticalfollowreset', action);
},
setPosition: function(move) {
this.menu.tween(this.options[this.property],move);
return this;
}
});
window.addEvent('domready', function(){
if (Igloo.asset_verticalfollow) {
Object.each(Igloo.asset_verticalfollow, function (options, id) {
var elem = $(id);
new verticalFollow(elem, options);
});
}
});Element.implement({
ajaxDelete: function(objectId, message) {
var confirmDelete = true;
if (message) {
confirmDelete = confirm(message);
}
if (confirmDelete) {
var apiMethod = 'objects/' + objectId + '/delete';
var apiMethodMarker = $$('input[name=deleteapiurl]')[0];
if (apiMethodMarker && apiMethodMarker.get('value') != "") {
// This gets a value from a hidden input on the page. This input allows for semi-automatic variable substitution thusly:
// {} (the actual javascript variable name inside of curly brackets.) It should be able to handle
// multiple substitutions.
apiMethod = apiMethodMarker.get('value');
var apiMethodReplacements = apiMethod.match(/\{.*\}/g);
Array.each(apiMethodReplacements, function(replacement) {
replacement = replacement.replace('{', '').replace('}','');
var replacementVar = eval(replacement);
apiMethod = apiMethod.replace('{'+replacement+'}', replacementVar);
});
}
var errormsg;
var children = $$('.childId_' + objectId);
var self = this;
new ApiClient({
'apimethod': apiMethod,
onRequest: function() {
// hide the element from the user immediately to give the illusion of instant response.
self.hideFade();
// hide any children as well
children.each(function(elem) {
elem.hideFade();
});
},
onFailure: function(xhr) {
// unhide element
(function() {
self.fade('show');
self.removeClass('hide')
}).delay(500);
// unhide children
if (children && children.length > 0) {
children.each(function(elem) {
elem.fade('show');
elem.removeClass('hide');
}).delay(500);
}
var returnstring = xhr.responseText;
var returnjson = JSON.decode(returnstring, true);
if (returnjson != null) {
// Errors Present in Post
if (returnjson.exception != null) {
// Throw specific error if user doesn't have perms to delete all objects in folder
if (returnjson.exception.statusCode == 500 && returnjson.exception.innerException.errorId == 659879) {
Utils.modalAlert(window.translations('media-js-folder_insufficent_perms'));
} else {
Utils.modalAlert(window.translations('media-js-api_error-delete'));
}
}
}
}
});
}
}
});
window.addEvent('domready', function(){
if (Igloo && Igloo.asset_url_retyper_field) {
Object.each(Igloo.asset_url_retyper_field, function(object, id){
var r = new Retyper({
'elem':$(id),
'allowed':object.allowed, //Listing of characters that will not be removed (e.g. '0-9a-z_')
'lowercase':object.lowercase // true is the default value.
});
});
}
});var SetChannelColor = new Class({
initialize: function(){
this.optionNone = $('channel_color_none');
this.optionCustom = $('channel_color_custom');
this.colors = $$('#channelColorSelectors .ig-channel-tag');
this.addHandlers();
},
addHandlers: function() {
var self = this;
// Add Click event for each color
this.colors.each(function(elem) {
elem.addEvent('click',function(event) {
event.stop();
self.setColor(this);
self.setCheckmark(this);
});
});
// Add Click event for color option "None" - reset checkmark selector
this.optionNone.addEvent('click', function(event) {
self.setCheckmark(this);
});
},
setColor: function(elem) {
this.optionCustom.set({
'value': elem.id,
'checked': 'checked'
});
},
setCheckmark: function(target) {
this.colors.each(function(elem) {
elem.removeClass('active');
if (target.id == elem.id) {
elem.addClass('active');
}
});
}
});
window.addEvent('domready', function() {
if (Igloo.asset_setChannelColor) {
Object.each(Igloo.asset_setChannelColor, function(options, id) {
var elem = $(id);
if (elem) {
var channelColor = new SetChannelColor();
}
});
}
});