// ================================================
// PHP image browser - iBrowser
// ================================================
// iBrowser - wysiwyg editor interface (IE & Gecko)
// for tinyMCE, FCKeditor, SPAW, Xinha, and HTMLarea
// ================================================
// Developed: net4visions.com
// Copyright: net4visions.com
// License: GPL - see license.txt
// (c)2005 All rights reserved.
// File: common.js
// ================================================
// Revision: 1.0 Date: 08/10/2006
// ================================================
//=========================================================================
// common code for all wysiwyg editor interfaces like tinyMCE, FCKeditor,
// SPAW, Xinha, and HTMLarea
//=========================================================================
// initiate iBrowser object
function iBrowser() {
}
var ib = new iBrowser;
//-------------------------------------------------------------------------
// open iBrowser
function iBrowser_open() {
ib.oEditor.contentWindow.focus();
var wArgs = {};
var elm = ib.selectedElement;
if (elm != null) { // if element
if (elm.nodeName.toLowerCase() == 'img') { // selected object is image
var oImageElement = elm;
var oLinkElement = oImageElement.parentNode.nodeName.toLowerCase() == 'a' ? oImageElement.parentNode : null;
var oCaptionElement = ib.getNextSiblingByName(oImageElement, 'span');
ib.getImgParam(oImageElement, wArgs); // set image parameters )
if (oLinkElement) { // set popup parameters
var oCaptionElement = ib.getNextSiblingByName(oLinkElement, 'span');
ib.getLinkParam(oLinkElement, wArgs);
}
} else if (elm.nodeName.toLowerCase() == 'a') { // selected object is link
var oLinkElement = elm;
var oImageElement = oLinkElement.childNodes[0].nodeName.toLowerCase() == 'img' ? oLinkElement.childNodes[0] : null;
var oCaptionElement = ib.getNextSiblingByName(oLinkElement, 'span');
ib.getLinkParam(oLinkElement, wArgs); // set popup parameters
if (oImageElement) { // if first child is image
ib.getImgParam(oImageElement, wArgs); // set image parameters
}
} else if (elm.nodeName.toLowerCase() == 'span') { // selected element is caption container
var oCaptionElement = ib.getChildByName(elm, 'span');
if (ib.isCaption(oCaptionElement)) { // check to see whether it is a caption element
if (elm.childNodes[0].nodeName.toLowerCase() == 'img') {
var oImageElement = elm.childNodes[0];
ib.getImgParam(oImageElement, wArgs);
} else if (elm.childNodes[0].nodeName.toLowerCase() == 'a') {
var oLinkElement = elm.childNodes[0];
var oImageElement = oLinkElement.childNodes[0].nodeName.toLowerCase() == 'img' ? oLinkElement.childNodes[0] : null;
ib.getLinkParam(oLinkElement, wArgs); // set popup parameters
if (oImageElement) { // if first child is image
ib.getImgParam(oImageElement, wArgs); // set image parameters
}
}
} else { // selected element is caption text
oCaptionElement = elm;
if (ib.isCaption(oCaptionElement)) { // check to see whether it is a caption element
if (oCaptionElement.previousSibling.nodeName.toLowerCase() == 'img') {
var oImageElement = oCaptionElement.previousSibling;
ib.getImgParam(oImageElement, wArgs);
} else if (oCaptionElement.previousSibling.nodeName.toLowerCase() == 'a') {
var oLinkElement = oCaptionElement.previousSibling;
var oImageElement = oLinkElement.childNodes[0].nodeName.toLowerCase() == 'img' ? oLinkElement.childNodes[0] : null;
ib.getLinkParam(oLinkElement, wArgs); // set popup parameters
if (oImageElement) { // if first child is image
ib.getImgParam(oImageElement, wArgs); // set image parameters
}
}
}
}
}
//-------------------------------------------------------------------------
// set caption argument
ib.isCaption(oCaptionElement) ? wArgs.caption = 1 : '';
ib.isCaption(oCaptionElement) ? wArgs.captionClass = oCaptionElement.parentNode.attributes['class'].value : '';
}
//-------------------------------------------------------------------------
// open iBrowser dialog
if (ib.isMSIE) { // IE
var rArgs = showModalDialog(ib.baseURL, wArgs, 'dialogHeight:500px; dialogWidth:580px; scrollbars: no; menubar: no; toolbar: no; resizable: no; status: no;');
if (rArgs) { // returning from iBrowser (IE) and calling callback function
iBrowser_callback('','',rArgs);
}
} else if (ib.isGecko) { // Gecko
var wnd = window.open(ib.baseURL + '?editor=' + ib.editor + '&callback=iBrowser_callback', 'ibrowser', 'status=no, modal=yes, width=625, height=530');
wnd.dialogArguments = wArgs;
}
}
//-------------------------------------------------------------------------
// iBrowser callback
function iBrowser_callback(editor, sender, iArgs) {
if (iArgs) { // IE
var rArgs = iArgs;
} else { // Gecko
var rArgs = sender.returnValue;
}
ib.oEditor.contentWindow.focus();
var elm = ib.selectedElement;
if (elm != null) {
if (elm.nodeName.toLowerCase() == 'img') { // is current cell a image ?
var oImageElement = elm;
}
if (elm.nodeName.toLowerCase() == 'a') { // is current cell a link ?
var oLinkElement = elm;
}
if (elm.nodeName.toLowerCase() == 'span') {
if (elm.childNodes[0] && elm.childNodes[0].nodeName.toLowerCase() == 'img') { // caption container
var oImageElement = elm.childNodes[0];
} else if (elm.previousSibling && elm.previousSibling.nodeName.toLowerCase() == 'img') { // caption text
var oImageElement = elm.previousSibling;
}
}
}
if (rArgs) {
if (!rArgs.action) { // no action set - image
if (!oImageElement) { // new image// no image - create new image
ib.oEditor.contentWindow.document.execCommand('insertimage', false, rArgs.src);
oImageElement = ib.getElementByAttributeValue(ib.oEditor.contentWindow.document, 'img', 'src', rArgs.src);
}
// set image attributes
ib.setAttrib(oImageElement, 'src', rArgs.src, true);
ib.setAttrib(oImageElement, 'alt', rArgs.alt, true);
ib.setAttrib(oImageElement, 'title', rArgs.title, true);
ib.setAttrib(oImageElement, 'align', rArgs.align, true);
ib.setAttrib(oImageElement, 'border', rArgs.border);
ib.setAttrib(oImageElement, 'hspace', rArgs.hspace);
ib.setAttrib(oImageElement, 'vspace', rArgs.vspace);
ib.setAttrib(oImageElement, 'width', rArgs.width);
ib.setAttrib(oImageElement, 'height', rArgs.height);
ib.isMSIE ? ib.setAttrib(oImageElement, 'className', rArgs.className, true) : ib.setAttrib(oImageElement, 'class', rArgs.className, true);
// set caption
if (oImageElement.parentNode.nodeName.toLowerCase() == 'a') { // popup image
var oLinkElement = oImageElement.parentNode;
ib.setCaption(oLinkElement,rArgs.caption,oImageElement.getAttribute('title'),rArgs.captionClass);
} else {
ib.setCaption(oImageElement,rArgs.caption,oImageElement.getAttribute('title'),rArgs.captionClass);
}
} else if (rArgs.action == 1) { // action set - image popup
if (oLinkElement) { // edit exiting popup link
a.href = rArgs.popSrc;
rArgs.popSrc = escape(rArgs.popSrc);
ib.setAttrib(oLinkElement, 'title', rArgs.popTitle, true);
ib.isMSIE ? ib.setAttrib(oLinkElement, 'className', rArgs.popClassName, true) : ib.setAttrib(oLinkElement, 'class', rArgs.popClassName, true);
ib.setAttrib(oLinkElement, 'onclick', "window.open('" + rArgs.popUrl + "?url=" + rArgs.popSrc + '&clTxt=' + rArgs.popTxt + "','Image', 'width=500, height=300, scrollbars=no, toolbar=no, location=no, status=no, resizable=yes, screenX=100, screenY=100'); return false;", true);
} else { // create new popup link
var oLinkElement = ib.oEditor.contentWindow.document.createElement('A');
oLinkElement.href = rArgs.popSrc;
rArgs.popSrc = escape(rArgs.popSrc);
ib.setAttrib(oLinkElement, 'title', rArgs.popTitle, true);
ib.isMSIE ? ib.setAttrib(oLinkElement, 'className', rArgs.popClassName, true) : ib.setAttrib(oLinkElement, 'class', rArgs.popClassName, true);
ib.setAttrib(oLinkElement, 'onclick', "window.open('" + rArgs.popUrl + "?url=" + rArgs.popSrc + '&clTxt=' + rArgs.popTxt + "','Image', 'width=500, height=300, scrollbars=no, toolbar=no, location=no, status=no, resizable=yes, screenX=100, screenY=100'); return false;", true);
if (ib.isMSIE) { // IE
if (elm.nodeName.toLowerCase() == 'span' || elm.nodeName.toLowerCase() == 'img') {
if (elm.lastChild && elm.lastChild.className == 'caption') {
oLinkElement.innerHTML = elm.firstChild.outerHTML;
elm.firstChild.outerHTML = oLinkElement.outerHTML;
} else if (elm.nodeName.toLowerCase() == 'img') {
oLinkElement.innerHTML = elm.outerHTML;
elm.outerHTML = oLinkElement.outerHTML;
} else if (elm.nodeName.toLowerCase() == 'span' && elm.className == 'caption') {
elm = elm.previousSibling;
oLinkElement.innerHTML = elm.outerHTML;
elm.outerHTML = oLinkElement.outerHTML;
}
} else {
var rng = ib.oEditor.contentWindow.document.selection.createRange();
if (rng.text == '') {
oLinkElement.innerHTML = '#';
} else {
oLinkElement.innerHTML = rng.htmlText;
}
rng.pasteHTML(oLinkElement.outerHTML);
}
} else { // Gecko
var sel = ib.oEditor.contentWindow.getSelection();
if (sel.rangeCount > 0 && sel.getRangeAt(0).startOffset != sel.getRangeAt(0).endOffset) {
oLinkElement.appendChild(sel.getRangeAt(0).cloneContents());
} else {
oLinkElement.innerHTML = '#';
}
ib.insertNodeAtSelection(ib.oEditor.contentWindow, oLinkElement);
}
}
//-------------------------------------------------------------------------
} else if (rArgs.action == 2) { // action set - delete popup link
ib.oEditor.contentWindow.document.execCommand('Unlink');
}
}
return;
}
//-------------------------------------------------------------------------
// set image attributes
iBrowser.prototype.getImgParam = function (oImageElement, wArgs) {
var tsrc = oImageElement.src;
if (tsrc.lastIndexOf('?') >= 0) { // dynamic thumbnail or random image
var str = tsrc.substring(tsrc.lastIndexOf('?')+1, tsrc.length);
firstIndexOf = str.indexOf('&');
if (tsrc.lastIndexOf('?src') >= 0) {
wArgs.src = str.substring(4, firstIndexOf); // image part of src
wArgs.tsrc = tsrc; // full src incl. dynamic parameters
} else if (tsrc.lastIndexOf('?dir') >= 0) { // random image
wArgs.rsrc = tsrc; // full url
wArgs.rlib = str.substring(4,firstIndexOf); // image library for random picture
wArgs.rset = str.substring(firstIndexOf, str.lenght); // random parameter string
}
} else { // regular image
wArgs.src = tsrc;
}
wArgs.alt = oImageElement.alt;
wArgs.title = oImageElement.title;
if (!wArgs.rsrc) { // if not random picture
wArgs.width = oImageElement.style.width ? parseInt(oImageElement.style.width) : oImageElement.width;
wArgs.height = oImageElement.style.height ? parseInt(oImageElement.style.height) : oImageElement.height;
}
wArgs.border = oImageElement.border;
wArgs.align = oImageElement.align;
/* if (oImageElement.hspace >= 0) { // (-1 when not set under gecko for some reason)
wArgs.hspace = oImageElement.attributes['hspace'].nodeValue;
}
if (oImageElement.vspace >= 0) { // // (-1 when not set under gecko for some reason)
wArgs.vspace = oImageElement.attributes['vspace'].nodeValue;
} */
wArgs.className = oImageElement.className;
return wArgs;
}
//-------------------------------------------------------------------------
// set popup link attributes
iBrowser.prototype.getLinkParam = function (oLinkElement, wArgs) {
wArgs.a = oLinkElement;
var str = oLinkElement.getAttribute('onclick') ? oLinkElement.attributes['onclick'].value : oLinkElement.attributes['mce_onclick'].value;
wArgs.popSrc = unescape(str.substring(str.indexOf('?url=')+5, str.indexOf('&'))); // popup image src
wArgs.popTitle = oLinkElement.title;
wArgs.popClassName = oLinkElement.className;
return wArgs;
}
//-------------------------------------------------------------------------
// set image caption
iBrowser.prototype.setCaption = function (elm,chkCaption, caption, captionClass) {
if (chkCaption == 1) { // set caption
var doc = ib.oEditor.contentWindow.document;
if (elm.nextSibling && elm.nextSibling.className == 'caption') { // existing caption
var capDiv = elm.parentNode;
var newtext = elm.nextSibling.firstChild.nodeValue.replace(elm.nextSibling.firstChild.nodeValue, caption); // change caption text
ib.isMSIE ? ib.setAttrib(capDiv, 'className', captionClass, true) : ib.setAttrib(capDiv, 'class', captionClass, true); // change class
elm.nextSibling.firstChild.nodeValue = newtext;
} else { // new caption
var capDiv = doc.createElement('span');
var capText = doc.createElement('span');
capText.appendChild(doc.createTextNode(caption));
if (ib.isMSIE) { // IE
ib.setAttrib(capDiv, 'className', captionClass, true); // set class for caption container
ib.setAttrib(capText, 'className', 'caption', true); // set class for caption text
capDiv.innerHTML = elm.outerHTML;
capDiv.appendChild(capText);
elm.outerHTML = capDiv.outerHTML;
} else if (ib.isGecko) { // Gecko
ib.setAttrib(capDiv, 'class', captionClass, true); // set class for caption container
ib.setAttrib(capText, 'class', 'caption', true); // set class for caption text
var sel = ib.oEditor.contentWindow.getSelection();
capDiv.appendChild(capText);
capDiv.insertBefore(elm,capDiv.firstChild);
ib.insertNodeAtSelection(ib.oEditor.contentWindow, capDiv);
}
}
} else { // no caption set - if caption, remove it
if (elm.nextSibling && elm.nextSibling.className == 'caption') {
var parent = elm.parentNode;
parent.parentNode.replaceChild(elm, elm.parentNode);
};
}
}
//-------------------------------------------------------------------------
// check if caption
iBrowser.prototype.isCaption = function (elm) {
if (elm && elm.className == 'caption') {
return true;
}
return false;
}
//-------------------------------------------------------------------------
// get selected element (focus element)
iBrowser.prototype.getSelectedElement = function () {
if (ib.isMSIE) {
var sel = ib.oEditor.contentWindow.document.selection;
var rng = sel.createRange();
if (sel.type != 'Control') {
return rng.parentElement();
} else {
return rng(0);
}
} else if (ib.isGecko) {
var elm = null;
var sel = ib.oEditor.contentWindow.getSelection();
if (sel && sel.rangeCount > 0) {
var rng = sel.getRangeAt(0);
elm = rng.startContainer;
if (elm.nodeType != 1) {
elm = elm.parentNode;
}
}
return elm;
}
}
//-------------------------------------------------------------------------
// get element by attribute value
iBrowser.prototype.getElementByAttributeValue = function (node, element_name, attrib, value) {
var elements = ib.getElementsByAttributeValue(node, element_name, attrib, value);
if (elements.length == 0) {
return null;
}
return elements[0];
};
//-------------------------------------------------------------------------
// get elements by attribute value
iBrowser.prototype.getElementsByAttributeValue = function (node, element_name, attrib, value) {
var elements = new Array();
if (node && node.nodeName.toLowerCase() == element_name) {
if (node.getAttribute(attrib) && node.getAttribute(attrib).indexOf(value) != -1) {
elements[elements.length] = node;
}
}
if (node.hasChildNodes) {
for (var x=0, n=node.childNodes.length; x<n; x++) {
var childElements = ib.getElementsByAttributeValue(node.childNodes[x], element_name, attrib, value);
for (var i=0, m=childElements.length; i<m; i++) {
elements[elements.length] = childElements[i];
}
}
}
return elements;
};
//-------------------------------------------------------------------------
// set attributes
iBrowser.prototype.setAttrib = function (element, name, value, fixval) {
if (!fixval && value != null) {
var re = new RegExp('[^0-9%]', 'g');
value = value.replace(re, '');
}
if (value != null && value != '') {
element.setAttribute(name, value);
} else {
element.removeAttribute(name);
}
}
//-------------------------------------------------------------------------
// insert node at selection
iBrowser.prototype.insertNodeAtSelection = function (win, insertNode) { // Gecko
var sel = win.getSelection(); // get current selection
var range = sel.getRangeAt(0); // get the first range of the selection -(there's almost always only one range)
sel.removeAllRanges(); // deselect everything
range.deleteContents(); // remove content of current selection from document
var container = range.startContainer; // get location of current selection
var pos = range.startOffset;
range = document.createRange(); // make a new range for the new selection
if (container.nodeType == 3 && insertNode.nodeType == 3) {
container.insertData(pos, insertNode.nodeValue); // if we insert text in a textnode, do optimized insertion
range.setEnd(container, pos+insertNode.length); // put cursor after inserted text
range.setStart(container, pos+insertNode.length);
} else {
var afterNode;
if (container.nodeType == 3 ) { // text node
// when inserting into a textnode, we create 2 new textnodes and put the insertNode in between
var textNode = container;
container = textNode.parentNode;
var text = textNode.nodeValue;
var textBefore = text.substr(0,pos); // text before the split
var textAfter = text.substr(pos); // text after the split
var beforeNode = document.createTextNode(textBefore);
var afterNode = document.createTextNode(textAfter);
container.insertBefore(afterNode, textNode); // insert the 3 new nodes before the old one
container.insertBefore(insertNode, afterNode);
container.insertBefore(beforeNode, insertNode);
container.removeChild(textNode); // remove the old node
} else {
afterNode = container.childNodes[pos]; // else simply insert the node
container.insertBefore(insertNode, afterNode);
}
range.setEnd(afterNode, 0);
range.setStart(afterNode, 0);
}
sel.addRange(range);
win.getSelection().removeAllRanges(); // remove all ranges
}
//-------------------------------------------------------------------------
// get next sibling element by name
iBrowser.prototype.getNextSiblingByName = function (node, name) {
while ((node = node.nextSibling) != null) {
if (node.nodeName.toLowerCase() == name) {
return node;
}
}
return null;
}
//-------------------------------------------------------------------------
// get child element by name
iBrowser.prototype.getChildByName = function (node, name) {
var nodes = node.childNodes;
for (var i=0; i<nodes.length; i++) {
if (nodes[i].nodeName.toLowerCase() == name) {
return nodes[i];
}
}
return null;
}
//-------------------------------------------------------------------------