blob: a58dcfc6ac92da70a764342cbfed5a9becb5e154 [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
*/
/*
The following variables must be set:
WEBAPP_BASE_PATH - path to the web application root, including the trailing slash
AREA_BASE_PATH - path to the area root, without the trailing slash
PUBLICATION_ID
PIPELINE_PATH
IMAGE_PATH
SHOW_LOADING_HINT (optional)
SHOW_ICONS (optional)
*/
var xmlhttp;
var SHOW_LOADING_HINT = false;
var SHOW_ICONS = true;
/******************************************
* LenyaNode
******************************************/
function LenyaNode(id, parent) {
this.id = id;
this.parent = parent;
this.items = {};
this.isfolder = false;
this.label = '';
};
LenyaNode.prototype = new Node;
LenyaNode.prototype.addItems = function(items) {
this.items = {};
this.itemids = [];
for (var i = items.length - 1; i >= 0; i--) {
var item = items[i];
this.items[item.id] = item;
this.itemids.unshift(item.id);
};
};
LenyaNode.prototype.isCollection = function() {
return this.isfolder;
};
LenyaNode.prototype.getStyle = function() {
if (this.tree.root == this) {
return 'lenya-info-root';
} else {
return 'treenode_label';
}
}
LenyaNode.prototype.loadSubTree = function(handler) {
// display a 'loading' that the tree is being loaded
if (SHOW_LOADING_HINT) {
var div = this.tree.doc.createElement('div');
var text = this.tree.doc.createTextNode('loading...');
div.appendChild(text);
this.element.firstChild.firstChild.firstChild.lastChild.appendChild(div);
}
var url = this.getLoadSubTreeURL();
var callback = function (xml, item) {
item.subTreeLoaded(xml);
}
loadAsyncXML(url, callback, this);
}
LenyaNode.prototype.getLoadSubTreeURL = function() {
var path = this.getPath();
return encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
}
LenyaNode.prototype.subTreeLoaded = function(xml) {
// remove the 'loading' hint
if (SHOW_LOADING_HINT) {
var td = this.element.firstChild.firstChild.firstChild.lastChild;
td.removeChild(td.lastChild);
}
var root = xml.documentElement;
var children = root.childNodes;
var items=[];
for (var i = 0; i < children.length; i++) {
if (this.canAcceptNode(children[i])) {
items.push(this.createNewNode(children[i]));
}
}
//handler(items);
this._continueOpen(items);
}
LenyaNode.prototype.canAcceptNode = function(item) {
if (getTagName(item) == "nav:node") return true;
return false;
}
LenyaNode.prototype.addNodesRec = function(parentNode) {
var children = parentNode.childNodes;
var items = [];
var nodes = [];
var item;
for (var i = 0; i < children.length; i++) {
if (this.canAcceptNode(children[i])) {
this.reopen = true; // this causes the parent to unfold
item = this.createNewNode(children[i]);
items.push(item);
item.addNodesRec(children[i]);
}
}
this.addItems(items);
}
LenyaNode.prototype.createNewNode = function(node) {
var newItem = new LenyaNode(node.getAttribute('id'), this);
newItem.init();
var isfolder = node.getAttribute('folder') =='true' ? true : false;
newItem.isfolder = isfolder;
return newItem;
}
//workaround for http://issues.apache.org/bugzilla/show_bug.cgi?id=35227
function getTagName(element) {
var tagName = element.tagName;
var prefix = element.prefix;
if(tagName.indexOf(prefix + ':') == -1) {
tagName = prefix + ':' + tagName;
}
return tagName;
}
/******************************************
* LenyaTree
******************************************/
function LenyaTree(doc, treeElement) {
this.doc = doc;
this.treeElement = treeElement;
this.selected = null;
};
LenyaTree.prototype = new Tree;
LenyaTree.prototype.init = function(id) {
this.root = new LenyaNode(id);
this.root.tree = this;
this.root.depth = 0;
this.root.reopen = false;
this.root.isfolder = true;
this._currentId = 0;
};
LenyaTree.prototype.getItems = function(item, handler, allow_cache) {
if (item.tree.root == item) {
alert('getTtems() of root called. This should not happen, loadInitialTree should be called first.');
} else {
item.loadSubTree(handler);
}
};
LenyaTree.prototype.loadInitialTree = function(path) {
var url = this.getLoadInitialTreeURL(path);
callback = function(fragment, param) {
var tree = param[0];
var path = param[1];
tree.initialTreeLoaded(fragment);
var selectedItem = tree.getItemByPath(path);
if (selectedItem != false) {
tree.select(selectedItem);
}
}
var param = new Array(this, path);
loadAsyncXML(url, callback, param);
};
LenyaTree.prototype.getLoadInitialTreeURL = function(path) {
return encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
}
LenyaTree.prototype.initialTreeLoaded = function(xml) {
var root = xml.documentElement;
var children = root.childNodes;
var items=[];
var item;
for (var i = 0; i < children.length; i++) {
if (this.canAcceptNode(children[i])) {
item = this.createNewNode(children[i]);
items.push(item);
//item.addNodesRec(children[i]);
}
}
this.root.addItems(items);
this.root.open();
}
LenyaTree.prototype.canAcceptNode = function(item) {
if (getTagName(item) == "nav:site") return true;
return false;
}
LenyaTree.prototype.createNewNode = function(node) {
var newItem = new LenyaNode(node.getAttribute('id'), this.root);
newItem.init();
return newItem;
}
/* LenyaTree.prototype.getIcon = function(item) {
// don't use an icon for root and area nodes
if (item.depth<2) return this.doc.createTextNode('');
var img = this.doc.createElement('img');
img.setAttribute('src', IMAGE_PATH + 'document.gif');
return img;
}; */
/* return an img object that represents the file type */
LenyaTree.prototype.getIcon = function(item) {
if (SHOW_ICONS) {
var steps = new Array();
steps = item.getPath().split('/');
if (steps.length < 2) {
return this.doc.createTextNode('');
}
else {
var href;
if (steps.length < 4) {
href = AREA_BASE_PATH + "/folder";
}
else if(item.href == "") {
href = AREA_BASE_PATH + "/default";
}
else {
href = item.href;
}
var img = this.doc.createElement('img');
var language = CHOSEN_LANGUAGE;
img.setAttribute('src', href + '.gif?lenya.module=sitetree');
img.setAttribute('alt', '');
return img;
}
} else {
return this.doc.createTextNode('');
}
};
/* creates the item name and any icons and such */
LenyaTree.prototype.createItemLine = function(item) {
var div = this.doc.createElement('div');
var span = this.doc.createElement('span');
var icon = this.getIcon(item);
if (icon.nodeType == 1) {
icon.className = 'treenode_icon';
};
div.appendChild(icon);
var text = this.doc.createTextNode(item.label ? item.label : item.id);
span.className = item.getStyle();
span.appendChild(text);
div.appendChild(span);
return div;
};
LenyaTree.prototype.createItemHtml = function(item) {
var div = this.doc.createElement('div');
div.className = 'treenode';
// place a reference to the item on the div
div.treeitem = item;
var table = this.doc.createElement('table');
div.appendChild(table);
var tbody = this.doc.createElement('tbody');
table.appendChild(tbody);
var tr = this.doc.createElement('tr');
tbody.appendChild(tr);
// add the lines:
this.addLines(item, tr);
// add the opensign
var td1 = this.doc.createElement('td');
tr.appendChild(td1);
item.opensign = this.getCloseSign(item);
item.opensign.className = 'treenode_sign';
if (this.getSignType(item) == 'T') {
// if the label of this item is too long the line will wrap
// by setting the background image we get a continuos line
td1.style.backgroundImage = 'url('+IMAGE_PATH+'vertical-line.gif)';
}
td1.appendChild(item.opensign);
// add the label
var td2 = this.doc.createElement('td');
tr.appendChild(td2);
td2.className = 'lenya-info-label-td';
var line = this.createItemLine(item);
td2.appendChild(line);
addEventHandler(line, 'click', this.handleItemClick, this, item);
addEventHandler(item.opensign, 'click', this.handleItemSignClick,
this, item);
if (this.selected == item.getPath()) {
this.unselect();
this.select(item);
div.className = 'selected_node';
};
return div;
};
/* decide if the [+] or [-] sign is 'L' or '|-' type */
LenyaTree.prototype.getSignType = function(item) {
if (item.tree.root != item) {
if (isLastChild(item.parent, item)) {
return 'L';
} else {
return 'T';
}
}
return 'X'; // invalid type
};
/* get the [+] sign for a collection or resource */
LenyaTree.prototype.getCloseSign = function(item) {
var opensign = this.doc.createElement('img');
opensign.className = 'treenode_sign';
if (item.tree.root == item) {
// the root needs no opensign
opensign.setAttribute('src', IMAGE_PATH+'empty.gif');
opensign.setAttribute('width', '0');
} else {
var suffix = this.getSignType(item);
if (item.isCollection()) {
opensign.setAttribute('src', IMAGE_PATH+'closed-collection-'+suffix+'.gif');
} else {
opensign.setAttribute('src', IMAGE_PATH+'non-collection-'+suffix+'.gif');
};
}
return opensign;
};
/* get the [-] sign for a collection */
LenyaTree.prototype.getOpenSign = function(item) {
var opensign = this.doc.createElement('img');
opensign.className = 'treenode_sign';
if (item.tree.root == item) {
// the root needs no opensign
opensign.setAttribute('src', IMAGE_PATH+'empty.gif');
opensign.setAttribute('width', '0');
} else {
var suffix = this.getSignType(item);
opensign.setAttribute('src', IMAGE_PATH+'opened-collection-'+suffix+'.gif');
}
return opensign;
};
/* add the lines of an item (the edges of the tree) */
LenyaTree.prototype.addLines = function(item, parentElement) {
var linesStr = this.computeLinesString(item);
// linesStr is in the reverse order
for (var i=linesStr.length-1; i>0; i--) {
var td = this.doc.createElement('td');
var img = this.doc.createElement('img');
var imageName = '';
if (linesStr.charAt(i)=='I') {
imageName = 'vertical-line.gif';
// if the label of this item is too long the line will wrap
// by setting the background image we get a continuos line
td.style.backgroundImage = 'url('+IMAGE_PATH+'vertical-line.gif)';
} else {
imageName = 'empty.gif';
}
img.setAttribute('src', IMAGE_PATH+imageName);
img.className = 'treenode_sign';
td.appendChild(img);
parentElement.appendChild(td);
}
}
/* computes the lines of an item as a string (the edges of the tree)
E: ' ' empty
I: '|' vertical line
L: 'L'
T: '|-'
*/
LenyaTree.prototype.computeLinesString = function(item) {
var lines = ''
if (item.tree.root == item) return lines;
// first level, decide T or L
if (isLastChild(item.parent, item)) {
lines += 'L';
} else {
lines += 'T';
}
item = item.parent;
// subsequent levels, decide I or E
while (item.tree.root != item) {
if (isLastChild(item.parent, item)) {
lines += 'E'; // empty
} else {
lines += 'I'; // vertical line
}
item = item.parent;
}
return lines;
}
LenyaTree.prototype.handleItemClick = function(item, event) {
alert('you clicked on '+item.id);
// do something useful here
};
// helper function
function isLastChild(parent, child) {
// this should be a method of Node
for (var i=0; i<parent.itemids.length-1; i++) {
if (parent.itemids[i] == child.id) return false;
};
return true;
}
/******************************************
* Dynamic loading functions
******************************************/
function loadSyncXML(url) {
if (xmlhttp==null) createXMLHttp();
//alert('loading '+url);
// do synchronous loading
xmlhttp.open("GET",url,false);
xmlhttp.setRequestHeader('Accept','text/xml');
xmlhttp.send(null);
//alert('result: '+xmlhttp.responseText);
var xml = xmlhttp.responseXML;
if (xml == null || xml.documentElement == null) {
alert('Error: could not load response xml for url: '+url);
return null;
}
return xml;
}
function loadAsyncXML(url, callbackFunction, callbackParam) {
if (xmlhttp==null) createXMLHttp();
//alert('loading '+url);
// do asynchronous loading
xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('Accept','text/xml');
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
var xml = xmlhttp.responseXML;
if (xml == null || xml.documentElement == null) {
alert('Error: could not load response xml for url: '+url);
return null;
}
callbackFunction(xml, callbackParam);
}
};
xmlhttp.send(null);
}
function loadAsyncText(url, callbackFunction, callbackParam) {
if (xmlhttp==null) createXMLHttp();
//alert('loading '+url);
// do asynchronous loading
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
var text = xmlhttp.responseText;
if (text == null) {
alert('Error: could not load response text for url: '+url);
return null;
}
callbackFunction(text, callbackParam);
}
};
xmlhttp.send(null);
}
function updateElement(placeholder, url) {
var callback = function (fragment) {
var div = document.getElementById(placeholder);
div.innerHTML = fragment;
}
loadAsyncText(url, callback);
}
// create the xmlhttp object
function createXMLHttp() {
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
}
/*******************************************
* Misc
*******************************************/
function stripPrefix(s) {
if (s.indexOf(':')==-1) return s;
return s.split(':')[1];
}