Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1072228
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Jul 23, 10:26 PM
Size
93 KB
Mime Type
text/x-diff
Expires
Fri, Jul 25, 10:26 PM (6 h, 2 m)
Engine
blob
Format
Raw Data
Handle
694853
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/grid_scroller.js
===================================================================
--- branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/grid_scroller.js (revision 7088)
+++ branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/grid_scroller.js (revision 7089)
@@ -1,835 +1,835 @@
var sheetRules; // all rules in stylesheet Set by initStyleChange()
var currentRule; // which rule are we editing? Set by assignRule()
var defaultStyles = new Array();
function StyleManager() {}
StyleManager.InitStyles = function() {
if (!document.styleSheets) return;
var sheets = document.styleSheets;
this.Map = new Object();
// alert('total '+sheets.length+' sheets')
for (var i=0;i<sheets.length;i++) {
var currentSheet = sheets[i];
if (currentSheet.cssRules)
sheetRules = currentSheet.cssRules
else if (currentSheet.rules)
sheetRules = currentSheet.rules;
else {
// alert('bad sheet '+currentSheet.href);
continue;
}
// alert('sheet: '+currentSheet.href)
for (var ii=0;ii<sheetRules.length;ii++) {
var value = sheetRules[ii].selectorText;
if (value.match(',')) { // Mozilla does not break comma-separated selectors into separate rules...
var subselectors = value.split(',');
for (var sub in subselectors) {
var real_name = subselectors[sub].replace(/^[ \t]*(.*)[ \t]*/, '$1');
this.Map[real_name] = sheetRules[ii]
}
}
else {
this.Map[value.toLowerCase()] = sheetRules[ii];
}
}
}
this.Inited = true;
// preg_print_pre(this.Map, /last/);
}
StyleManager.ChangeStyle = function(selector, style, value)
{
if (!this.Inited) this.InitStyles()
rule = this.Map[selector.toLowerCase()];
if (!rule) {
alert('rule '+selector+' not found')
return;
}
rule.style[style] = value;
}
function preg_print_pre(obj, reg)
{
if (!reg) reg = /.*/;
var p = ''
for (var prop in obj) {
if (prop.match(reg) ) {
p += prop + ': '+obj[prop] + '\n'
}
}
alert(p)
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return [curleft,curtop];
}
function execJS(node)
{
var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
var bMoz = (navigator.appName == 'Netscape');
if (!node) return;
/* IE wants it uppercase */
var st = node.getElementsByTagName('SCRIPT');
var strExec;
for(var i=0;i<st.length; i++)
{
if (bSaf) {
strExec = st[i].innerHTML;
st[i].innerHTML = "";
} else if (bOpera) {
strExec = st[i].text;
st[i].text = "";
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent = "";
} else {
strExec = st[i].text;
st[i].text = "";
}
try {
var x = document.createElement("script");
x.type = "text/javascript";
/* In IE we must use .text! */
if ((bSaf) || (bOpera) || (bMoz))
x.innerHTML = strExec;
else x.text = strExec;
document.getElementsByTagName("head")[0].appendChild(x);
} catch(e) {
alert(e);
}
}
};
var startTime,endTime;
function getDimensions(obj) {
var style
if (obj.currentStyle) {
style = obj.currentStyle;
}
else {
style = getComputedStyle(obj,'');
}
padding = [parseInt(style.paddingTop), parseInt(style.paddingRight), parseInt(style.paddingBottom), parseInt(style.paddingLeft)]
border = [parseInt(style.borderTopWidth), parseInt(style.borderRightWidth), parseInt(style.borderBottomWidth), parseInt(style.borderLeftWidth)]
for (var i in padding) if ( isNaN( padding[i] ) ) padding[i] = 0
for (var i in border) if ( isNaN( border[i] ) ) border[i] = 0
var result = new Object();
result.innerHeight = obj.clientHeight - padding[0] - padding[2];
result.innerWidth = obj.clientWidth - padding[1] - padding[3];
result.padding = padding;
result.borders = border;
return result;
}
var profile = 0;
var startTime = new Date().getTime();
function Profile(message,force)
{
if (profile || force) {
endTime = new Date().getTime();
alert(message+' took '+(endTime-startTime)+' ms?')
startTime = new Date().getTime();
}
}
function GridScroller(grid_id, w, h)
{
this.GridId = grid_id
this.Footer = false;
this.LeftCells = 0;
this.LeftWidth = 0;
this.BottomOffset = 0;
this.Width = w;
this.Height = h;
this.AutoWidth = true;
this.ScrollerW = 0;
this.ScrollerH = 0;
this.MinWidths = [];
this.IDs = [];
this.Rendered = false;
}
GridScroller.prototype.Render = function(id)
{
// alert('rendering '+( id ? id : 'defulat'))
startTime = new Date().getTime();
html = this.GetHTML();
if (id && id != '') {
document.getElementById(id).innerHTML = '<div id="main_div_'+this.GridId+'">'+html+'</div>';
execJS(document.getElementById(id))
}
else {
if (this.Rendered) {
this.Render('main_div_'+this.GridId);
return;
}
document.write('<div id="main_div_'+this.GridId+'">'+html+'</div>');
}
this.Rendered = true;
Profile('Preparing HTML and writing it')
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.scroll = 'no'
this.SetReferences()
this.ScrollerW = this.MainInner.offsetWidth - this.MainInner.clientWidth
this.ScrollerH = this.MainInner.offsetHeight - this.MainInner.clientHeight
if (!this.UpdateColWidths()) return;
// Profile('UpdateColWidths');
if (this.Width == 'auto') {
this.Resize( this.GetAutoSize() );
}
else {
this.Resize();
}
// Profile('Resizing');
this.TheGrid.style.visibility = 'visible'
this.MainScroller.style.visibility = 'visible'
var the_grid = this;
if (document.all) {
$status = window.attachEvent('onresize', function(ev) { the_grid.AutoResize() });
} else {
$status = window.addEventListener('resize', function(ev) { the_grid.AutoResize() }, true);
}
Profile('Finalizng', 0);
}
GridScroller.prototype.SetReferences = function() {
this.MainOuter = document.getElementById('outer_main_'+this.GridId );
this.MainInner = document.getElementById('inner_main_'+this.GridId)
this.MainScroller = document.getElementById('main_scroller_'+this.GridId)
this.TheGrid = document.getElementById(this.GridId );
this.HeadTable = document.getElementById('header_'+this.GridId);
this.HeadScroller = document.getElementById('inner_header_'+this.GridId);
this.HeadOuter = document.getElementById('outer_header_'+this.GridId);
this.DataTable = document.getElementById('data_'+this.GridId);
this.DataScroller = document.getElementById('inner_data_'+this.GridId);
this.DataOuter = document.getElementById('outer_data_'+this.GridId);
if (this.HasFooter) {
this.FooterTable = document.getElementById('footer_'+this.GridId);
this.FooterScroller = document.getElementById('inner_footer_'+this.GridId);
this.FooterOuter = document.getElementById('outer_footer_'+this.GridId);
}
if (this.LeftCells != 0) {
this.LeftHeaderTable = document.getElementById('left_header_'+this.GridId);
this.LeftHeaderScroller = document.getElementById('inner_left_header_'+this.GridId);
this.LeftHeaderOuter = document.getElementById('outer_left_header_'+this.GridId);
this.LeftDataTable = document.getElementById('left_data_'+this.GridId);
this.LeftDataScroller = document.getElementById('inner_left_data_'+this.GridId);
this.LeftDataOuter = document.getElementById('outer_left_data_'+this.GridId);
if (this.HasFooter) {
this.LeftFooterTable = document.getElementById('left_footer_'+this.GridId);
this.LeftFooterScroller = document.getElementById('inner_left_footer_'+this.GridId);
this.LeftFooterOuter = document.getElementById('outer_left_footer_'+this.GridId);
}
}
this.DataScroller.TheGrid = this;
this.MainInner.TheGrid = this;
this.Dot = document.getElementById('dot_'+this.GridId)
// this.MainOuter.style.border = '5px solid red';
// this.MainOuter.style.padding = '30px';
this.MainOuter.className = 'grid-scrollable'
if (!is.ie) {
this.MainOuter.style.marginLeft = '-1px';
}
}
GridScroller.prototype.UpdateColWidths = function() {
var data_cf = 1;
var count = 1;
var header_cf = 0;
var footer_cf = 0.2;
// alert('MinWidths: '+this.MinWidths.length + ' vs Data ' + this.Header[0].length)
if (this.MinWidths.length < this.Header[0].length) {
var widths = new Array();
var total = 0;
StyleManager.ChangeStyle('td.grid-header-last-cell', 'width', '123px')
StyleManager.ChangeStyle('td.grid-data-last-cell', 'width', 'auto')
if (this.HasFooter()) {
StyleManager.ChangeStyle('td.grid-footer-last-cell', 'width', 'auto')
}
if (this.LeftCells) {
widths.push(this.LeftHeaderTable.clientWidth)
}
var header_widths = this.GetWidths('header_'+this.GridId);
var data_widths = this.GetWidths('data_'+this.GridId);
/*if (this.HasFooter()) {
var footer_widths = this.GetWidths('footer_'+this.GridId);
data_cf -= footer_cf;
count++;
}*/
for (var i=0; i<header_widths.length; i++)
{
target = data_widths[i] ? data_widths[i] : header_widths[i];
if (target < header_widths[i]) target = header_widths[i];
widths.push(target);
total += target;
}
this.MinWidths = widths;
StyleManager.ChangeStyle('td.grid-header-last-cell', 'width', '100%')
StyleManager.ChangeStyle('td.grid-data-last-cell', 'width', '100%')
if (this.HasFooter()) {
StyleManager.ChangeStyle('td.grid-footer-last-cell', 'width', '100%')
}
this.Render();
return false;
}
/*for (var i=0; i<header_widths.length; i++)
{
// target = Math.max( Math.max(header_widths[i], data_widths[i]), footer_widths[i]);
var sum = header_widths[i]*header_cf*count + (data_widths[i] ? data_widths[i]*data_cf*count : header_widths[i]*data_cf*count);
alert('sum ('+i+') = '+header_widths[i]+' * '+header_cf+' * '+count+' + '+data_widths[i]+' * '+data_cf+' * '+count+' = '+sum)
if (this.HasFooter()) {
sum += footer_widths[i]*footer_cf*count;
alert('sum + '+footer_widths[i]+' * '+footer_cf+' * '+count+' = '+sum)
}
target = Math.round( sum / count )
widths.push(target);
// alert('target: '+target)
total += target;
}
*/
Profile('Getting widths');
// preg_print_pre(widths)
// this.MinDataWidth = total;
// this.SetWidths('header_'+this.GridId, widths, 0, -1);
// this.SetWidths('data_'+this.GridId, widths, 0, -1);
if (this.LeftCells != 0) {
this.SetHeights('left_header_'+this.GridId, this.GetHeights('header_'+this.GridId));
this.SetHeights('left_data_'+this.GridId, this.GetHeights('data_'+this.GridId));
if (this.HasFooter()) {
this.SetHeights('left_footer_'+this.GridId, this.GetHeights('footer_'+this.GridId));
}
// alert('setting left widths')
// this.SetWidths('left_header_'+this.GridId, [30], 0, 1);
// this.SetWidths('left_data_'+this.GridId, [30], 0, 1);
}
// this.HeadTable.style.width = '100%'
if (this.HasFooter()) {
this.SetRowWidths('footer_'+this.GridId, widths);
this.FooterTable.style.width = '100%'
this.FooterHeight = this.FooterTable.offsetHeight;
this.FooterOuter.style.height = this.FooterHeight + 'px'
}
else {
this.FooterHeight = 0;
}
this.HeadHeight = this.HeadTable.offsetHeight;
this.DataHeight = this.DataTable.offsetHeight;
this.HeadOuter.style.height = (this.HeadHeight) + 'px'
if (this.LeftCells != 0) {
this.LeftWidth = Math.max(this.LeftHeaderTable.offsetWidth, this.LeftDataTable.offsetWidth)
this.LeftHeaderOuter.style.height = (this.HeadHeight) + 'px'
if (this.HasFooter()) {
this.LeftFooterOuter.style.height = (this.FooterHeight) + 'px'
this.LeftWidth = Math.max(this.LeftWidth, this.LeftFooterTable.offsetWidth);
}
}
this.MainInner.onscroll = function() {
this.TheGrid.SyncScroll()
}
this.MainOuter.style.width = 'auto'
if (document.all) {
this.DataScroller.onmousewheel = function(ev) {
var e = document.all ? window.event : ev;
this.TheGrid.MainInner.scrollTop += -e.wheelDelta/2
this.TheGrid.SyncScroll();
}
}
else {
this.DataScroller.addEventListener("DOMMouseScroll", function(ev) {
var e = document.all ? window.event : ev;
this.TheGrid.MainInner.scrollTop += e.detail*10
this.TheGrid.SyncScroll();
}, false);
}
return true;
}
GridScroller.prototype.SetRowWidths = function(table_id, widths, row, from, to)
{
if (!row) row = 0;
table = document.getElementById(table_id);
var inner_width = 0;
var final_width;
if (!from) from = 0;
if (!to) {
to = table.rows[row].cells.length;
}
else {
if (to < 0) {
to = table.rows[row].cells.length + to; // + because to is negative!
}
}
var min_offset = 0;
if (!table_id.match(/^left_/)) {
min_offset = this.LeftCells;
}
// alert('table: '+table_id+' min_offset: '+min_offset)
// alert('from: '+from+' to '+to)
for (var col=from; col < to; col++)
{
final_width = widths[col];
// alert('col: '+col)
if ( this.MinWidths[col+min_offset] && (final_width < this.MinWidths[col+min_offset])) {
// alert('correcting minwidth of '+col+': '+this.MinWidths[col]+ ' / '+final_width)
final_width = this.MinWidths[col+min_offset]
}
table.rows[row].cells[col].innerHTML = '<div style="width: '+(final_width) +'px; overflow: hidden; background-color: yellow;">' + table.rows[row].cells[col].innerHTML + '</div>'
// alert('setting '+widths[col]+' for col '+col)
// if (isNaN(final_width)) {
// alert('set '+table_id+'col '+col+' '+table.rows[0].cells[col].innerHTML+' to '+widths[col])
// }
table.rows[row].cells[col].style.width = final_width+'px';
// alert('set ('+col+')'+table.rows[0].cells[col].innerHTML+' to '+widths[col])
}
}
GridScroller.prototype.SetHeights = function(table_id, heights)
{
var table = document.getElementById(table_id);
for (var row=0; row<table.rows.length; row++)
{
var width = this.MinWidths[0] ? this.MinWidths[0] + 'px' : 'auto';
table.rows[row].cells[0].innerHTML = '<div style="display: table-cell; line-height: '+(heights[row])+'px; height: '+(heights[row]) +'px; width: '+width+'; overflow: hidden; background-color: inherit;">' + table.rows[row].cells[0].innerHTML + '</div>'
table.rows[row].cells[0].style.height = heights[row]+'px';
// heights.push( table.rows[0].cells[0].offsetHeight )
// alert('get ('+row+')'+table.rows[0].cells[0].innerHTML+' height '+table.rows[0].cells[0].offsetHeight)
}
// return heights;
}
GridScroller.prototype.SetWidths = function(table_id, widths, from, to)
{
var table = document.getElementById(table_id);
table.style.layout = 'fixed'
for (var row=0; row<1; row++)
{
this.SetRowWidths(table_id, widths, row, from, to)
}
table.style.width = '100%'
}
GridScroller.prototype.GetHeights = function(table_id)
{
var table = document.getElementById(table_id);
var heights = new Array();
var height
for (var row=0; row<table.rows.length; row++)
{
height = getDimensions( table.rows[row].cells[0] ).innerHeight
heights.push( height )
// alert('get ('+row+')'+table.rows[row].cells[0].innerHTML+' height (offset/client/computed (coorection)): '+table.rows[row].cells[0].offsetHeight + '/' + table.rows[row].cells[0].clientHeight + '/ ' +height + ' ('+correction+')')
}
return heights;
}
GridScroller.prototype.GetWidths = function(table_id)
{
var table = document.getElementById(table_id);
table.style.width = 'auto'
if (table.offsetWidth < document.body.clientWidth * 0.8) {
table.style.width = Math.round( document.body.clientWidth * 0.8 ) + 'px'
}
var widths = new Array();
var style;
if (!table.rows[0]) return [];
for (var col=0; col<table.rows[0].cells.length; col++)
{
widths.push( table.rows[0].cells[col].offsetWidth )
// alert('get ('+col+')'+table.rows[0].cells[col].innerHTML+' width '+table.rows[0].cells[col].offsetWidth)
}
return widths;
}
GridScroller.prototype.GetAutoSize = function()
{
this.MainOuter.style.width = 'auto'
var w = this.MainInner.offsetWidth;
var h = document.body.clientHeight;
var pos = findPos(this.MainOuter);
var dim = getDimensions(this.MainOuter);
h -= pos[1] + dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2] + this.BottomOffset;
return [w,h]
}
GridScroller.prototype.AutoResize = function()
{
var obj = this;
if (this.ResizeHappening && this.ResizeTimer) {
window.clearTimeout(this.ResizeTimer);
this.ResizeTimer = false;
}
this.ResizeHappening = true;
this.ResizeTimer = window.setTimeout(function() {
obj.Resize( obj.GetAutoSize() );
obj.ResizeHappening = false;
// alert('resized')
}, 300)
}
GridScroller.prototype.Resize = function(w,h)
{
Profile('Resize 0')
if (typeof(w) == 'object') {
h = w[1];
w = w[0];
}
if (w) this.Width = w;
if (h) this.Height = h;
pos = findPos(this.Dot)
this.MainOuter.style.height = (this.Height)+'px'
this.MainOuter.style.width = (this.Width)+'px'
var data_width = this.DataTable.offsetWidth + this.LeftWidth;
var data_height = this.DataHeight + this.HeadHeight + this.FooterHeight;
scroller_height = data_width > this.Width ? this.ScrollerH : 0;
scroller_width = data_height > this.Height - scroller_height ? this.ScrollerW : 0;
scroller_height = data_width > this.Width - scroller_width ? this.ScrollerH : 0;
// alert('min: '+this.MinDataWidth+' pos: '+pos[0]+','+pos[1]+' scroller W x H: '+scroller_width+' x '+scroller_height+' will resize to '+this.Width+' x '+this.Height+' data: '+data_width+' x '+data_height)
this.TheGrid.style.left = (pos[0])+ 'px'
this.TheGrid.style.top = (pos[1]) + 'px'
this.HeadOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px';
this.DataOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px';
Profile('Resize 0.3')
if (this.LeftCells != 0) {
this.LeftHeaderOuter.style.width = (this.LeftWidth) + 'px'
this.LeftDataOuter.style.width = (this.LeftWidth) + 'px'
if (this.HasFooter()) {
this.LeftFooterOuter.style.width = (this.LeftWidth) + 'px'
}
}
Profile('Resize 1')
if (this.HasFooter()) {
this.FooterOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px';
}
Profile('Resize 1.1')
if (data_height < this.Height - scroller_height) {
var adjusted_data_height = data_height - this.HeadHeight - this.FooterHeight
}
else {
var adjusted_data_height = this.Height - this.HeadHeight - this.FooterHeight - scroller_height
}
Profile('Resize 1.2')
this.DataOuter.style.height = adjusted_data_height + 'px'
if (this.LeftCells != 0) {
this.LeftDataOuter.style.height = adjusted_data_height + 'px'
}
Profile('Resize 2')
this.MainScroller.style.width = (this.HeadTable.offsetWidth + this.LeftWidth)+'px'
this.MainScroller.style.height = ( this.DataTable.offsetHeight + this.HeadHeight + this.FooterHeight)+'px'
Profile('Resize 0.1')
this.TheGrid.style.width = (this.Width - scroller_width) + 'px';
this.TheGrid.style.height = (this.Height - scroller_height) + 'px';
Profile('Resize 0.2')
Profile('Full resize')
}
GridScroller.prototype.SyncScroll = function()
{
this.HeadScroller.scrollLeft = this.MainInner.scrollLeft;
this.DataScroller.scrollLeft = this.MainInner.scrollLeft;
if (this.HasFooter()) {
this.FooterScroller.scrollLeft = this.MainInner.scrollLeft;
}
this.DataScroller.scrollTop = this.MainInner.scrollTop;
if (this.LeftCells != 0) {
this.LeftDataScroller.scrollTop = this.MainInner.scrollTop;
}
}
GridScroller.prototype.GetHTML = function()
{
w = this.Width;
h = this.Height;
var o = '';
o += this.CreateScroller( '<div id="main_scroller_'+this.GridId+'" style="background-color: inherit; position: relative; width: auto;"><img src="'+this.Spacer+'" id="dot_'+this.GridId+'" width="200" height="200"><br/><br/></div>', 100, 100, 'main_'+this.GridId, false, 1 );
o += '<div id="'+this.GridId+'" class="grid-container" style="background-color: inherit; top: 0px; visibility: hidden; z-index: 10; width: auto; height: '+300+'px; position: absolute; overflow: hidden;">';
var header = this.CreateScroller( this.CreateTable( this.GetHeaderCells(), 'header_'+this.GridId), 100, 10, 'header_'+this.GridId, true, 5 )
var data = this.CreateScroller( this.CreateTable( this.GetDataCells(), 'data_'+this.GridId ), 100, 10, 'data_'+this.GridId, true, 5 )
var footer = this.HasFooter() ? this.CreateScroller( this.CreateTable( this.GetFooterCells(), 'footer_'+this.GridId ), 100, 10, 'footer_'+this.GridId, true, 5 ) : '';
if (this.LeftCells != 0) {
var left_header = this.CreateScroller( this.CreateTable( this.GetLeftHeader(), 'left_header_'+this.GridId), 20, 10, 'left_header_'+this.GridId, true, 5 )
var left_data = this.CreateScroller( this.CreateTable( this.GetLeftData(), 'left_data_'+this.GridId), 20, 10, 'left_data_'+this.GridId, true, 5 )
var left_footer = this.CreateScroller( this.CreateTable( this.GetLeftFooter(), 'left_footer_'+this.GridId), 20, 10, 'left_footer_'+this.GridId, true, 5 )
o += '<table style="width: 100%; border-collapse: collapse;">'
o += '<tr><td style="vertical-align: top; margin: 0px; padding: 0px;">' + left_header + '</td>'
o += '<td style="vertical-align: top; margin: 0px; padding: 0px;">' + header + '</td></tr>'
o += '<tr><td style="vertical-align: top; margin: 0px; padding: 0px">' + left_data + '</td>'
o += '<td style="vertical-align: top; margin: 0px; padding: 0px">' + data + '</td></tr>'
if (this.HasFooter()) {
o += '<tr><td style="vertical-align: top; margin: 0px; padding: 0px">' + left_footer + '</td>'
o += '<td style="vertical-align: top; margin: 0px; padding: 0px">' + footer + '</td></tr>'
}
o += '</table>'
}
else {
o += header + data + footer;
}
o += '</div>';
return o
}
GridScroller.prototype.HasFooter = function()
{
return (this.Footer != false)
}
GridScroller.prototype.CreateTable = function(content, id)
{
return '<table style="width: 100%" id="'+id+'">'+content+'</table>';
}
GridScroller.prototype.CreateScroller = function(content, w, h, id, hidden, z)
{
if (hidden) {
overflow = 'hidden'
}
else {
overflow = 'auto'
}
if (!z) {
z = 0;
}
if (id && id != '') {
outer_id = 'id="outer_'+id+'"';
inner_id = 'id="inner_'+id+'"';
}
else {
outer_id = '';
inner_id = '';
}
var o = '';
o += '<div '+outer_id+' class="scroller-outer" style="z-index: '+z+'; width: '+w+'px; height: '+h+'px;">'
o += '<div '+inner_id+' class="scroller-inner" style="z-index: '+z+'; width: 100%; height: 100%; overflow: '+overflow+'; position: relative">'
o += content
o += '</div></div>'
return o
}
GridScroller.prototype.GetLeftHeader = function()
{
var o = '';
for (var row in this.Header) {
o +='<tr class="grid-header-row grid-header-row-'+row+'">'
for (var col=0; col<this.LeftCells; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
o += '<td class="grid-header-col-'+col+'"><div class="grid-cell-div" style="width: '+width+';">'+this.Header[row][col]+'</div></td>'
}
o += '</tr>'
}
return o
}
GridScroller.prototype.GetLeftData = function()
{
var o = '';
var even = false;
for (var row in this.Data) {
var id = this.IDs[row] ? 'id="left_'+this.IDs[row]+'"' : '';
o += even ? '<tr class="grid-row grid-row-even grid-row-'+row+'" '+id+'>' : '<tr class="grid-row grid-row-'+row+'" '+id+'>'
even = !even;
for (var col=0; col<this.LeftCells; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
o += '<td class="grid-col-'+col+'"><div class="grid-cell-div" style="width: '+width+';">'+this.Data[row][col]+'</div></td>'
}
o += '</tr>'
}
return o
}
GridScroller.prototype.GetLeftFooter = function()
{
var o = '';
if (this.HasFooter()) {
o += '<tr class="grid-footer-row">'
for (var col=0; col<this.LeftCells; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
o += '<td class="grid-footer-col-'+col+'"><div class="grid-cell-div" style="width: '+width+';">'+this.Footer[col]+'</div></td>'
}
o += '</tr>'
}
return o
}
GridScroller.prototype.GetHeaderCells = function()
{
var o = '';
for (var row in this.Header) {
o +='<tr class="grid-header-row grid-header-row-'+row+'">'
for (var col=this.LeftCells; col<this.Header[row].length; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
- o += '<td class="grid-header-col-'+col+'"><div class="grid-cell-div" style="background-color: inherit; width: '+width+';">'+this.Header[row][col]+'</div></td>'
+ o += '<td class="grid-header-col-'+col+'"><div style="width: '+width+'; overflow: auto;"><div class="grid-cell-div" style="background-color: inherit; width: '+width+';">'+this.Header[row][col]+'</div></div></td>'
}
o += '<td class="grid-header-last-cell"><img src="'+this.Spacer+'" width="1" height="1" alt=""/></td>'
o += '</tr>'
}
return o
/*var o = '<tr class="grid-header-row">'
for (var col=this.LeftCells; col<this.Header.length; col++) {
o += '<td class="grid-header-col-'+col+'">'+this.Header[col]+'</td>'
}
o += '<td class="grid-header-last-cell" style="width: auto"><img src="'+this.Spacer+'" width="1" height="1" alt=""/></td>'
o += '</tr>'
return o*/
}
GridScroller.prototype.GetDataCells = function()
{
var o = '';
var even = false;
var width;
for (var row in this.Data) {
var id = this.IDs[row] ? 'id="'+this.IDs[row]+'"' : '';
o += even ? '<tr class="grid-row grid-row-even grid-row-'+row+'" '+id+' sequence="'+(row+1)+'">' : '<tr class="grid-row grid-row-'+row+'" '+id+' sequence="'+(row+1)+'">'
even = !even;
for (var col=this.LeftCells; col<this.Data[row].length; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
o += '<td class="grid-col-'+col+'"><div class="grid-cell-div" style="width: '+width+';">'+this.Data[row][col]+'</div></td>'
}
o += '<td class="grid-data-last-cell"><img src="'+this.Spacer+'" width="1" height="1" alt=""/></td>'
o += '</tr>'
}
return o
}
GridScroller.prototype.GetFooterCells = function()
{
var o = '<tr class="grid-footer-row">'
for (var col=this.LeftCells; col<this.Footer.length; col++) {
width = this.MinWidths[col] ? this.MinWidths[col] + 'px' : 'auto';
o += '<td class="grid-footer-col-'+col+'">'+this.Footer[col]+'</td>'
}
o += '<td class="grid-footer-last-cell" style="width: 100%"><img src="'+this.Spacer+'" width="1" height="1" alt=""/></td>'
o += '</tr>'
return o
}
GridScroller.prototype.SetData = function(a_data)
{
this.Data = a_data;
}
GridScroller.prototype.SetHeader = function(a_header)
{
this.Header = a_header;
}
GridScroller.prototype.SetFooter = function(a_footer)
{
this.Footer = a_footer;
}
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/grid_scroller.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.12
\ No newline at end of property
+1.1.2.13
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-setup.js
===================================================================
--- branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-setup.js (revision 7088)
+++ branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-setup.js (revision 7089)
@@ -1,200 +1,202 @@
/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
* ---------------------------------------------------------------------------
*
* The DHTML Calendar
*
* Details and latest version at:
* http://dynarch.com/mishoo/calendar.epl
*
* This script is distributed under the GNU Lesser General Public License.
* Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
*
* This file defines helper functions for setting up the calendar. They are
* intended to help non-programmers get a working calendar on their site
* quickly. This script should not be seen as part of the calendar. It just
* shows you what one can do with the calendar, while in the same time
* providing a quick and simple method for setting it up. If you need
* exhaustive customization of the calendar creation process feel free to
* modify this code to suit your needs (this is recommended and much better
* than modifying calendar.js itself).
*/
-// $Id: calendar-setup.js,v 1.1.2.1 2007-01-10 12:41:49 kostja Exp $
+// $Id: calendar-setup.js,v 1.1.2.2 2007-01-10 19:07:23 kostja Exp $
/**
* This function "patches" an input field (or other element) to use a calendar
* widget for date selection.
*
* The "params" is a single object that can have the following properties:
*
* prop. name | description
* -------------------------------------------------------------------------------------------------
* inputField | the ID of an input field to store the date
* displayArea | the ID of a DIV or other element to show the date
* button | ID of a button or other element that will trigger the calendar
* eventName | event that will trigger the calendar, without the "on" prefix (default: "click")
* ifFormat | date format that will be stored in the input field
* daFormat | the date format that will be used to display the date in displayArea
* singleClick | (true/false) wether the calendar is in single click mode or not (default: true)
* firstDay | numeric: 0 to 6. "0" means display Sunday first, "1" means display Monday first, etc.
* align | alignment (default: "Br"); if you don't know what's this see the calendar documentation
* range | array with 2 elements. Default: [1900, 2999] -- the range of years available
* weekNumbers | (true/false) if it's true (default) the calendar will display week numbers
* flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
* flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
* disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
* onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay)
* onClose | function that gets called when the calendar is closed. [default]
* onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar.
* date | the date that the calendar will be initially displayed to
* showsTime | default: false; if true the calendar will include a time selector
* timeFormat | the time format; can be "12" or "24", default is "12"
* electric | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
* step | configures the step of the years in drop-down boxes; default: 2
* position | configures the calendar absolute position; default: null
* cache | if "true" (but default: "false") it will reuse the same calendar object, where possible
* showOthers | if "true" (but default: "false") it will show days from other months too
*
* None of them is required, they all have default values. However, if you
* pass none of "inputField", "displayArea" or "button" you'll get a warning
* saying "nothing to setup".
*/
Calendar.setup = function (params) {
function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
+
+
param_default("inputField", null);
param_default("displayArea", null);
param_default("button", null);
param_default("eventName", "click");
param_default("ifFormat", "%Y/%m/%d");
param_default("daFormat", "%Y/%m/%d");
param_default("singleClick", true);
param_default("disableFunc", null);
param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined
param_default("dateText", null);
param_default("firstDay", null);
param_default("align", "Br");
param_default("range", [1900, 2999]);
param_default("weekNumbers", true);
param_default("flat", null);
param_default("flatCallback", null);
param_default("onSelect", null);
param_default("onClose", null);
param_default("onUpdate", null);
param_default("date", null);
param_default("showsTime", false);
param_default("timeFormat", params['ifFormat'].match(/%l|%p|%P/) ? "12" : "24");
param_default("electric", true);
param_default("step", 2);
param_default("position", null);
param_default("cache", false);
param_default("showOthers", false);
param_default("multiple", null);
var tmp = ["inputField", "displayArea", "button"];
for (var i in tmp) {
if (typeof params[tmp[i]] == "string") {
params[tmp[i]] = document.getElementById(params[tmp[i]]);
}
}
if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");
return false;
}
function onSelect(cal) {
var p = cal.params;
var update = (cal.dateClicked || p.electric);
if (update && p.inputField) {
p.inputField.value = cal.date.print(p.ifFormat);
if (typeof p.inputField.onchange == "function")
p.inputField.onchange();
}
if (update && p.displayArea)
p.displayArea.innerHTML = cal.date.print(p.daFormat);
if (update && typeof p.onUpdate == "function")
p.onUpdate(cal);
if (update && p.flat) {
if (typeof p.flatCallback == "function")
p.flatCallback(cal);
}
if (update && p.singleClick && cal.dateClicked)
cal.callCloseHandler();
};
if (params.flat != null) {
if (typeof params.flat == "string")
params.flat = document.getElementById(params.flat);
if (!params.flat) {
alert("Calendar.setup:\n Flat specified but can't find parent.");
return false;
}
var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
cal.showsOtherMonths = params.showOthers;
cal.showsTime = params.showsTime;
cal.time24 = (params.timeFormat == "24");
cal.params = params;
cal.weekNumbers = params.weekNumbers;
cal.setRange(params.range[0], params.range[1]);
cal.setDateStatusHandler(params.dateStatusFunc);
cal.getDateText = params.dateText;
if (params.ifFormat) {
cal.setDateFormat(params.ifFormat);
}
if (params.inputField && typeof params.inputField.value == "string") {
cal.parseDate(params.inputField.value);
}
cal.create(params.flat);
cal.show();
return false;
}
var triggerEl = params.button || params.displayArea || params.inputField;
triggerEl["on" + params.eventName] = function() {
var dateEl = params.inputField || params.displayArea;
var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
var mustCreate = false;
var cal = window.calendar;
if (dateEl)
params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
if (!(cal && params.cache)) {
window.calendar = cal = new Calendar(params.firstDay,
params.date,
params.onSelect || onSelect,
params.onClose || function(cal) { cal.hide(); });
cal.showsTime = params.showsTime;
cal.time24 = (params.timeFormat == "24");
cal.weekNumbers = params.weekNumbers;
mustCreate = true;
} else {
if (params.date)
cal.setDate(params.date);
cal.hide();
}
if (params.multiple) {
cal.multiple = {};
for (var i = params.multiple.length; --i >= 0;) {
var d = params.multiple[i];
var ds = d.print("%Y%m%d");
cal.multiple[ds] = d;
}
}
cal.showsOtherMonths = params.showOthers;
cal.yearStep = params.step;
cal.setRange(params.range[0], params.range[1]);
cal.params = params;
cal.setDateStatusHandler(params.dateStatusFunc);
cal.getDateText = params.dateText;
cal.setDateFormat(dateFmt);
if (mustCreate)
cal.create();
cal.refresh();
if (!params.position)
cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
else
cal.showAt(params.position[0], params.position[1]);
return false;
};
return cal;
};
Property changes on: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-setup.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-en.js
===================================================================
--- branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-en.js (revision 7088)
+++ branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-en.js (revision 7089)
@@ -1,127 +1,127 @@
// ** I18N
// Calendar EN language
// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
// Encoding: any
// Distributed under the same terms as the calendar itself.
// For translators: please use UTF-8 if possible. We strongly believe that
// Unicode is the answer to a real internationalized world. Also please
// include your contact information in the header, as can be seen above.
// full day names
Calendar._DN = new Array
("Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday");
// Please note that the following array of short day names (and the same goes
// for short month names, _SMN) isn't absolutely necessary. We give it here
// for exemplification on how one can customize the short day names, but if
// they are simply the first N letters of the full name you can simply say:
//
// Calendar._SDN_len = N; // short day name length
// Calendar._SMN_len = N; // short month name length
//
// If N = 3 then this is not needed either since we assume a value of 3 if not
// present, to be compatible with translation files that were written before
// this feature.
// short day names
Calendar._SDN = new Array
("Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun");
// First day of the week. "0" means display Sunday first, "1" means display
// Monday first, etc.
Calendar._FD = 0;
// full month names
Calendar._MN = new Array
("January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December");
// short month names
Calendar._SMN = new Array
("Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec");
// tooltips
Calendar._TT = {};
Calendar._TT["INFO"] = "About the calendar";
Calendar._TT["ABOUT"] =
"DHTML Date/Time Selector\n" +
"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
"\n\n" +
"Date selection:\n" +
"- Use the \xab, \xbb buttons to select year\n" +
"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
"- Hold mouse button on any of the above buttons for faster selection.";
Calendar._TT["ABOUT_TIME"] = "\n\n" +
"Time selection:\n" +
"- Click on any of the time parts to increase it\n" +
"- or Shift-click to decrease it\n" +
"- or click and drag for faster selection.";
Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
Calendar._TT["GO_TODAY"] = "Go Today";
Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
Calendar._TT["SEL_DATE"] = "Select date";
Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
Calendar._TT["PART_TODAY"] = " (today)";
// the following is to inform that "%s" is to be the first day of week
// %s will be replaced with the day name.
Calendar._TT["DAY_FIRST"] = "Display %s first";
// This may be locale-dependent. It specifies the week-end days, as an array
// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
// means Monday, etc.
Calendar._TT["WEEKEND"] = "0,6";
Calendar._TT["CLOSE"] = "Close";
Calendar._TT["TODAY"] = "Today";
-Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
+Calendar._TT["TIME_PART"] = "(Shift-)Click or drag<br/> to change value";
// date formats
Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
Calendar._TT["WK"] = "wk";
Calendar._TT["TIME"] = "Time:";
Property changes on: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/calendar/calendar-en.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/tree.js
===================================================================
--- branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/tree.js (revision 7088)
+++ branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/tree.js (revision 7089)
@@ -1,388 +1,575 @@
+var last_hightlighted = null;
+var last_highlighted_key = null;
+
function TreeItem(title, url, icon, onclick)
{
this.Title = title;
this.Url = url;
this.Rendered = false;
this.Displayed = false;
this.Level = 0;
this.Icon = icon;
this.Onclick = onclick;
}
-TreeItem.prototype.Render = function(before)
+TreeItem.prototype.Render = function(before, force)
{
- if (!this.Rendered) {
+ if (!this.Rendered || force) {
if (!isset(before)) {before = null}
tr = document.createElement('tr');
this.ParentElement.insertBefore(tr, before);
if (!this.Displayed) { tr.style.display = 'none' }
td = document.createElement('td');
td.TreeElement = this;
tr.appendChild(td);
this.appendLevel(td);
if (this.ParentFolder != null) this.appendNodeImage(td);
this.appendIcon(td);
this.appendLink(td);
this.Tr = tr;
this.Rendered = true;
// alert(this.Tr.innerHTML)
}
}
+TreeItem.prototype.remove = function()
+{
+ var p = this.Tr.parentNode;
+ p.removeChild(this.Tr);
+}
+
TreeItem.prototype.appendLevel = function(td)
{
for (var i=0; i < this.Level; i++)
{
img = document.createElement('img');
img.src = TREE_ICONS_PATH+'/ftv2blank.gif';
img.style.verticalAlign = 'middle';
td.appendChild(img);
}
}
TreeItem.prototype.getNodeImage = function(is_last)
{
return is_last ? TREE_ICONS_PATH+'/ftv2lastnode.gif' : TREE_ICONS_PATH+'/ftv2node.gif';
}
TreeItem.prototype.appendNodeImage = function(td)
{
img = document.createElement('img');
img.src = this.getNodeImage();
img.style.verticalAlign = 'middle';
td.appendChild(img);
}
TreeItem.prototype.appendIcon = function (td)
{
img = document.createElement('img');
if (this.Icon.indexOf('http://') != -1) {
img.src = this.Icon;
}
else {
img.src = this.Icon;
}
img.style.verticalAlign = 'middle';
td.appendChild(img);
}
TreeItem.prototype.appendLink = function (td)
{
var $node_text = document.createElement('span');
$node_text.innerHTML = this.Title;
-
+
link = document.createElement('a');
link.nodeValue = this.Title;
link.href = this.Url;
link.target = 'main';
link.appendChild($node_text);
link.treeItem = this;
//addEvent(link, 'click',
link.onclick =
function(ev) {
var e = is.ie ? window.event : ev;
res = true;
if (isset(this.treeItem.Onclick)) {
res = eval(this.treeItem.Onclick);
}
if (!res) { // if we need to cancel onclick action
if (is.ie) {
window.event.cancelBubble = true;
window.event.returnValue = false;
} else {
ev.preventDefault();
ev.stopPropagation();
}
return res;
}
else {
// ensures, that click is made before AJAX request will be sent
if (res === true) {
// only in case of "true" is returned, used in catalog
getFrame(link.target).location.href = this.href;
}
-
+
if (!this.treeItem.Expanded && typeof(this.treeItem.folderClick) == 'function') {
if (this.treeItem.folderClick());
}
- return false;
+ this.treeItem.highLight();
+ return false;
}
}
td.appendChild(link);
+
+ if (this.LateLoadURL) {
+ var span = document.createElement('span');
+ span.innerHTML = ' Reload';
+ span.treeItem = this;
+ span.onclick = function(ev) {
+ this.treeItem.reload();
+ }
+ td.appendChild(span);
+ }
}
TreeItem.prototype.display = function()
{
this.Tr.style.display = is.ie ? 'block' : 'table-row';
this.Displayed = true;
+
+ var do_sub = TreeManager.isExpanded(this.Key);
+ if (this.Children && do_sub && !this.Expanding) {
+ this.expand();
+ }
+
}
TreeItem.prototype.hide = function()
{
this.Tr.style.display = 'none';
this.Displayed = false;
}
+TreeItem.prototype.highLight = function()
+{
+ if (last_hightlighted) last_hightlighted.Tr.className = '';
+ this.Tr.className = "highlighted";
+ last_hightlighted = this;
+ last_highlighted_key = this.Key;
+}
+
TreeItem.prototype.expand = function() { this.display() }
TreeItem.prototype.collapse = function() { this.hide() }
TreeItem.prototype.updateLastNodes = function(is_last, lines_pattern)
{
if (!isset(is_last)) is_last = true;
if (!isset(this.Tr)) return;
if (!isset(lines_pattern)) { var lines_pattern = new Array() }
imgs = this.Tr.getElementsByTagName('img');
found = false;
for (var i=0; i<imgs.length; i++)
{
the_img = imgs.item(i);
if (in_array(i, lines_pattern) && the_img.src.indexOf('ftv2blank.gif') != -1) {
the_img.src = TREE_ICONS_PATH+'/ftv2vertline.gif';
}
if (this.isNodeImage(the_img))
{
found = true;
break;
}
}
if (found) {
the_img.src = this.getNodeImage(is_last);
}
this.isLast = is_last;
return lines_pattern;
}
TreeItem.prototype.isNodeImage = function(img)
{
return (
img.src.indexOf('ftv2node.gif') != -1 ||
img.src.indexOf('ftv2lastnode.gif') != -1
)
}
TreeItem.prototype.locateLastItem = function()
{
return this;
}
+
+TreeItem.prototype.locateItemByURL = function(url)
+{
+ if (this.Url == url) return this;
+ return false;
+}
+
+TreeItem.prototype.locateItemByKey = function(key)
+{
+ if (this.Key == key) return this;
+ return false;
+}
+
+TreeItem.prototype.reload = function()
+{
+}
+
/* FOLDER */
function TreeFolder(parent_id, title, url, icon, late_load_url, onclick)
{
var render = false;
if (isset(parent_id)) {
this.ParentElement = document.getElementById(parent_id);
render = true;
}
+ else {
+
+
+ }
this.Title = title;
this.Url = url;
this.Rendered = false;
this.Displayed = false;
this.Expanded = false;
this.Level = 0;
+ this.Id = 0;
this.Tr = null;
this.Icon = icon;
this.LateLoadURL = isset(late_load_url) ? late_load_url : false;
this.Loaded = false;
this.Onclick = onclick;
this.Children = new Array();
this.ChildIndex = 0;
if (render) {
this.Expanded = true;
this.Displayed = true;
this.Render();
this.expand();
}
}
TreeFolder.prototype = new TreeItem;
TreeFolder.prototype.locateLastItem = function()
{
if (this.Children.length == 0) return this;
for (var i=0; i<this.Children.length; i++)
{
last_item = this.Children[i].locateLastItem()
}
return last_item;
}
+TreeFolder.prototype.locateItemByURL = function(url)
+{
+ last_item = false;
+ if (this.Url == url) {
+ return this;
+ }
+
+ for (var i=0; i<this.Children.length; i++)
+ {
+ last_item = this.Children[i].locateItemByURL(url)
+ if (last_item) return last_item;
+ }
+ return last_item;
+}
+
+TreeFolder.prototype.locateItemByKey = function(key)
+{
+ last_item = false;
+ if (this.Key == key) {
+ return this;
+ }
+
+ for (var i=0; i<this.Children.length; i++)
+ {
+ last_item = this.Children[i].locateItemByKey(key)
+ if (last_item) return last_item;
+ }
+ return last_item;
+}
+
TreeFolder.prototype.locateTopItem = function()
{
if (this.ParentFolder == null) return this;
return this.ParentFolder.locateTopItem();
}
TreeFolder.prototype.AddItem = function(an_item, render, display) {
an_item.ParentElement = this.ParentElement;
an_item.Level = this.ParentFolder != null ? this.Level + 1 : 0;
an_item.ParentFolder = this;
last_item = this.locateLastItem();
this.Children.push(an_item);
+ an_item.Id = this.Children.length;
an_item.Render(last_item.Tr.nextSibling);
+
+ var keys = new Array()
+ var tmp = an_item;
+ keys.push(tmp.Level + '_' + tmp.Id);
+ while (tmp.ParentFolder) {
+ tmp = tmp.ParentFolder
+ keys.push(tmp.Level + '_' + tmp.Id);
+ }
+ keys = keys.reverse();
+ key_str = keys.join('-');
+ an_item.Key = key_str;
+
if (this.Expanded)
{
an_item.display();
}
+
return an_item;
}
TreeFolder.prototype.AddFromXML = function(xml, render)
{
// start = new Date();
if (!isset(render)) render = true;
doc = getDocumentFromXML(xml);
this.LastFolder = this;
this.ProcessXMLNode(doc, render);
// end = new Date();
this.locateTopItem().updateLastNodes();
// alert('AddFromXML took: '+(end - start))
}
TreeFolder.prototype.ProcessXMLNode = function(node, render)
{
if (!isset(render)) render = true;
if (!isset(this.LastFolder)) this.LastFolder = this;
for (var i=0; i<node.childNodes.length; i++)
{
child = node.childNodes.item(i);
if (child.tagName == 'folder') {
var backupLastFolder = this.LastFolder;
this.LastFolder = this.LastFolder.AddItem(new TreeFolder(null, child.getAttribute('name'), child.getAttribute('href'), child.getAttribute('icon'), child.getAttribute('load_url'), child.getAttribute('onclick')), render);
if (child.hasChildNodes) {
this.ProcessXMLNode(child);
}
this.LastFolder = backupLastFolder;
}
else if (child.tagName == 'item') {
this.LastFolder.AddItem(new TreeItem(child.firstChild.nodeValue, child.getAttribute('href'), child.getAttribute('icon'), child.getAttribute('onclick')), render)
}
else if (child.tagName == 'tree') {
this.LastFolder = this;
this.ProcessXMLNode(child);
}
}
}
TreeFolder.prototype.getNodeImage = function(is_last)
{
if (is_last) {
return this.Expanded ? TREE_ICONS_PATH+'/ftv2mlastnode.gif' : TREE_ICONS_PATH+'/ftv2plastnode.gif';
}
else {
return this.Expanded ? TREE_ICONS_PATH+'/ftv2mnode.gif' : TREE_ICONS_PATH+'/ftv2pnode.gif';
}
}
TreeFolder.prototype.appendNodeImage = function(td, is_last)
{
img = document.createElement('img');
img.src = this.getNodeImage(is_last);
img.style.cursor = 'hand';
img.style.cursor = 'pointer';
img.style.verticalAlign = 'middle';
img.onclick = function() { this.parentNode.TreeElement.folderClick(this) }
this.Img = img;
td.appendChild(img);
}
TreeFolder.prototype.updateLastNodes = function(is_last, lines_pattern)
{
if (!isset(is_last)) is_last = true;
if (!isset(lines_pattern)) { var lines_pattern = new Array() }
if (!is_last && !in_array(this.Level, lines_pattern)) { lines_pattern.push(this.Level) }
lines_pattern = TreeItem.prototype.updateLastNodes.apply(this, new Array(is_last, lines_pattern))
for (var i=0; i<this.Children.length; i++)
{
lines_pattern = this.Children[i].updateLastNodes((i+1) == this.Children.length, lines_pattern)
}
lines_pattern[array_search(this.Level, lines_pattern)] = -1;
return lines_pattern;
}
TreeFolder.prototype.isNodeImage = function(img)
{
return (
img.src.indexOf('ftv2mlastnode.gif') != -1 ||
img.src.indexOf('ftv2plastnode.gif') != -1 ||
img.src.indexOf('ftv2mnode.gif') != -1 ||
img.src.indexOf('ftv2pnode.gif') != -1
)
}
TreeFolder.prototype.folderClick = function(img)
{
- if (this.LateLoadURL && !this.Loaded) {
- Request.headers['Content-type'] = 'text/xml';
- Request.makeRequest(this.LateLoadURL, false, '', this.successCallback, this.errorCallback, '', this);
- }
-
if (this.Expanded) {
this.collapse();
}
else {
this.expand();
}
}
+TreeFolder.prototype.remove = function()
+{
+ this.removeChildren();
+ var p = this.Tr.parentNode;
+ p.removeChild(this.Tr);
+}
+
+TreeFolder.prototype.removeChildren = function()
+{
+ for (var i in this.Children) {
+ this.Children[i].remove();
+ }
+ this.Children = new Array();
+}
+
TreeFolder.prototype.successCallback = function ($request, $params, $object) {
- $object.ProcessXMLNode($request.responseXML);
+ if ($params == 'reload') {
+ $object.removeChildren();
+ }
$object.Loaded = true;
+ $object.ProcessXMLNode($request.responseXML);
$object.Render();
$object.locateTopItem().updateLastNodes();
$object.expand();
+ if (last_highlighted_key) {
+ var fld = $object.locateItemByKey(last_highlighted_key)
+ if (fld) {
+ fld.highLight();
+ }
+ }
+}
+
+TreeFolder.prototype.reload = function()
+{
+ Request.headers['Content-type'] = 'text/xml';
+ Request.makeRequest(this.LateLoadURL, false, '', this.successCallback, this.errorCallback, 'reload', this);
}
TreeFolder.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX ERROR: ' + Request.getErrorHtml($request));
}
TreeFolder.prototype.expand = function(mode)
{
+ this.Expanding = true;
+
if (!isset(mode)) mode = 0;
this.display();
if (mode == 0 || this.Expanded ) {
for (var i=0; i<this.Children.length; i++)
{
this.Children[i].expand(mode+1);
}
}
if (mode == 0) {
+ if (this.LateLoadURL && !this.Loaded) {
+ Request.headers['Content-type'] = 'text/xml';
+ Request.makeRequest(this.LateLoadURL, false, '', this.successCallback, this.errorCallback, '', this);
+ }
this.Expanded = true;
+ TreeManager.markStatus(this.Key, 1)
if (isset(this.Img)) {
this.Img.src = this.getNodeImage(this.isLast);
}
}
+ this.Expanding = false;
}
TreeFolder.prototype.collapse = function(mode)
{
if (!isset(mode)) mode = 0;
for (var i=0; i<this.Children.length; i++)
{
this.Children[i].collapse(mode+1);
this.Children[i].hide();
}
if (mode == 0) {
this.Expanded = false;
+ TreeManager.markStatus(this.Key, 0)
if (isset(this.Img)) {
this.Img.src = this.getNodeImage(this.isLast);
}
}
-}
\ No newline at end of file
+}
+
+
+function TreeManager() {}
+
+TreeManager.ExpandStatus = [];
+
+TreeManager.markStatus = function(id, status)
+{
+ this.ExpandStatus[id] = status;
+ if (!status) {
+ for (var i in this.ExpandStatus) {
+ if (i.indexOf(id) == 0) { // if i starts with the same as id, meaning it is its child node
+ this.ExpandStatus[i] = 0;
+ }
+ }
+ }
+ TreeManager.saveStatus()
+}
+
+TreeManager.isExpanded = function(id)
+{
+ return (this.ExpandStatus[id] == 1);
+}
+
+TreeManager.saveStatus = function ()
+{
+ var cookieString = new Array();
+
+ for (var i in this.ExpandStatus) {
+ if (this.ExpandStatus[i] == 1) {
+ cookieString.push(i);
+ }
+ }
+ document.cookie = 'TreeExpandStatus=' + cookieString.join(':');
+}
+
+TreeManager.loadStatus = function ()
+{
+ var doc_cookies = document.cookie.split('; ');
+
+ for (var i=0; i < doc_cookies.length; i++) {
+ var pair = doc_cookies[i].split('=');
+ if ('TreeExpandStatus' == pair[0] && pair[1]) {
+ var expandedBranches = pair[1].split(':');
+ for (var j=0; j<expandedBranches.length; j++) {
+ this.ExpandStatus[expandedBranches[j]] = true;
+ }
+ }
+ }
+// print_pre(this.ExpandStatus)
+}
+
+TreeManager.loadStatus();
Property changes on: branches/unlabeled/unlabeled-1.1.2/core/admin_templates/js/tree.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.65.4/core/kernel/processors/main_processor.php
===================================================================
--- branches/unlabeled/unlabeled-1.65.4/core/kernel/processors/main_processor.php (revision 7088)
+++ branches/unlabeled/unlabeled-1.65.4/core/kernel/processors/main_processor.php (revision 7089)
@@ -1,956 +1,961 @@
<?php
class kMainTagProcessor extends TagProcessor {
function Init($prefix, $special, $event_params = null)
{
parent::Init($prefix, $special, $event_params);
$actions =& $this->Application->recallObject('kActions');
$actions->Set('t', $this->Application->GetVar('t'));
$actions->Set('sid', $this->Application->GetSID());
$actions->Set('m_opener', $this->Application->GetVar('m_opener') );
}
/**
* Used to handle calls where tag name
* match with existing php function name
*
* @param Tag $tag
* @return string
*/
function ProcessTag(&$tag)
{
if ($tag->Tag=='include') $tag->Tag='MyInclude';
return parent::ProcessTag($tag);
}
/**
* Base folder for all template includes
*
* @param Array $params
* @return string
*/
function TemplatesBase($params)
{
if ($this->Application->IsAdmin()) {
$module = isset($params['module']) ? $params['module'] : 'core';
if ($module == 'in-portal') {
$module = 'kernel';
}
$path = preg_replace('/\/(.*?)\/(.*)/', $module.'/\\2', THEMES_PATH); // remove leading slash + substitute module
}
else {
$path = substr(THEMES_PATH, 1);
}
return $this->Application->BaseURL().$path;
}
/**
* Creates <base href ..> HTML tag for all templates
* affects future css, js files and href params of links
*
* @return string
* @access public
*/
function Base_Ref($params)
{
return '<base href="'.$this->TemplatesBase($params).'/" />';
}
/**
* Returns base url for web-site
*
* @return string
* @access public
*/
function BaseURL()
{
return $this->Application->BaseURL();
}
//for compatability with K3 tags
function Base($params)
{
return $this->TemplatesBase($params).'/';
}
function ProjectBase($params)
{
return $this->Application->BaseURL();
}
/*function Base($params)
{
return $this->Application->BaseURL().$params['add'];
}*/
/**
* Used to create link to any template.
* use "pass" paramter if "t" tag to specify
* prefix & special of object to be represented
* in resulting url
*
* @param Array $params
* @return string
* @access public
*/
function T($params)
{
//by default link to current template
$t = $this->SelectParam($params, 't,template');
unset($params['t']);
unset($params['template']);
$prefix=isset($params['prefix']) ? $params['prefix'] : ''; unset($params['prefix']);
$index_file = isset($params['index_file']) ? $params['index_file'] : null; unset($params['index_file']);
return $this->Application->HREF($t, $prefix, $params, $index_file);
}
function Link($params)
{
if (isset($params['template'])) {
$params['t'] = $params['template'];
unset($params['template']);
}
if (!isset($params['pass']) && !isset($params['no_pass'])) $params['pass'] = 'm';
if (isset($params['no_pass'])) unset($params['no_pass']);
if( $this->Application->GetVar('admin') ) $params['admin'] = 1;
return $this->T($params);
}
function Env($params)
{
$t = $params['template'];
unset($params['template']);
return $this->Application->BuildEnv($t, $params, 'm', null, false);
}
function FormAction($params)
{
return $this->Application->ProcessParsedTag('m', 't', array_merge($params, Array('pass'=>'all,m', 'pass_category' => 1 )) );
}
/*// NEEDS TEST
function Config($params)
{
return $this->Application->ConfigOption($params['var']);
}
function Object($params)
{
$name = $params['name'];
$method = $params['method'];
$tmp =& $this->Application->recallObject($name);
if ($tmp != null) {
if (method_exists($tmp, $method))
return $tmp->$method($params);
else
echo "Method $method does not exist in object ".get_class($tmp)." named $name<br>";
}
else
echo "Object $name does not exist in the appliaction<br>";
}*/
/**
* Tag, that always returns true.
* For parser testing purposes
*
* @param Array $params
* @return bool
* @access public
*/
function True($params)
{
return true;
}
/**
* Tag, that always returns false.
* For parser testing purposes
*
* @param Array $params
* @return bool
* @access public
*/
function False($params)
{
return false;
}
/**
* Returns block parameter by name
*
* @param Array $params
* @return stirng
* @access public
*/
function Param($params)
{
//$parser =& $this->Application->recallObject('TemplateParser');
$res = $this->Application->Parser->GetParam($params['name']);
if ($res === false) $res = '';
if (isset($params['plus']))
$res += $params['plus'];
return $res;
}
function DefaultParam($params)
{
foreach ($params as $key => $val) {
if ($this->Application->Parser->GetParam($key) === false) {
$this->Application->Parser->SetParam($key, $val);
}
}
}
/**
* Gets value of specified field from specified prefix_special and set it as parser param
*
* @param Array $params
*/
/*function SetParam($params)
{
// <inp2:m_SetParam param="custom_name" src="cf:FieldName"/>
list($prefix_special, $field_name) = explode(':', $params['src']);
$object =& $this->Application->recallObject($prefix_special);
$name = $this->SelectParam($params, 'param,name,var');
$this->Application->Parser->SetParam($name, $object->GetField($field_name) );
}*/
/**
* Compares block parameter with value specified
*
* @param Array $params
* @return bool
* @access public
*/
function ParamEquals($params)
{
//$parser =& $this->Application->recallObject('TemplateParser');
$name = $this->SelectParam($params, 'name,var,param');
$value = $params['value'];
return ($this->Application->Parser->GetParam($name) == $value);
}
/*function PHP_Self($params)
{
return $HTTP_SERVER_VARS['PHP_SELF'];
}
*/
/**
* Returns session variable value by name
*
* @param Array $params
* @return string
* @access public
*/
function Recall($params)
{
$ret = $this->Application->RecallVar( $this->SelectParam($params,'name,var,param') );
$ret = ($ret === false && isset($params['no_null'])) ? '' : $ret;
if( getArrayValue($params,'special') || getArrayValue($params,'htmlchars')) $ret = htmlspecialchars($ret);
if ( getArrayValue($params, 'urlencode') ) $ret = urlencode($ret);
return $ret;
}
+ function RemoveVar($params)
+ {
+ $this->Application->RemoveVar( $this->SelectParam($params,'name,var,param') );
+ }
+
// bad style to store something from template to session !!! (by Alex)
// Used here only to test how session works, nothing more
function Store($params)
{
//echo"Store $params[name]<br>";
$name = $params['name'];
$value = $params['value'];
$this->Application->StoreVar($name,$value);
}
/**
* Sets application variable value(-s)
*
* @param Array $params
* @access public
*/
function Set($params)
{
foreach ($params as $param => $value) {
$this->Application->SetVar($param, $value);
}
}
/**
* Increment application variable
* specified by number specified
*
* @param Array $params
* @access public
*/
function Inc($params)
{
$this->Application->SetVar($params['param'], $this->Application->GetVar($params['param']) + $params['by']);
}
/**
* Retrieves application variable
* value by name
*
* @param Array $params
* @return string
* @access public
*/
function Get($params)
{
$ret = $this->Application->GetVar($this->SelectParam($params, 'name,var,param'), '');
return getArrayValue($params, 'htmlchars') ? htmlspecialchars($ret) : $ret;
}
/**
* Retrieves application constant
* value by name
*
* @param Array $params
* @return string
* @access public
*/
function GetConst($params)
{
return defined($this->SelectParam($params, 'name,const')) ? constant($this->SelectParam($params, 'name,const,param')) : '';
}
/**
* Retrieves configuration variable value by name
*
* @param Array $params
* @return string
* @access public
*/
function GetConfig($params)
{
$config_name = $this->SelectParam($params, 'name,var');
$ret = $this->Application->ConfigValue($config_name);
if( getArrayValue($params, 'escape') ) $ret = addslashes($ret);
return $ret;
}
function ConfigEquals($params)
{
$option = $this->SelectParam($params, 'name,option,var');
return $this->Application->ConfigValue($option) == getArrayValue($params, 'value');
}
/**
* Creates all hidden fields
* needed for kernel_form
*
* @param Array $params
* @return string
* @access public
*/
function DumpSystemInfo($params)
{
$actions =& $this->Application->recallObject('kActions');
$actions->Set('t', $this->Application->GetVar('t') );
$params = $actions->GetParams();
$o='';
foreach ($params AS $name => $val)
{
$o .= "<input type='hidden' name='$name' id='$name' value='$val'>\n";
}
return $o;
}
function GetFormHiddens($params)
{
$sid = $this->Application->GetSID();
$t = $this->SelectParam($params, 'template,t');
unset($params['template']);
$env = $this->Application->BuildEnv($t, $params, 'm', null, false);
$o = '';
if ( $this->Application->RewriteURLs() )
{
$session =& $this->Application->recallObject('Session');
if ($session->NeedQueryString()) {
$o .= "<input type='hidden' name='sid' id='sid' value='$sid'>\n";
}
}
else {
$o .= "<input type='hidden' name='env' id='env' value='$env'>\n";
}
if ($this->Application->GetVar('admin') == 1) {
$o .= "<input type='hidden' name='admin' id='admin' value='1'>\n";
}
return $o;
}
function Odd_Even($params)
{
$odd = $params['odd'];
$even = $params['even'];
if (!isset($params['var'])) {
$var = 'odd_even';
}
else {
$var = $params['var'];
}
if ($this->Application->GetVar($var) == 'even') {
if (!isset($params['readonly']) || !$params['readonly']) {
$this->Application->SetVar($var, 'odd');
}
return $even;
}
else {
if (!isset($params['readonly']) || !$params['readonly']) {
$this->Application->SetVar($var, 'even');
}
return $odd;
}
}
/**
* Returns phrase translation by name
*
* @param Array $params
* @return string
* @access public
*/
function Phrase($params)
{
// m:phrase name="phrase_name" default="Tr-alala" updated="2004-01-29 12:49"
if (array_key_exists('default', $params)) return $params['default']; //backward compatibility
$translation = $this->Application->Phrase($this->SelectParam($params, 'label,name,title'));
if (getArrayValue($params, 'escape')) {
$translation = htmlspecialchars($translation);
$translation = str_replace('\'', ''', $translation);
$translation = addslashes($translation);
}
return $translation;
}
// for tabs
function is_active($params)
{
$test_templ = $this->SelectParam($params, 'templ,template,t');
if ( !getArrayValue($params,'allow_empty') )
{
$if_true=getArrayValue($params,'true') ? $params['true'] : 1;
$if_false=getArrayValue($params,'false') ? $params['false'] : 0;
}
else
{
$if_true=$params['true'];
$if_false=$params['false'];
}
if ( preg_match("/^".str_replace('/', '\/', $test_templ)."/i", $this->Application->GetVar('t'))) {
return $if_true;
}
else {
return $if_false;
}
}
function IsNotActive($params)
{
return !$this->is_active($params);
}
function IsActive($params)
{
return $this->is_active($params);
}
function is_t_active($params)
{
return $this->is_active($params);
}
function CurrentTemplate($params)
{
return $this->is_active($params);
}
/**
* Checks if session variable
* specified by name value match
* value passed as parameter
*
* @param Array $params
* @return string
* @access public
*/
function RecallEquals($params)
{
$name = $this->SelectParam($params, 'name,var');
$value = $params['value'];
return ($this->Application->RecallVar($name) == $value);
}
/**
* Checks if application variable
* specified by name value match
* value passed as parameter
*
* @param Array $params
* @return bool
* @access public
*/
function GetEquals($params)
{
$name = $this->SelectParam($params, 'var,name,param');
$value = $params['value'];
if ($this->Application->GetVar($name) == $value) {
return 1;
}
}
/**
* Includes template
* and returns it's
* parsed version
*
* @param Array $params
* @return string
* @access public
*/
function MyInclude($params)
{
$BlockParser =& $this->Application->makeClass('TemplateParser');
// $BlockParser->SetParams($params);
$parser =& $this->Application->Parser;
$this->Application->Parser =& $BlockParser;
// this is for the parser to know the master template in case an error occurs,
// ParseTemplate will reset it anyway, but this will allow error handler to display the tempalte
// which tries to include missing template for example
$this->Application->Parser->TemplateName = $parser->TemplateName;
$t = $this->SelectParam($params, 't,template,block,name');
$t = eregi_replace("\.tpl$", '', $t);
if (!$t) {
trigger_error('Template name not specified in <b><inp2:m_include .../></b> tag', E_USER_ERROR);
}
$res = $BlockParser->ParseTemplate( $t, 1, $params, isset($params['is_silent']) ? 1 : 0 );
if ( !$BlockParser->DataExists && (isset($params['data_exists']) || isset($params['block_no_data'])) ) {
if ($block_no_data = getArrayValue($params, 'block_no_data')) {
$res = $BlockParser->Parse(
$this->Application->TemplatesCache->GetTemplateBody($block_no_data, getArrayValue($params, 'is_silent') ),
$t
);
}
else {
$res = '';
}
}
$this->Application->Parser =& $parser;
$this->Application->Parser->DataExists = $this->Application->Parser->DataExists || $BlockParser->DataExists;
return $res;
}
function ModuleInclude($params)
{
$ret = '';
$block_params = array_merge($params, Array('is_silent' => 2)); // don't make fatal errors in case if template is missing
$current_template = $this->Application->GetVar('t');
$skip_prefixes = isset($params['skip_prefixes']) ? explode(',', $params['skip_prefixes']) : Array();
foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
$module_key = strtolower($module_name);
if ($module_name == 'In-Portal') {
$module_prefix = $this->Application->IsAdmin() ? 'in-portal/' : '';
}
else {
$module_prefix = $this->Application->IsAdmin() ? $module_key.'/' : $module_data['TemplatePath'].'/';
}
$block_params['t'] = $module_prefix.$this->SelectParam($params, $module_key.'_template,'.$module_key.'_t,template,t');
if ($block_params['t'] == $current_template || in_array($module_data['Var'], $skip_prefixes)) continue;
$no_data = $this->SelectParam($params, $module_key.'_block_no_data,block_no_data');
if ($no_data) {
$block_params['block_no_data'] = $module_prefix.'/'.$no_data;
}
$ret .= $this->MyInclude($block_params);
}
return $ret;
}
function ModuleEnabled($params)
{
return $this->Application->isModuleEnabled( $params['module'] );
}
/*function Kernel_Scripts($params)
{
return '<script type="text/javascript" src="'.PROTOCOL.SERVER_NAME.BASE_PATH.'/kernel3/js/grid.js"></script>';
}*/
/*function GetUserPermission($params)
{
// echo"GetUserPermission $params[name]";
if ($this->Application->RecallVar('user_type') == 1)
return 1;
else {
$perm_name = $params[name];
$aPermissions = unserialize($this->Application->RecallVar('user_permissions'));
if ($aPermissions)
return $aPermissions[$perm_name];
}
}*/
/**
* Set's parser block param value
*
* @param Array $params
* @access public
*/
function AddParam($params)
{
$parser =& $this->Application->Parser; // recallObject('TemplateParser');
foreach ($params as $param => $value) {
$this->Application->SetVar($param, $value);
$parser->SetParam($param, $value);
$parser->AddParam('/\$'.$param.'/', $value);
}
}
/*function ParseToVar($params)
{
$var = $params['var'];
$tagdata = $params['tag'];
$parser =& $this->Application->Parser; //recallObject('TemplateParser');
$res = $this->Application->ProcessTag($tagdata);
$parser->SetParam($var, $res);
$parser->AddParam('/\$'.$var.'/', $res);
return '';
}*/
/*function TagNotEmpty($params)
{
$tagdata = $params['tag'];
$res = $this->Application->ProcessTag($tagdata);
return $res != '';
}*/
/*function TagEmpty($params)
{
return !$this->TagNotEmpty($params);
}*/
/**
* Parses block and returns result
*
* @param Array $params
* @return string
* @access public
*/
function ParseBlock($params)
{
$parser =& $this->Application->Parser; // recallObject('TemplateParser');
return $parser->ParseBlock($params);
}
function RenderElement($params)
{
return $this->ParseBlock($params);
}
function RenderElements($params)
{
if (!isset($params['elements']) || !$params['elements']) return;
$elements = explode(',',$params['elements']);
if (isset($params['skip']) && $params['skip']) {
$tmp_skip = explode(',',$params['skip']);
foreach ($tmp_skip as $elem) {
$skip[] = trim($elem);
}
}
else {
$skip = array();
}
unset($params['elements']);
$o = '';
foreach ($elements as $an_element)
{
$cur = trim($an_element);
if (in_array($cur,$skip)) continue;
$pass_params = $params;
$pass_params['name'] = $cur;
$o .= $this->ParseBlock($pass_params);
}
return $o;
}
/**
* Checks if debug mode is on
*
* @return bool
* @access public
*/
function IsDebugMode()
{
return $this->Application->isDebugMode();
}
function MassParse($params)
{
$qty = $params['qty'];
$block = $params['block'];
$mode = $params['mode'];
$o = '';
if ($mode == 'func') {
$func = create_function('$params', '
$o = \'<tr>\';
$o.= \'<td>a\'.$params[\'param1\'].\'</td>\';
$o.= \'<td>a\'.$params[\'param2\'].\'</td>\';
$o.= \'<td>a\'.$params[\'param3\'].\'</td>\';
$o.= \'<td>a\'.$params[\'param4\'].\'</td>\';
$o.= \'</tr>\';
return $o;
');
for ($i=1; $i<$qty; $i++) {
$block_params['param1'] = rand(1, 10000);
$block_params['param2'] = rand(1, 10000);
$block_params['param3'] = rand(1, 10000);
$block_params['param4'] = rand(1, 10000);
$o .= $func($block_params);
}
return $o;
}
$block_params['name'] = $block;
for ($i=0; $i<$qty; $i++) {
$block_params['param1'] = rand(1, 10000);
$block_params['param2'] = rand(1, 10000);
$block_params['param3'] = rand(1, 10000);
$block_params['param4'] = rand(1, 10000);
$block_params['passed'] = $params['passed'];
$block_params['prefix'] = 'm';
$o.= $this->Application->ParseBlock($block_params, 1);
}
return $o;
}
function LoggedIn($params)
{
return $this->Application->LoggedIn();
}
/**
* Allows to check if permission exists directly in template and perform additional actions if required
*
* @param Array $params
* @return bool
*/
function CheckPermission($params)
{
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
return $perm_helper->TagPermissionCheck($params, 'm_CheckPermission');
}
/**
* Checks if user is logged in and if not redirects it to template passed
*
* @param Array $params
*/
function RequireLogin($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
// check by permissions: begin
if ((isset($params['perm_event']) && $params['perm_event']) ||
(isset($params['perm_prefix']) && $params['perm_prefix']) ||
(isset($params['permissions']) && $params['permissions'])) {
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
-
+
$perm_status = $perm_helper->TagPermissionCheck($params, 'm_RequireLogin');
if (!$perm_status) {
list($redirect_template, $redirect_params) = $perm_helper->getPermissionTemplate($params);
$this->Application->Redirect($redirect_template, $redirect_params);
}
else {
return ;
}
}
// check by permissions: end
// check by configuration value: begin
$condition = getArrayValue($params, 'condition');
if (!$condition) {
$condition = true;
}
else {
if (substr($condition, 0, 1) == '!') {
$condition = !$this->Application->ConfigValue(substr($condition, 1));
}
else {
$condition = $this->Application->ConfigValue($condition);
}
}
// check by configuration value: end
// check by belonging to group: begin
$group = $this->SelectParam($params, 'group');
$group_access = true;
if ($group) {
$conn =& $this->Application->GetADODBConnection();
$group_id = $conn->GetOne('SELECT GroupId FROM '.TABLE_PREFIX.'PortalGroup WHERE Name = '.$conn->qstr($group));
if ($group_id) {
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
$group_access = in_array($group_id, $groups);
}
}
// check by belonging to group: end
if ((!$this->Application->LoggedIn() || !$group_access) && $condition) {
if ( $this->Application->LoggedIn() && !$group_access) {
$this->Application->Redirect( $params['no_group_perm_template'], Array('next_template'=>$t) );
}
$redirect_params = Array('next_template' => $t);
$session_expired = $this->Application->GetVar('expired');
if ($session_expired) {
$redirect_params['expired'] = $session_expired;
}
$this->Application->Redirect($params['login_template'], $redirect_params);
}
}
function IsMember($params)
{
$group = getArrayValue($params, 'group');
$conn =& $this->Application->DB;
$group_id = $conn->GetOne('SELECT GroupId FROM '.TABLE_PREFIX.'PortalGroup WHERE Name = '.$conn->qstr($group));
if ($group_id) {
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
$group_access = in_array($group_id, $groups);
}
return $group_access;
}
/**
* Checks if SSL is on and redirects to SSL URL if needed
* If SSL_URL is not defined in config - the tag does not do anything
* If for_logged_in_only="1" exits if user is not logged in.
* If called without params forces https right away. If called with by_config="1" checks the
* Require SSL setting from General Config and if it is ON forces https
*
* @param unknown_type $params
*/
function CheckSSL($params)
{
$ssl = $this->Application->ConfigValue('SSL_URL');
if (!$ssl) return; //SSL URL is not set - no way to require SSL
$require = false;
if (isset($params['mode']) && $params['mode'] == 'required') {
$require = true;
if (isset($params['for_logged_in_only']) && $params['for_logged_in_only'] && !$this->Application->LoggedIn()) {
$require = false;
}
if (isset($params['condition'])) {
if (!$this->Application->ConfigValue($params['condition'])) {
$require = false;
}
}
}
$http_query =& $this->Application->recallObject('HTTPQuery');
$pass = $http_query->getRedirectParams();
if ($require) {
if (PROTOCOL == 'https://') {
$this->Application->SetVar('__KEEP_SSL__', 1);
return;
}
$this->Application->Redirect('', array_merge_recursive2($pass, Array('__SSL__' => 1)));
}
else {
if (PROTOCOL == 'https://' && $this->Application->ConfigValue('Force_HTTP_When_SSL_Not_Required')) {
if ($this->Application->GetVar('__KEEP_SSL__')) return;
$pass = array('pass'=>'m', 'm_cat_id'=>0);
$this->Application->Redirect('', array_merge_recursive2($pass, Array('__SSL__' => 0)));
}
}
}
function ConstOn($params)
{
$name = $this->SelectParam($params,'name,const');
return constOn($name);
}
function SetDefaultCategory($params)
{
$module_name = $params['module'];
$module =& $this->Application->recallObject('mod.'.$module_name);
$this->Application->SetVar('m_cat_id', $module->GetDBField('RootCat') );
}
function XMLTemplate($params)
{
safeDefine('DBG_SKIP_REPORTING', 1);
$lang =& $this->Application->recallObject('lang.current');
header('Content-type: text/xml; charset='.$lang->GetDBField('Charset'));
}
function Header($params)
{
header($params['data']);
}
function NoDebug($params)
{
define('DBG_SKIP_REPORTING', 1);
}
function RootCategoryName($params)
{
$root_phrase = $this->Application->ConfigValue('Root_Name');
return $this->Application->Phrase($root_phrase);
}
function AttachFile($params)
{
$email_object =& $this->Application->recallObject('kEmailMessage');
$path = FULL_PATH.'/'.$params['path'];
if (file_exists($path)) {
$email_object->attachFile($path);
}
}
function CaptchaImage($params){
$captcha_helper =& $this->Application->recallObject('CaptchaHelper');
$captcha_helper->GenerateCaptchaImage(
$this->Application->RecallVar($this->Application->GetVar('var')),
$this->Application->GetVar('w'),
$this->Application->GetVar('h'),
true
);
}
}
Property changes on: branches/unlabeled/unlabeled-1.65.4/core/kernel/processors/main_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.65.4.5
\ No newline at end of property
+1.65.4.6
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.8.2/core/units/categories/cache_updater.php
===================================================================
--- branches/unlabeled/unlabeled-1.8.2/core/units/categories/cache_updater.php (revision 7088)
+++ branches/unlabeled/unlabeled-1.8.2/core/units/categories/cache_updater.php (revision 7089)
@@ -1,401 +1,415 @@
<?php
class clsRecursionStack
{
var $Stack;
function clsRecursionStack()
{
$this->Stack = Array();
}
function Push($values)
{
array_push($this->Stack, $values);
}
function Pop()
{
if ($this->Count() > 0) {
return array_pop($this->Stack);
}
else {
return false;
}
}
function Get()
{
if ($this->Count() > 0) {
// return end($this->Stack);
return $this->Stack[count($this->Stack)-1];
}
else {
return false;
}
}
function Update($values)
{
$this->Stack[count($this->Stack)-1] = $values;
}
function Count()
{
return count($this->Stack);
}
}
class clsCachedPermissions
{
var $Allow = Array();
var $Deny = Array();
var $CatId;
function clsCachedPermissions($CatId)
{
$this->CatId = $CatId;
}
function SetCatId($CatId)
{
$this->CatId = $CatId;
}
function CheckPermArray($Perm)
{
if (!isset($this->Allow[$Perm])) {
$this->Allow[$Perm] = array();
$this->Deny[$Perm] = array();
}
}
function AddAllow($Perm, $GroupId)
{
$this->CheckPermArray($Perm);
if (!in_array($GroupId, $this->Allow[$Perm])) {
array_push($this->Allow[$Perm], $GroupId);
$this->RemoveDeny($Perm, $GroupId);
}
}
function AddDeny($Perm, $GroupId)
{
$this->CheckPermArray($Perm);
if (!in_array($GroupId, $this->Deny[$Perm])) {
array_push($this->Deny[$Perm], $GroupId);
$this->RemoveAllow($Perm, $GroupId);
}
}
function RemoveDeny($Perm, $GroupId)
{
if (in_array($GroupId, $this->Deny[$Perm])) {
array_splice($this->Deny[$Perm], array_search($GroupId, $this->Deny[$Perm]), 1);
}
}
function RemoveAllow($Perm, $GroupId)
{
if (in_array($GroupId, $this->Allow[$Perm])) {
array_splice($this->Allow[$Perm], array_search($GroupId, $this->Allow[$Perm]), 1);
}
}
function GetInsertSQL()
{
$values = array();
$has_deny = array();
// don't write DACL at all
/*foreach ($this->Deny as $perm => $groups) {
if (count($groups) > 0) {
$values[] = '('.$this->CatId.', '.$perm.', "", "'.join(',', $groups).'")';
$has_deny[] = $perm;
}
}*/
foreach ($this->Allow as $perm => $groups) {
// if (in_array($perm, $has_deny)) continue;
if (count($groups) > 0) {
$values[] = '(' .$this->CatId. ', ' .$perm. ', "' .join(',', $groups). '", "")';
}
}
if (!$values) return '';
$sql = 'INSERT INTO '.TABLE_PREFIX.'PermCache (CategoryId, PermId, ACL, DACL) VALUES '.join(',', $values);
return $sql;
}
}
class kPermCacheUpdater extends kHelper
{
+ /**
+ * Holds Stack
+ *
+ * @var clsRecursionStack
+ */
var $Stack;
var $iteration;
var $totalCats;
var $doneCats;
var $table;
var $primaryLanguageId = 0;
var $languageCount = 0;
var $root_prefixes = Array();
var $StrictPath = false;
function Init($prefix, $special, $event_params = null)
{
parent::Init($prefix, $special, $event_params);
$continuing = isset($event_params['continue']) ? $event_params['continue'] : 1;
$this->StrictPath = isset($event_params['strict_path']) ? $event_params['strict_path'] : false;
if ($this->StrictPath && !is_array($this->StrictPath)) {
$this->StrictPath = explode('|', trim($this->StrictPath, '|'));
}
// cache widely used values to speed up process: begin
$ml_helper =& $this->Application->recallObject('kMultiLanguageHelper');
$this->languageCount = $ml_helper->getLanguageCount();
$this->primaryLanguageId = $this->Application->GetDefaultLanguageId();
// cache widely used values to speed up process: end
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$this->root_prefixes[ $module_info['RootCat'] ] = $module_info['Var'];
}
$this->iteration = 0;
$this->table = $this->Application->GetTempName('permCacheUpdate');
if ($continuing == 1) {
$this->InitUpdater();
}
elseif ($continuing == 2) {
$this->getData();
}
}
function InitUpdater()
{
$this->Stack =& new clsRecursionStack();
$sql = 'DELETE FROM '.TABLE_PREFIX.'PermCache';
if ($this->StrictPath) {
$sql .= ' WHERE CategoryId IN ('.implode(',',$this->StrictPath).')';
}
$this->Conn->Query($sql);
$this->initData();
}
function getDonePercent()
{
if(!$this->totalCats)return 0;
return min(100, intval( round( $this->doneCats / $this->totalCats * 100 ) ));
}
function getData()
{
$tmp = $this->Conn->GetOne('SELECT data FROM '.$this->table);
if ($tmp) $tmp = unserialize($tmp);
$this->totalCats = isset($tmp['totalCats']) ? $tmp['totalCats'] : 0;
$this->doneCats = isset($tmp['doneCats']) ? $tmp['doneCats'] : 0;
if (isset($tmp['stack'])) {
$this->Stack = $tmp['stack'];
}
else {
$this->Stack = & new clsRecursionStack();
}
}
function setData()
{
$tmp = Array (
'totalCats' => $this->totalCats,
'doneCats' => $this->doneCats,
'stack' => $this->Stack,
);
$this->Conn->Query('DELETE FROM '.$this->table);
$fields_hash = Array('data' => serialize($tmp));
$this->Conn->doInsert($fields_hash, $this->table);
}
function initData()
{
$this->clearData(); // drop table before starting anyway
$this->Conn->Query('CREATE TABLE '.$this->table.'(data LONGTEXT)');
$this->totalCats = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Category');
$this->doneCats = 0;
}
function clearData()
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$this->table);
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = \'ForcePermCacheUpdate\'');
}
function DoTheJob()
{
$data = $this->Stack->Get();
if ($data === false) { //If Stack is empty
$data['current_id'] = 0;
$data['titles'] = Array();
$data['parent_path'] = Array();
$data['named_path'] = Array();
$data['category_template'] = '';
$data['item_template'] = '';
+ $data['children_count'] = 0;
$this->Stack->Push($data);
}
if (!isset($data['queried'])) {
$this->QueryTitle($data);
$this->QueryChildren($data);
+ $data['children_count'] = count($data['children']);
$this->QueryPermissions($data);
$data['queried'] = 1;
if ($sql = $data['perms']->GetInsertSQL()) {
$this->Conn->Query($sql);
// $this->doneCats++; // moved to the place where it pops out of the stack by Kostja
}
$this->iteration++;
}
// start with first child if we haven't started yet
if (!isset($data['current_child'])) $data['current_child'] = 0;
// if we have more children
if (isset($data['children'][$data['current_child']])) {
if ($this->StrictPath) {
while ( isset($data['children'][ $data['current_child'] ]) && !in_array($data['children'][ $data['current_child'] ], $this->StrictPath) ) {
$data['current_child']++;
continue;
}
if (!isset($data['children'][ $data['current_child'] ])) return false; //error
}
$next_data = Array();
$next_data['titles'] = $data['titles'];
$next_data['parent_path'] = $data['parent_path'];
$next_data['named_path'] = $data['named_path'];
$next_data['category_template'] = $data['category_template'];
$next_data['item_template'] = $data['item_template'];
$next_data['current_id'] = $data['children'][ $data['current_child'] ]; //next iteration should process child
$next_data['perms'] = $data['perms']; //we should copy our permissions to child - inheritance
$next_data['perms']->SetCatId($next_data['current_id']);
$data['current_child']++;
$this->Stack->Update($data); //we need to update ourself for the iteration after the next (or further) return to next child
$this->Stack->Push($next_data); //next iteration should process this child
return true;
}
else {
$this->UpdateCachedPath($data);
- $this->Stack->Pop(); //remove ourself from stack if we have finished all the childs (or there are none)
+ $prev_data = $this->Stack->Pop(); //remove ourself from stack if we have finished all the childs (or there are none)
// we are getting here if we finished with current level, so check if it's first level - then bail out.
$this->doneCats++; // moved by Kostja from above, seems to fix the prob
- return $this->Stack->Count() > 0;
+ $has_more = $this->Stack->Count() > 0;
+ if ($has_more) {
+ $next_data = $this->Stack->Get();
+ $next_data['children_count'] += $data['children_count'];
+ $this->Stack->Update($next_data);
+ }
+ return $has_more;
}
}
function UpdateCachedPath(&$data)
{
$fields_hash = Array (
'ParentPath' => '|'.implode('|', $data['parent_path']).'|',
'NamedParentPath' => implode('/', $data['named_path'] ),
'CachedCategoryTemplate' => $data['category_template'],
+ 'CachedDescendantCatsQty' => $data['children_count'],
);
$i = 1;
while ($i <= $this->languageCount) {
$fields_hash['l'.$i.'_CachedNavbar'] = implode('&|&', $data['titles'][$i]);
$i++;
}
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$data['current_id']);
}
function QueryTitle(&$data)
{
$category_id = $data['current_id'];
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$category_id;
$record = $this->Conn->GetRow($sql);
if ($record) {
$i = 1;
while ($i <= $this->languageCount) {
$data['titles'][$i][] = $record['l'.$i.'_Name'] ? $record['l'.$i.'_Name'] : $record['l'.$this->primaryLanguageId.'_Name'];
$i++;
}
$data['parent_path'][] = $category_id;
$data['named_path'][] = $record['Filename'];
// it is one of the modules root category
$root_prefix = isset($this->root_prefixes[$category_id]) ? $this->root_prefixes[$category_id] : false;
if ($root_prefix) {
$fields_hash = Array();
if (!$record['CategoryTemplate']) {
$record['CategoryTemplate'] = $this->Application->ConfigValue($root_prefix.'_CategoryTemplate');
$fields_hash['CategoryTemplate'] = $record['CategoryTemplate'];
}
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Category', 'CategoryId = '.$category_id);
}
// if explicitly set, then use it; use parent template otherwise
if ($record['CategoryTemplate']) {
$data['category_template'] = $record['CategoryTemplate'];
}
}
}
function QueryChildren(&$data)
{
$sql = 'SELECT CategoryId
FROM '.TABLE_PREFIX.'Category
WHERE ParentId = '.$data['current_id'];
$data['children'] = $this->Conn->GetCol($sql);
}
function QueryPermissions(&$data)
{
// don't search for section "view" permissions here :)
$sql = 'SELECT ipc.PermissionConfigId, ip.GroupId, ip.PermissionValue
FROM '.TABLE_PREFIX.'Permissions AS ip
LEFT JOIN '.TABLE_PREFIX.'PermissionConfig AS ipc ON ipc.PermissionName = ip.Permission
WHERE (CatId = '.$data['current_id'].') AND (Permission LIKE "%.VIEW") AND (ip.Type = 0)';
$records = $this->Conn->Query($sql);
//create permissions array only if we don't have it yet (set by parent)
if (!isset($data['perms'])) {
$data['perms'] = new clsCachedPermissions($data['current_id']);
}
foreach ($records as $record) {
if ($record['PermissionValue'] == 1) {
$data['perms']->AddAllow($record['PermissionConfigId'], $record['GroupId']);
}
else {
$data['perms']->AddDeny($record['PermissionConfigId'], $record['GroupId']);
}
}
}
/**
* Rebuild all cache in one step
*
*/
function OneStepRun($path='')
{
$needs_more = true;
while ($needs_more) {
// until proceeeded in this step category count exceeds category per step limit
$needs_more = $this->DoTheJob();
}
$this->clearData();
}
}
?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.8.2/core/units/categories/cache_updater.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8.2.2
\ No newline at end of property
+1.8.2.3
\ No newline at end of property
Event Timeline
Log In to Comment