Refactor config.js let ConfigXML use mt-daapd.conf section:element_id

as the html element id. This fixes ticket #125 and makes the config.xml
parser a bit less complicated.
Config.xml no got rid of config_section and uses an id like this:
"general:servername" etc
One day I will actually think before I start coding. Always pick the
easy and well thought out solution over the quick and dirty.
This commit is contained in:
Anders Betnér 2006-06-04 18:03:10 +00:00
parent 0554045c32
commit 2ba789d0a1
2 changed files with 91 additions and 109 deletions

View File

@ -18,22 +18,14 @@ function init() {
}
var ConfigXML = {
config: {},
configIndex: {},
getOptionFromElementName: function (name) {
return this.configIndex[name];
getItem: function (id) {
return this.config[id];
},
getOption: function (section,id) {
return this.config[section][id];
},
getSections: function () {
return $H(this.config).keys();
},
getItems: function(section) {
return $H(this.config[section]).keys();
getAllItems: function () {
return $H(this.config);
},
parseXML: function(xmlDoc) {
$A(xmlDoc.getElementsByTagName('section')).each(function (section) {
var items = {};
$A(section.getElementsByTagName('item')).each(function (item) {
var returnItem = {};
$A(item.attributes).each(function (attr) {
@ -58,22 +50,15 @@ var ConfigXML = {
returnItem[attr.name] = attr.value;
});
});
// Double index everything one as [section][id]
// and one as [config_section:id]
items[item.getAttribute('id')] = returnItem;
ConfigXML.configIndex[returnItem.config_section+ ':' +returnItem.id] = returnItem;
ConfigXML.config[returnItem.id] = returnItem;
});
ConfigXML.config[section.getAttribute('name')] = items;
});
}
};
var ConfigInitialValues = {
values: {},
getValues: function () {
return $H(ConfigInitialValues.values);
},
getValue: function (section,id) {
return ConfigInitialValues.values[section+':'+id];
getValue: function (id) {
return ConfigInitialValues.values[id];
},
parseXML: function (xmldoc) {
// IE and w3c treat xmldoc differently make shore firstChild is firstchild of <config>
@ -104,38 +89,39 @@ var Config = {
new Ajax.Request('/config.xml',{method: 'get',onComplete: Config.storeConfigLayout});
},
storeConfigLayout: function (request) {
// Need to store this until showConfig is run
Config.tmpConfigXML = request.responseXML;
ConfigXML.parseXML(request.responseXML);
new Ajax.Request('/xml-rpc?method=stats',{method: 'get',onComplete: Config.updateStatus});
},
updateStatus: function (request) {
Config.configPath = Element.textContent(request.responseXML.getElementsByTagName('config_path')[0]);
Config.isWritable = Element.textContent(request.responseXML.getElementsByTagName('writable_config')[0]) == '1';
// $('config_path').appendChild(document.createTextNode(
// );
new Ajax.Request('/xml-rpc?method=config',{method: 'get',onComplete: Config.showConfig});
},
showConfig: function (request) {
ConfigInitialValues.parseXML(request.responseXML);
var sections = ConfigXML.getSections();
sections.each(function (section) {
$A(Config.tmpConfigXML.getElementsByTagName('section')).each(function (section) {
var head = document.createElement('div');
head.className= 'naviheader';
head.appendChild(document.createTextNode(section));
var sectionName = section.getAttribute('name');
head.appendChild(document.createTextNode(sectionName));
var body = document.createElement('div');
body.className = 'navibox';
if ('Server' == section) {
if ('Server' == sectionName) {
body.appendChild(Builder.node('span',{id:'config_path'},'Config File Location'));
body.appendChild(document.createTextNode(Config.configPath));
body.appendChild(Builder.node('br'));
body.appendChild(Builder.node('div',{style: 'clear: both;'}));
}
ConfigXML.getItems(section).each(function (itemId) {
body.appendChild(Config._buildItem(section,itemId));
$A(section.getElementsByTagName('item')).each(function (item) {
body.appendChild(Config._buildItem(item.getAttribute('id')));
});
$('theform').appendChild(head);
$('theform').appendChild(body);
});
// Won't be using the config.xml XML doc anymore get rid of it
Config.tmpConfigXML = '';
if (!Config.isWritable) {
Effect.Appear('config_not_writable_warning');
} else {
@ -172,23 +158,21 @@ var Config = {
div.appendChild(advanced);
div.appendChild(basic);
},
_buildItem: function(section,itemId) {
_buildItem: function(itemId) {
var frag = document.createElement('div');
var href;
var item = ConfigXML.getOption(section,itemId);
var postId = item.config_section + ':' + itemId;
var noBrowse = false;
var item = ConfigXML.getItem(itemId);
switch(item.type) {
case 'text':
if (item.multiple) {
var values = ConfigInitialValues.getValue(item.config_section,item.id);
var values = ConfigInitialValues.getValue(itemId);
if (!values || values.length === 0) {
values = [''];
}
// var parentSpan = Builder.node('span');
values.each(function (val,i) {
var div = document.createElement('div');
div.appendChild(BuildElement.input(postId+i,postId,
div.appendChild(BuildElement.input(itemId+i,itemId,
item.name,
val || item.default_value || '',
item.size || 20,
@ -214,9 +198,9 @@ var Config = {
Event.observe(href,'click',Config._addItemEvent);
frag.appendChild(Builder.node('div',{style:'clear: both'}));
} else {
frag.appendChild(BuildElement.input(postId,postId,
frag.appendChild(BuildElement.input(itemId,itemId,
item.name,
ConfigInitialValues.getValue(item.config_section,item.id) || item.default_value || '',
ConfigInitialValues.getValue(itemId) || item.default_value || '',
item.size || 20,
item.short_description,
''));
@ -229,10 +213,10 @@ var Config = {
}
break;
case 'select':
frag.appendChild(BuildElement.select(postId,
frag.appendChild(BuildElement.select(itemId,
item.name,
item.options,
ConfigInitialValues.getValue(item.config_section,item.id) || item.default_value,
ConfigInitialValues.getValue(itemId) || item.default_value,
item.short_description));
frag.appendChild(Builder.node('br'));
break;
@ -298,7 +282,7 @@ var Config = {
Element.toggle('advanced_config_button');
Element.toggle('basic_config_button');
Cookie.setVar('show_advanced_config','true',30);
$H(ConfigXML.configIndex).each(function (item) {
ConfigXML.getAllItems().each(function (item) {
if (item.value.advanced) {
var element = $(item.key);
if (!element) {
@ -316,7 +300,7 @@ var Config = {
Element.toggle('advanced_config_button');
Element.toggle('basic_config_button');
Cookie.removeVar('show_advanced_config');
$H(ConfigXML.configIndex).each(function (item) {
ConfigXML.getAllItems().each(function (item) {
if (item.value.advanced) {
var element = $(item.key);
if (!element) {
@ -400,7 +384,7 @@ function saveForm() {
});
$A($('theform').getElementsByTagName('input')).each(function (input) {
if (ConfigXML.getOptionFromElementName(input.name).multiple) {
if (ConfigXML.getItem(input.name).multiple) {
if (multiple[input.name]) {
multiple[input.name].push(encodeURIComponent(input.value));
} else {
@ -458,42 +442,40 @@ function saveForm() {
}
}
function cancelForm() {
ConfigXML.getSections().each(function (section){
ConfigXML.getItems(section).each(function (itemId) {
var item = ConfigXML.getOption(section,itemId);
var itemConfigId = item.config_section + ':' + item.id;
if (item.multiple) {
var values = ConfigInitialValues.getValue(item.config_section,itemId);
if (!values || values.length === 0) {
values = [''];
}
var initialValuesCount = values.length;
var currentElements = document.getElementsByName(itemConfigId);
var i=0;
while (initialValuesCount < currentElements.length) {
i++;
if (i > 10) {
alert('Getting dizzy; too many turns in this loop (silly errormessage 1)');
return;
}
Config._removeItem(currentElements[0].parentNode,'noAnimation');
}
while (initialValuesCount > currentElements.length) {
i++;
if (i > 10) {
alert('An important part came off (silly errormessage 2)');
return;
}
Config._addItem(currentElements[currentElements.length-1].parentNode);
}
values.each(function (val,i){
currentElements[i].value = val;
});
} else {
//###TODO potential error a select without a default value
$(itemConfigId).value = ConfigInitialValues.getValue(item.config_section,item.id) || item.default_value || '';
ConfigXML.getAllItems().each(function (item) {
// this is from a hash $H hence use value
item = item.value;
if (item.multiple) {
var values = ConfigInitialValues.getValue(item.id);
if (!values || values.length === 0) {
values = [''];
}
});
var initialValuesCount = values.length;
var currentElements = document.getElementsByName(item.id);
var i=0;
while (initialValuesCount < currentElements.length) {
i++;
if (i > 10) {
alert('Getting dizzy; too many turns in this loop (silly errormessage 1)');
return;
}
Config._removeItem(currentElements[0].parentNode,'noAnimation');
}
while (initialValuesCount > currentElements.length) {
i++;
if (i > 10) {
alert('An important part came off (silly errormessage 2)');
return;
}
Config._addItem(currentElements[currentElements.length-1].parentNode);
}
values.each(function (val,i){
currentElements[i].value = val;
});
} else {
//###TODO potential error a select without a default value
$(item.id).value = ConfigInitialValues.getValue(item.id) || item.default_value || '';
}
});
return;
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<config>
<section name="Server">
<item id="servername" config_section="general" restart="true">
<item id="general:servername" restart="true">
<name>Server Name</name>
<short_description>
The name iTunes and other daap clients should see
@ -13,43 +13,43 @@
</long_description>
<type size="20">text</type>
</item>
<item id="web_root" advanced="true" config_section="general" required="true" restart="true">
<item id="general:web_root" advanced="true" required="true" restart="true">
<name>Web Root</name>
<short_description></short_description>
<type size="80" browse="directory">text</type>
</item>
<item id="port" advanced="true" config_section="general" required="true" restart="true">
<item id="general:port" advanced="true" required="true" restart="true">
<name>Port</name>
<short_description>
The port the server should run at; default is 3689
</short_description>
<type size="20">text</type>
</item>
<item id="logfile" config_section="general">
<item id="general:logfile">
<name>Logfile</name>
<short_description></short_description>
<type size="80" browse="file">text</type>
</item>
<item id="runas" advanced="true" config_section="general" required="true" restart="true">
<item id="general:runas" advanced="true" required="true" restart="true">
<name>Run As</name>
<short_description></short_description>
<type size="20">text</type>
</item>
<item id="admin_pw" config_section="general" required="true">
<item id="general:admin_pw" required="true">
<name>Admin password</name>
<short_description>
The password for this administration interface.
</short_description>
<type size="20">text</type>
</item>
<item id="password" config_section="general">
<item id="general:password">
<name>MP3 Password</name>
<short_description>
The password clients need to access this server.
</short_description>
<type size="20">text</type>
</item>
<item id="compress" advanced="true" config_section="general">
<item id="general:compress" advanced="true">
<name>Compress</name>
<short_description>
Should browsing data be compressed on the way to the client?
@ -60,7 +60,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="debuglevel" advanced="true" config_section="general">
<item id="general:debuglevel" advanced="true">
<name>Debug Level</name>
<short_description>
Possible values are 0 to 9, 9 being the most detailed debug level.
@ -82,22 +82,22 @@
</section>
<section name="Music Files">
<item id="mp3_dir" config_section="general" required="true">
<item id="general:mp3_dir" required="true">
<name>MP3 Directory</name>
<short_description></short_description>
<type size="80" multiple="true" add_item_label="Add mp3 directory" browse="directory">text</type>
</item>
<item id="extensions" config_section="general">
<item id="general:extensions">
<name>Extensions</name>
<short_description></short_description>
<type size="20">text</type>
</item>
<item id="playlist" config_section="general">
<item id="general:playlist">
<name>Playlist File</name>
<short_description></short_description>
<type size="80" browse="file">text</type>
</item>
<item id="process_m3u" config_section="general">
<item id="general:process_m3u">
<name>Process .m3u Files</name>
<short_description>
Should m3u files be processed as playlists?
@ -108,14 +108,14 @@
<option value="1">Yes</option>
</options>
</item>
<item id="compdirs" advanced="true" config_section="general">
<item id="general:compdirs" advanced="true">
<name>Compilation Directories</name>
<short_description></short_description>
<type size="80" multiple="true" add_item_label="Add compilation directory" browse="directory">text</type>
</item>
</section>
<section name="Scanning">
<item id="process_xml" advanced="true" config_section="scanning">
<item id="scanning:process_xml" advanced="true">
<name>Process xmlFiles</name>
<short_description>
Should iTunes xml-files be processed?
@ -126,7 +126,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="ignore_appledouble" advanced="true" config_section="scanning">
<item id="scanning:ignore_appledouble" advanced="true">
<name>Ignore appledouble</name>
<short_description>
Skip appledouble files when scanning
@ -137,7 +137,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="ignore_dotfiles" advanced="true" config_section="scanning">
<item id="scanning:ignore_dotfiles" advanced="true">
<name>Ignore dotfiles</name>
<short_description>
Ignore unix hidden dot files
@ -148,7 +148,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="concat_compilations" advanced="true" config_section="scanning">
<item id="scanning:concat_compilations" advanced="true">
<name>Group compilations</name>
<short_description>
Compilations are grouped under &amp;Various artists&amp;
@ -161,7 +161,7 @@
</item>
</section>
<section name="Database">
<item id="db_type" advanced="true" config_section="general" restart="true">
<item id="general:db_type" advanced="true" restart="true">
<name>Database Type</name>
<short_description></short_description>
<type default_value="sqlite">select</type>
@ -170,12 +170,12 @@
<option value="sqlite3">sqlite3</option>
</options>
</item>
<item id="db_parms" advanced="true" config_section="general" restart="true">
<item id="general:db_parms" advanced="true" restart="true">
<name>Database Directory</name>
<short_description></short_description>
<type size="80" browse="directory">text</type>
</item>
<item id="scan_type" config_section="general" restart="true">
<item id="general:scan_type" restart="true">
<name>Scan Type</name>
<short_description></short_description>
<type default_value="2">select</type>
@ -185,14 +185,14 @@
<option value="2">2 - Painfully aggressive</option>
</options>
</item>
<item id="rescan_interval" config_section="general" restart="true">
<item id="general:rescan_interval" restart="true">
<name>Rescan Interval</name>
<short_description>
How often should mt-daapd look for new files? In seconds.
</short_description>
<type size="20">text</type>
</item>
<item id="always_scan" config_section="general" restart="true">
<item id="general:always_scan" restart="true">
<name>Always Scan</name>
<short_description></short_description>
<type default_value="0">select</type>
@ -204,7 +204,7 @@
</section>
<section name="Daap">
<item id="empty_strings" advanced="true" config_section="daap">
<item id="daap:empty_strings" advanced="true">
<name>Empty strings</name>
<short_description></short_description>
<type default_value="0">select</type>
@ -213,7 +213,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="supports_update" advanced="true" config_section="daap">
<item id="daap:supports_update" advanced="true">
<name>Supports update</name>
<short_description></short_description>
<type default_value="1">select</type>
@ -222,7 +222,7 @@
<option value="1">Yes</option>
</options>
</item>
<item id="supports_browse" advanced="true" config_section="daap">
<item id="daap:supports_browse" advanced="true">
<name>Supports browse</name>
<short_description></short_description>
<type default_value="1">select</type>
@ -235,12 +235,12 @@
</section>
<section name="Plugins">
<item id="plugin_dir" advanced="true" config_section="plugins" restart="true">
<item id="plugins:plugin_dir" advanced="true" config_section="plugins" restart="true">
<name>Plugin Directory</name>
<short_description></short_description>
<type size="80" browse="directory">text</type>
</item>
<item id="plugins" advanced="true" config_section="plugins" restart="true">
<item id="plugins:plugins" advanced="true" config_section="plugins" restart="true">
<name>Plugins</name>
<short_description></short_description>
<type size="20" multiple="true" add_item_label="Add plugin">text</type>
@ -248,12 +248,12 @@
</section>
<section name="Transcoding">
<item id="ssc_prog" advanced="true" config_section="general">
<item id="general:ssc_prog" advanced="true">
<name>SSC Program</name>
<short_description></short_description>
<type size="80" browse="file">text</type>
</item>
<item id="ssc_codectypes" advanced="true" config_section="general">
<item id="general:ssc_codectypes" advanced="true">
<name>SSC Codec Types</name>
<short_description></short_description>
<type size="80">text</type>