Table of contents
No headers
// SectionUI, by neilw and rberinger, 2009
//
// Version History
// 1.0.0 24-Sept-2009 neilw, rberinger First release
// 1.1.0 ??-????-2009 neilw, rberinger Added support for "Accordion" style
// 1.1.1 12-Nov-2009 neilw Slight tweak for accordion options
// 1.1.2 12-Nov-2009 neilw A bit of code cleanup
//
// Usage:
// SectionUI {
// style: str?, (default "tab") Style of UI for sections. Valid options: "tab", "accordion".
// allowEdits: bool?, (default true) Allow editing of subsections if user has permission
// showOriginal: bool?, (default false) Provide link to reload page with original version of page
// maxLength: num?, (default 0) Maximum length of tab title after which title will be truncated. "0" -> no limit
// maxHeight: str?, (default "0") Maximum height of a tab section, after which it will be scrolled. "0" -> no limit
// textSize: str?, (default "1em") Size of text in tab titles
// options: map? (default {}) Options specific to each style
// }
// Parameters
var errors = [];
// Style
var style = $0 ?? $style ?? "tab";
let style = string.tolower(style);
var allowable_styles = [ "tab", "accordion" ];
if (!list.contains(allowable_styles, style)) {
let errors ..= [ "invalid style '"..style.."': supported styles are "..
string.join(allowable_styles, ",") ];
let style = "tab";
}
// allowEdits
var allow_edits = $1 ?? $allowEdits ?? true;
if (allow_edits is not bool) {
let errors ..= [ "allowEdits parameter must be true or false" ];
let allow_edits = true;
}
// showOriginal
var show_original = $2 ?? $showOriginal ?? false;
// maxLength
var max_length = $3 ?? $maxLength ?? 0;
if (max_length is not num || max_length < 0) {
let errors ..= [ "maxLength parameter must be a non-negative number" ];
let max_length = 0;
}
// maxHeight
var max_height = $4 ?? $maxHeight ?? 0;
// textSize
var text_size = $5 ?? $textSize ?? '';
// options
var options = $6 ?? $options;
if (options is not nil && options is not map) {
let errors ..= [ "options parameter must be a map" ];
let options = nil;
}
if (style == "tab") {
let options = options ?? { collapsible:true };
if (options.event == "mouseover") // bad to use "mouseover" with "collapsible"
let options ..= { collapsible:false };
}
else if (style == "accordion") {
let options = options ?? {};
if (options.autoHeight == nil) let options ..= { autoHeight:false };
if (options.active == nil) let options ..= { active:false };
}
if (__request.args.SectionUI == false)
<p><a href=(page.uri & { sectionUI:true })> "Show transformed page" </a></p>;
else {
<html>
<head>
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.all.css" rel="stylesheet" />
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.base.css" rel="stylesheet" />
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.core.css" rel="stylesheet" />
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.theme.css" rel="stylesheet" />
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.tabs.css" rel="stylesheet" />
<link type="text/css" href="/deki/script/jquery/1.3.2/ui.accordion.css" rel="stylesheet" />
<script type="text/javascript" src="/deki/script/jquery/1.3.2/jquery-1.3.2.js"></script>
<script type="text/javascript" src="/deki/script/jquery/1.3.2/ui.core.js"></script>
<script type="text/javascript" src="/deki/script/jquery/1.3.2/ui.tabs.js"></script>
<script type="text/javascript" src="/deki/script/jquery/1.3.2/ui.accordion.js"></script>
// Hide entire page content frame until SectionUI does its thing. Optimal if at most 1 SectionUI is used on a page.
<style type="text/css"> " .pageContentFrame { display:none; } " </style>
// Call the main SectionUI function
<script type="text/javascript"> "
Deki.$(document).ready(function($) {
var id = "..json.emit(@id)..";
var $section = $('div#'+id).parent();
$('div#'+id).remove();
transform_sections($, id, $section,
"..json.emit(style)..",
"..json.emit(max_length)..",
"..json.emit(max_height)..",
"..json.emit(text_size)..",
"..json.emit(allow_edits)..",
"..json.emit(options)..");
$('div.pageContentFrame').show();
});
" </script>
// Main SectionUI function. This does all the work in mangling the HTML to enable the transformation
<script type="text/javascript"> "
function transform_sections($, id, $section, style, max_length, max_height, font_size, editable, options) {
// Figure out what header level we're at (should be simpler way to do this???)
var $outer = $section.find(':header').eq(0);
var inner;
$outer.each(function() { inner = 'h' + (1+Number(this.tagName.substr(1,1))); });
// Process options as necessary
if (font_size != '') font_size = 'font-size:'+font_size;
// First wrap entire top level section in a div
var top_id = id + 'top';
$outer.nextAll().wrapAll('<div id=\"'+top_id+'\"></div>');
// If 'tab', create a UL for tab names
if (style == 'tab') $section.find('div#'+top_id).prepend('<ul></ul>');
var $ul = $section.find('ul:first');
// Now process each of the subsections
$section.find(inner).each(function() {
$(this).hide();
var $div = $(this).parent();
// clean up extra vertical whitespace
$div.css({ 'padding-top':'5px', 'padding-bottom':'10px' });
$(this).nextAll(':first').css({'margin-top':'0px','padding-top':'0px'});
$(this).nextAll(':last').css({'margin-bottom':'0px','padding-bottom':'0px'});
// set max_height of each section
if (max_height)
$div.css({'max-height':max_height, 'overflow':'auto'});
// truncate title text if necessary
var title_text = $(this).text();
if (max_length && title_text.length > max_length) title_text = title_text.substr(0,max_length) + '...';
// Process the section title according to style
var hdr_link = '<a style=\"'+font_size+';text-decoration:none;\" href=\"#'+$div.attr('id')+'\" title=\"'+title_text+'\">' + title_text +
'<span class=\"icon\" style=\"visibility:hidden; margin-left:10px\">' +
'<img class=\"sectionedit\" alt=\"Edit section\" src=\"/skins/common/icons/icon-trans.gif\" style=\"cursor:pointer\"/></span></a>';
switch(style) {
case 'tab': // add tab title to <ul>
$ul.append('<li style=\"list-style-type:none\">' + hdr_link + '</li>');
break;
case 'accordion': // insert title before <div>
$div.before('<div class=\"accordion-header\">' + hdr_link + '</div>'); break;
default: break;
}
// Add pop-up 'edit' icon, if enabled
if (editable && $(this).find('div.editIcon').length) {
var $header = (style == 'tab' ? $ul.find('li:last') :
$section.find('div.accordion-header:last'));
$header.hover(
function() {
if (!Deki.Editor || (!Deki.Editor.IsLoading && !Deki.Editor.IsStarted))
$(this).find('span:last').css('visibility','visible');
},
function() { $(this).find('span:last').css('visibility','hidden'); }
);
var $tab = $header.find('a:first');
$header.find('img:last').click(function() {
$tab.click();
$div.find(inner+' a:last').click();
return(false);
});
}
});
// Call appropriate styler
switch(style) {
case 'tab':
$('#'+top_id).tabs(options); break;
case 'accordion':
options.header = 'div.accordion-header';
$('#'+top_id).accordion(options); break; default: break;
}
}
" </script>
</head>
<body>
<div id=(@id) />; // Marker
<div id=(@id.."original") // "Show Original" link
style=("width:100%;text-align:right;font-size:.7em;visibility:"..(show_original?"visible":"hidden"))>
<a href=(page.uri&{SectionUI:false})> (show_original ? "show original" : ".") </a>
</div>;
if (#errors) {
<p style="color:red">
"ERRORS:"; <br />;
foreach (var e in errors) { e; <br />; }
</p>
}
</body>
</html>
}

Comments