impl options explanation, uiLock (#343)

* update schemas

* update

* killed upstream change

* min prio is now 100

* reset watchdog regularly

* update

* fix

* update
This commit is contained in:
brindosch
2016-12-21 18:24:03 +01:00
committed by GitHub
parent 0414e3c860
commit 88bed79c07
34 changed files with 879 additions and 399 deletions

View File

@@ -30,7 +30,7 @@ JSONEditor.defaults.editors.colorPicker = JSONEditor.defaults.editors.string.ext
build: function() {
this._super();
var myinput = this;
$(myinput.input).parent().attr("class", $(myinput.input).parent().attr('class') + " colorpicker-element");
$(myinput.input).parent().attr("class", $(myinput.input).parent().attr('class') + " colorpicker-element input-group");
$(myinput.input).append("<span class='input-group-addon' id='event_catcher'><i></i></span>");
$(myinput.input).colorpicker({
format: 'rgb',
@@ -116,7 +116,7 @@ $(hyperion).one("cmd-config-getschema", function(event) {
if (effects[idx].schemaContent.script == this.value){
effects_editor = createJsonEditor('editor_container', {
args : effects[idx].schemaContent,
},false);
},false, true);
effectPy = ':';
effectPy += effects[idx].schemaContent.script;
}
@@ -130,7 +130,7 @@ $(hyperion).one("cmd-config-getschema", function(event) {
});
});
$("#name-input").on('change keydown click', function(event) {
$("#name-input").on('change keydown click focusout', function(event) {
effectName = $(this).val();
if ($(this).val() == '') {
effects_editor.disable();

View File

@@ -1,17 +1,26 @@
var conf_editor = null;
var conf_editor_v4l2 = null;
var conf_editor_fg = null;
$(hyperion).one("cmd-config-getschema", function(event) {
schema = parsedConfSchemaJSON.properties;
conf_editor = createJsonEditor('editor_container', {
framegrabber: schema.framegrabber,
grabberV4L2 : schema.grabberV4L2
}, true);
conf_editor_fg = createJsonEditor('editor_container_fg', {
framegrabber: schema.framegrabber
}, true, true);
$('#btn_submit').off().on('click',function() {
requestWriteConfig(conf_editor.getValue());
$('#btn_submit_fg').off().on('click',function() {
requestWriteConfig(conf_editor_fg.getValue());
});
conf_editor_v4l2 = createJsonEditor('editor_container_v4l2', {
grabberV4L2 : schema.grabberV4L2
}, true, true);
$('#btn_submit_v4l2').off().on('click',function() {
requestWriteConfig(conf_editor_v4l2.getValue());
});
$('#opt_expl_fg').html(createHelpTable(schema.framegrabber.properties, '<i class="fa fa-camera fa-fw"></i>'+$.i18n("edt_conf_fg_heading_title")));
$('#opt_expl_v4l2').html(createHelpTable(schema.grabberV4L2.items.properties, '<i class="fa fa-camera fa-fw"></i>'+$.i18n("edt_conf_v4l2_heading_title")));
});

View File

@@ -1,4 +1,6 @@
$(document).ready( function() {
var uiLock = false;
$("#main-nav").hide();
$("#loading_overlay").addClass("overlay");
loadContentTo("#container_connection_lost","connection_lost");
@@ -22,12 +24,6 @@ $(document).ready( function() {
parsedServerInfoJSON = event.response;
currentVersion = parsedServerInfoJSON.info.hyperion[0].version;
cleanCurrentVersion = currentVersion.replace(/\./g, '');
// ToDo lock config menu and display appropriate message
if (! parsedServerInfoJSON.info.hyperion[0].config_writeable)
{
console.log("ATTENTION config is not writable");
}
if (parsedServerInfoJSON.info.hyperion[0].config_modified)
$("#hyperion_reload_notify").fadeIn("fast");
@@ -78,7 +74,7 @@ $(document).ready( function() {
});
}
if ($("#logmessages").length == 0)
if ($("#logmessages").length == 0 && loggingStreamActive)
{
requestLoggingStop();
}
@@ -87,6 +83,19 @@ $(document).ready( function() {
$("#loading_overlay").removeClass("overlay");
$("#main-nav").show('slide', {direction: 'left'}, 1000);
if (!parsedServerInfoJSON.info.hyperion[0].config_writeable)
{
showInfoDialog('uilock',$.i18n('InfoDialog_nowrite_title'),$.i18n('InfoDialog_nowrite_text'));
$('#wrapper').toggle(false);
uiLock = true;
}
else if (uiLock)
{
$("#modal_dialog").modal('hide');
$('#wrapper').toggle(true);
uiLock = false;
}
}); // end cmd-serverinfo
$(hyperion).one("cmd-config-getschema", function(event) {
@@ -108,11 +117,7 @@ $(document).ready( function() {
});
$("#btn_hyperion_reload").on("click", function(){
$(hyperion).off();
requestServerConfigReload();
watchdog = 1;
$("#wrapper").fadeOut("slow");
cron();
initRestart();
});
});

View File

@@ -4,18 +4,19 @@ $(hyperion).one("cmd-config-getschema", function(event) {
schema = parsedConfSchemaJSON.properties;
conf_editor = createJsonEditor('editor_container', {
kodiVideoChecker: schema.kodiVideoChecker
}, true);
$('#editor_container h3').remove();
}, true, true);
$('#btn_submit').off().on('click',function() {
requestWriteConfig(conf_editor.getValue());
});
$('#opt_expl').html(createHelpTable(schema.kodiVideoChecker.properties, '<i class="fa fa-play-circle-o fa-fw"></i>'+$.i18n("conf_kodi_label_title")));
});
$(document).ready( function() {
performTranslation();
requestServerConfigSchema();
});

View File

@@ -450,10 +450,9 @@ $(document).ready(function() {
}
$('#leds_canvas').html(leds_html);
$('#led_0').css({"z-index":"10"});
$('#leds_custom_updsim').trigger('click');
$('#image_preview').hide();
$('#image_preview').attr("width" , $('#leds_canvas').innerWidth()-2);
$('#image_preview').hide();
$('#image_preview').attr("width" , $('#leds_canvas').innerWidth()-2);
$('#image_preview').attr("height", $('#leds_canvas').innerHeight()-2);
});
@@ -520,6 +519,7 @@ $(document).ready(function() {
var target = $(e.target).attr("href") // activated tab
if (target == "#menu_gencfg" && !ledsCustomCfgInitialized)
{
$('#leds_custom_updsim').trigger('click');
ledsCustomCfgInitialized = true;
}
});

View File

@@ -25,7 +25,7 @@ $(document).ready(function() {
{
loggingHandlerInstalled = true;
$(hyperion).on("cmd-logging-update",function(event){
if ($("#logmessages").length == 0)
if ($("#logmessages").length == 0 && loggingStreamActive)
{
requestLoggingStop();
}

View File

@@ -1,18 +1,59 @@
var conf_editor = null;
var conf_editor_json = null;
var conf_editor_proto = null;
var conf_editor_bobl = null;
var conf_editor_udpl = null;
var conf_editor_forw = null;
$(hyperion).one("cmd-config-getschema", function(event) {
schema = parsedConfSchemaJSON.properties;
conf_editor = createJsonEditor('editor_container', {
jsonServer : schema.jsonServer,
protoServer : schema.protoServer,
boblightServer : schema.boblightServer,
udpListener : schema.udpListener,
forwarder : schema.forwarder,
}, true);
conf_editor_json = createJsonEditor('editor_container_jsonserver', {
jsonServer : schema.jsonServer
}, true, true);
$('#btn_submit').off().on('click',function() {
requestWriteConfig(conf_editor.getValue());
$('#btn_submit_jsonserver').off().on('click',function() {
requestWriteConfig(conf_editor_json.getValue());
});
conf_editor_proto = createJsonEditor('editor_container_protoserver', {
protoServer : schema.protoServer
}, true, true);
$('#btn_submit_protoserver').off().on('click',function() {
requestWriteConfig(conf_editor_proto.getValue());
});
conf_editor_bobl = createJsonEditor('editor_container_boblightserver', {
boblightServer : schema.boblightServer
}, true, true);
$('#btn_submit_boblightserver').off().on('click',function() {
requestWriteConfig(conf_editor_bobl.getValue());
});
conf_editor_udpl = createJsonEditor('editor_container_udplistener', {
udpListener : schema.udpListener
}, true, true);
$('#btn_submit_udplistener').off().on('click',function() {
requestWriteConfig(conf_editor_udpl.getValue());
});
conf_editor_forw = createJsonEditor('editor_container_forwarder', {
forwarder : schema.forwarder
}, true, true);
$('#btn_submit_forwarder').off().on('click',function() {
requestWriteConfig(conf_editor_forw.getValue());
});
$('#opt_expl_jsonserver').html(createHelpTable(schema.jsonServer.properties, '<i class="fa fa-sitemap fa-fw"></i>'+$.i18n("edt_conf_js_heading_title")));
$('#opt_expl_protoserver').html(createHelpTable(schema.protoServer.properties, '<i class="fa fa-sitemap fa-fw"></i>'+$.i18n("edt_conf_ps_heading_title")));
$('#opt_expl_boblightserver').html(createHelpTable(schema.boblightServer.properties, '<i class="fa fa-sitemap fa-fw"></i>'+$.i18n("edt_conf_bobls_heading_title")));
$('#opt_expl_udplistener').html(createHelpTable(schema.udpListener.properties, '<i class="fa fa-sitemap fa-fw"></i>'+$.i18n("edt_conf_udpl_heading_title")));
$('#opt_expl_forwarder').html(createHelpTable(schema.forwarder.properties, '<i class="fa fa-sitemap fa-fw"></i>'+$.i18n("edt_conf_fw_heading_title")));
});

View File

@@ -12,9 +12,11 @@
if (active) btn_type = "warning";
if (visible) btn_type = "success";
data += '<button id="srcBtn'+i+'" type="button" class="btn btn-lg btn-'+btn_type+' btn_input_selection" style="margin:10px;min-width:200px" onclick="requestSetSource('+priority+');">'+owner+'<span style="font-size:70% !important;"> ('+priority+')</span></button><br/>';
if(btn_type != 'default')
data += '<button id="srcBtn'+i+'" type="button" class="btn btn-lg btn-'+btn_type+' btn_input_selection" style="margin:10px;min-width:200px" onclick="requestSetSource('+priority+');">'+owner+'<span style="font-size:70% !important;"> ('+priority+')</span></button><br/>';
}
data += '<button id="srcBtn'+i+'" type="button" class="btn btn-lg btn-info btn_input_selection" style="margin:10px;min-width:200px" onclick="requestSetSource(\'auto\');">'+$.i18n('remote_input_label_autoselect')+'</button><br/>';
var autostate = (parsedServerInfoJSON.info.priorities_autoselect? "btn-success" : "btn-danger");
data += '<button id="srcBtn'+i+'" type="button" class="btn btn-lg '+autostate+' btn_input_selection" style="margin:10px;min-width:200px" onclick="requestSetSource(\'auto\');">'+$.i18n('remote_input_label_autoselect')+'</button><br/>';
$('#hyperion_inputs').html(data);
var max_width=200;
@@ -24,6 +26,23 @@
});
$('.btn_input_selection').css("min-width",max_width+"px");
}
function updateLedMapping()
{
mappingList = ["multicolor_mean", "unicolor_mean"];
mapping = parsedServerInfoJSON.info.ledMAppingType;
$('#mappingsbutton').html("");
for(var ix = 0; ix < mappingList.length; ix++)
{
if(mapping == mappingList[ix])
btn_style = 'btn-success';
else
btn_style = 'btn-warning';
$('#mappingsbutton').append('<button type="button" id="lmBtn_'+mappingList[ix]+'" class="btn btn-lg '+btn_style+'" style="margin:10px;min-width:200px" onclick="requestMappingType(\''+mappingList[ix]+'\');">'+$.i18n('remote_maptype_label_'+mappingList[ix])+'</button><br/>');
}
}
function updateComponents(event) {
if ($('#componentsbutton').length == 0)
@@ -33,12 +52,12 @@
else
{
updateInputSelect();
updateLedMapping();
components = event.response.info.components;
// create buttons
$('#componentsbutton').html("");
for ( idx=0; idx<components.length;idx++)
{
//components_html += '<tr><td>'+(components[idx].title)+'</td><td><i class="fa fa-circle component-'+(components[idx].enabled?"on":"off")+'"></i></td></tr>';
enable_style = (components[idx].enabled? "btn-success" : "btn-danger");
enable_icon = (components[idx].enabled? "fa-play" : "fa-stop");
comp_name = components[idx].name;
@@ -94,15 +113,6 @@ $(document).ready(function() {
$(function() {
$('#cp2').colorpicker({
format: 'rgb',
colorSelectors: {
'default': '#777777',
'primary': '#337ab7',
'success': '#5cb85c',
'info' : '#5bc0de',
'warning': '#f0ad4e',
'danger' : '#d9534f'
},
customClass: 'colorpicker-2x',
sliders: {
saturation: {

View File

@@ -19,7 +19,16 @@ var loggingStreamActive = false;
var loggingHandlerInstalled = false;
var watchdog = 0;
var debugMessagesActive = true;
//
function initRestart()
{
$(hyperion).off();
requestServerConfigReload();
watchdog = 1;
$("#wrapper").fadeOut("slow");
cron();
}
function cron()
{
if ( watchdog > 2)
@@ -35,6 +44,8 @@ function cron()
$(hyperion).trigger({type:"cron"});
}
setInterval(function(){ watchdog = 0 }, 8000);
// init websocket to hyperion and bind socket events to jquery events of $(hyperion) object
function initWebSocket()
{
@@ -251,3 +262,8 @@ function requestLoggingStop()
sendToHyperion("logging", "stop");
}
function requestMappingType(type)
{
sendToHyperion("processing", "", '"mappingType": "'+type+'"');
}

View File

@@ -1428,7 +1428,7 @@ JSONEditor.AbstractEditor = Class.extend({
if(!options.path && !this.schema.id) this.schema.id = 'root';
this.path = options.path || 'root';
this.formname = options.formname || this.path.replace(/\.([^.]+)/g,'[$1]');
this.formname = options.formname || this.path.replace(/\.([^.]+)/g,'_$1');
if(this.jsoneditor.options.form_name_root) this.formname = this.formname.replace(/^root\[/,this.jsoneditor.options.form_name_root+'[');
this.key = this.path.split('.').pop();
this.parent = options.parent;
@@ -1463,7 +1463,8 @@ JSONEditor.AbstractEditor = Class.extend({
if(this.schema.access){
if(this.schema.access == 'expert' && storedAccess != 'expert'){
this.disable();
this.container.style.display = "none";
//this.disable();
}
}
},
@@ -1885,12 +1886,12 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
register: function() {
this._super();
if(!this.input) return;
this.input.setAttribute('name',this.formname);
this.input.setAttribute('id',this.formname);
},
unregister: function() {
this._super();
if(!this.input) return;
this.input.removeAttribute('name');
this.input.removeAttribute('id');
},
setValue: function(value,initial,from_template) {
var self = this;
@@ -1953,7 +1954,9 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
this.format = this.schema.format;
this.placeholder = this.schema.default;
this.format = this.schema.format;
if(!this.format && this.schema.media && this.schema.media.type) {
this.format = this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,'');
}
@@ -2144,8 +2147,10 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
}
if(this.format) this.input.setAttribute('data-schemaformat',this.format);
this.control = this.theme.getFormControl(this.label, this.input, this.description, this.append);
if(this.defaultValue) this.input.setAttribute('data-schemaformat',this.format);
if(this.formname)this.label.setAttribute('for',this.formname);
this.control = this.theme.getFormControl(this.label, this.input, this.description, this.append, this.placeholder);
this.container.appendChild(this.control);
// Any special formatting that needs to happen after the input is added to the dom
@@ -2668,8 +2673,8 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
else {
this.header = document.createElement('span');
this.header.textContent = this.getTitle();
this.title = this.theme.getHeader(this.header);
this.container.appendChild(this.title);
this.title = this.theme.getHeader(this.header);
this.container.appendChild(this.title);
this.container.style.position = 'relative';
// Edit JSON modal
@@ -2739,12 +2744,6 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
this.description = this.theme.getDescription(this.schema.description);
this.container.appendChild(this.description);
}
// Appends
if(this.schema.append) {
this.append = this.theme.getAppend(this.schema.append);
this.container.appendChild(this.append);
}
// Validation error placeholder area
this.error_holder = document.createElement('div');
@@ -4878,12 +4877,12 @@ JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
register: function() {
this._super();
if(!this.input) return;
this.input.setAttribute('name',this.formname);
this.input.setAttribute('id',this.formname);
},
unregister: function() {
this._super();
if(!this.input) return;
this.input.removeAttribute('name');
this.input.removeAttribute('id');
},
getNumColumns: function() {
if(!this.enum_options) return 3;
@@ -5032,6 +5031,8 @@ JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
self.onInputChange();
});
if(this.formname)this.label.setAttribute('for',this.formname);
this.control = this.theme.getFormControl(this.label, this.input, this.description);
this.container.appendChild(this.control);
@@ -6023,7 +6024,9 @@ JSONEditor.defaults.editors.checkbox = JSONEditor.AbstractEditor.extend({
if(this.options.compact) this.container.className += ' compact';
this.input = this.theme.getCheckbox();
this.control = this.theme.getFormControl(this.label, this.input, this.description);
if(this.formname)this.label.setAttribute('for',this.formname);
if(this.formname)this.input.setAttribute('id',this.formname);
this.control = this.theme.getFormControl(this.label, this.input, this.description);
if(this.schema.readOnly || this.schema.readonly) {
this.always_disabled = true;
@@ -6227,18 +6230,21 @@ JSONEditor.AbstractTheme = Class.extend({
},
getCheckboxLabel: function(text) {
var el = this.getFormInputLabel(text);
el.style.fontWeight = 'normal';
el.style.fontWeight = 'bold';
return el;
},
getHeader: function(text) {
var el = document.createElement('h3');
if(typeof text === "string") {
el.textContent = text;
if(text.innerHTML == ''){
text.style.display = 'none';
return text;
}
else if(typeof text === "string") {
el.textContent = text;
}
else {
el.appendChild(text);
else {
el.appendChild(text);
}
return el;
},
getCheckbox: function() {
@@ -6547,20 +6553,23 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
}
return el;
},
getFormControl: function(label, input, description, append) {
getFormControl: function(label, input, description, append, placeholder) {
var group = document.createElement('div');
var subgroup = document.createElement('div');
if(placeholder)
input.setAttribute('placeholder',placeholder);
if (input.type === 'checkbox'){
var helplabel = document.createElement("label")
group.className += ' form-group';
group.style.minHeight = "30px";
label.className += ' col-form-label col-sm-2';
label.className += ' col-form-label col-sm-5 col-md-3 col-lg-5 col-xxl-4';
label.style.fontWeight = "bold";
group.appendChild(label);
group.appendChild(subgroup);
subgroup.className += 'checkbox col-sm-10';
subgroup.className += 'checkbox col-sm-7 col-md-9 col-lg-7 col-xxl-8';
subgroup.style.marginTop = "0px";
subgroup.appendChild(input);
subgroup.appendChild(helplabel);
@@ -6571,22 +6580,22 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
else if (append){
group.className += ' form-group';
if(label) {
label.className += ' col-form-label col-sm-2';
label.className += ' col-form-label col-sm-5 col-md-3 col-lg-5 col-xxl-4';
group.appendChild(label);
}
group.appendChild(subgroup);
subgroup.className += 'col-sm-10 input-group';
subgroup.className += ' col-sm-7 col-md-9 col-lg-7 input-group col-xxl-8';
subgroup.appendChild(input);
subgroup.appendChild(append);
}
else {
group.className += ' form-group';
if(label) {
label.className += ' col-form-label col-sm-2';
label.className += ' col-form-label col-sm-5 col-md-3 col-lg-5 col-xxl-4';
group.appendChild(label);
}
group.appendChild(subgroup);
subgroup.className += ' input-group col-sm-10';
subgroup.className += ' input-group col-sm-7 col-md-9 col-lg-7 col-xxl-8';
subgroup.appendChild(input);
}
@@ -6625,7 +6634,7 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
},
getButton: function(text, icon, title) {
var el = this._super(text, icon, title);
el.className += 'btn btn-default';
el.className += 'btn btn-sm btn-primary';
return el;
},
getTable: function() {

View File

@@ -82,6 +82,10 @@ function showInfoDialog(type,header,message,btnid)
$('#modal_dialog .modal-footer-button').html('<button type="button" id="'+btnid+'" class="btn btn-success" data-dismiss="modal">'+$.i18n('general_btn_save')+'</button>');
$('#modal_dialog .modal-footer-button').append('<button type="button" class="btn btn-danger" data-dismiss="modal">'+$.i18n('general_btn_abort')+'</button>');
}
else if (type == "uilock"){
$('#modal_dialog .modal-bodyicon').html('<img src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!">');
$('#modal_dialog .modal-footer-button').html('<b>'+$.i18n('InfoDialog_nowrite_foottext')+'</b>');
}
$("#modal_dialog").modal({
backdrop : "static",
@@ -104,11 +108,11 @@ function isJsonString(str)
}
function createJsonEditor(container,schema,setconfig)
function createJsonEditor(container,schema,setconfig,usePanel)
{
$('#'+container).off();
$('#'+container).html("");
var editor = new JSONEditor(document.getElementById(container),
{
theme: 'bootstrap3',
@@ -124,12 +128,13 @@ function createJsonEditor(container,schema,setconfig)
properties: schema
}
});
$('#editor_container .well').css("background-color","white");
$('#editor_container .well').css("border","none");
$('#editor_container .well').css("box-shadow","none");
$('#editor_container .btn').addClass("btn-primary");
$('#editor_container h3').first().remove();
if(usePanel)
{
$('#'+container+' .well').first().removeClass('well well-sm');
$('#'+container+' h3').remove();
$('#'+container+' .well').first().removeClass('well well-sm');
}
if (setconfig)
{
@@ -142,6 +147,80 @@ function createJsonEditor(container,schema,setconfig)
return editor;
}
function createTableTh(th1, th2){
var elth1 = document.createElement('th');
var elth2 = document.createElement('th');
var tr = document.createElement('tr');
elth1.innerHTML = th1;
elth2.innerHTML = th2;
tr.appendChild(elth1);
tr.appendChild(elth2);
return tr;
}
function createTableTd(td1, td2){
var eltd1 = document.createElement('td');
var eltd2 = document.createElement('td');
var tr = document.createElement('tr');
eltd1.innerHTML = td1;
eltd2.innerHTML = td2;
tr.appendChild(eltd1);
tr.appendChild(eltd2);
return tr;
}
function createHelpTable(list, phead){
var table = document.createElement('table');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
table.className = 'table table-hover borderless';
thead.appendChild(createTableTh($.i18n('conf_helptable_option'), $.i18n('conf_helptable_expl')));
for (key in list){
text = list[key].title.replace('title', 'expl');
tbody.appendChild(createTableTd($.i18n(list[key].title), $.i18n(text)));
}
table.appendChild(thead);
table.appendChild(tbody);
return createPanel(phead, table);
}
function createPanel(head, body, footer, type){
var p = document.createElement('div');
var phead = document.createElement('div');
var pbody = document.createElement('div');
var pfooter = document.createElement('div');
if(typeof type == 'undefined')
type = 'panel-default';
p.className = 'panel '+type;
phead.className = 'panel-heading';
pbody.className = 'panel-body';
pfooter.className = 'panel-footer';
phead.innerHTML = head;
if(typeof body != 'undefined')
pbody.appendChild(body);
pfooter.innerHTML = footer;
p.appendChild(phead);
p.appendChild(pbody);
if(typeof footer != 'undefined')
p.appendChild(pfooter);
return p;
}
function createSelGroup(group)
{
var el = document.createElement('optgroup');
@@ -176,7 +255,7 @@ function createSel(array, group)
function performTranslation()
{
$('#wrapper').i18n();
$('[data-i18n]').i18n();
}
function encode_utf8(s)