diff --git a/helma/Html.js b/helma/Html.js
index b92668db..d91e9d3e 100644
--- a/helma/Html.js
+++ b/helma/Html.js
@@ -9,646 +9,628 @@
* Copyright 1998-2006 Helma Software. All Rights Reserved.
*
* $RCSfile: Html.js,v $
- * $Author: czv $
- * $Revision: 1.2 $
- * $Date: 2006/04/24 07:02:17 $
+ * $Author: robert $
+ * $Revision: 1.3 $
+ * $Date: 2006/11/13 16:59:44 $
*/
+/**
+ * @fileoverview Fields and methods of the helma.Html
+ * and helma.Html.Tablewriter classes.
+ */
+
// take care of any dependencies
app.addRepository('modules/core/String.js');
+app.addRepository('modules/core/Object.js');
-
+/**
+ * Define the global namespace if not existing
+ */
if (!global.helma) {
global.helma = {};
}
+/**
+ * Creates a new instance of helma.Html
+ * @class This class provides various methods for rendering
+ * X/Html tags.
+ * @returns A newly created instance of helma.Html
+ * @constructor
+ */
helma.Html = function() {
- var self = this;
+ return this;
+};
- /**
- * helper function to render an arbitrary markup part
- * @param String the element's name
- * @param String prefix of each rendered element
- * @param String suffix of each rendered element
- * @param Object optional element's attributes
- */
- var renderMarkupPart = function(name, start, end, attr) {
- res.write(start);
- res.write(name);
- if (attr) {
- for (var i in attr) {
- if (i == "prefix" || i == "suffix" ||
- i == "default" || attr[i] == null) {
- continue;
- }
- res.write(" ");
- res.write(i);
- res.write("=\"");
- res.write(attr[i]);
- res.write("\"");
+/**
+ * Static helper method that renders an arbitrary markup part.
+ * @param {String} name The element's name
+ * @param {String} start Prefix of each rendered element
+ * @param {String} end Suffix of each rendered element
+ * @param {Object} attr Optional element attributes
+ */
+helma.Html.renderMarkupPart = function(name, start, end, attr) {
+ res.write(start);
+ res.write(name);
+ if (attr) {
+ for (var i in attr) {
+ if (i == "prefix" || i == "suffix" ||
+ i == "default" || attr[i] == null) {
+ continue;
}
+ res.write(" ");
+ res.write(i);
+ res.write("=\"");
+ res.write(attr[i]);
+ res.write("\"");
}
- res.write(end);
+ }
+ res.write(end);
+ return;
+};
+
+/**
+ * Static helper method used in helma.Html.checkBox
+ * and helma.Html.dropDown to check if a current value
+ * matches against one or more selected values passed
+ * as argument
+ * @param {String} value The current value to check
+ * @param {String|Array} selectedValue Either a single
+ * value to check against the current value, or an array
+ * containing values.
+ * @returns True in case the value is among the selected
+ * values, false otherwise
+ * @type Boolean
+ */
+helma.Html.isSelected = function(value, selectedValue) {
+ if (selectedValue == null || value == null)
+ return false;
+ if (selectedValue instanceof Array)
+ return Array.contains(selectedValue, value);
+ return value == selectedValue;
+};
+
+
+/** @ignore */
+helma.Html.prototype.toString = function() {
+ return "[helma.Html]";
+};
+
+/**
+ * Renders the opening tag of an arbitrary x/html tag
+ * @param {String} name The tag name
+ * @param {Object} attr An optional object containing element attributes
+ */
+helma.Html.prototype.openTag = function(name, attr) {
+ helma.Html.renderMarkupPart(name, "<", ">", attr);
+ return;
+};
+
+/**
+ * Returns the opening tag of an arbitrary x/html tag
+ * @param {String} name The tag name
+ * @param {Object} attr An optional object containing element attributes
+ * @returns The rendered x/html opening tag
+ * @type String
+ * @see #openTag
+ */
+helma.Html.prototype.openTagAsString = function(name, attr) {
+ res.push();
+ helma.Html.renderMarkupPart(name, "<", ">", attr);
+ return res.pop();
+};
+
+/**
+ * Renders the closing tag of an arbitrary x/html tag
+ * @param {String} name The tag name
+ */
+helma.Html.prototype.closeTag = function(name) {
+ helma.Html.renderMarkupPart(name, "", ">", null);
+ return;
+};
+
+/**
+ * Returns the closing tag of an arbitray x/html element
+ * @param {String} name The tag name
+ * @returns The rendered closing tag
+ * @type String
+ * @see #closeTag
+ */
+helma.Html.prototype.closeTagAsString = function(name) {
+ res.push();
+ helma.Html.renderMarkupPart(name, "", ">", null);
+ return res.pop();
+};
+
+/**
+ * Renders an empty arbitrary x/html tag ("contentless tag")
+ * @param {String} name The tag name
+ * @param {Object} attr An optional object containing tag attributes
+ */
+helma.Html.prototype.tag = function(name, attr) {
+ helma.Html.renderMarkupPart(name, "<", " />", attr);
+ return;
+};
+
+/**
+ * Returns an empty arbitrary x/html tag ("contentless tag")
+ * @param {String} name The tag name
+ * @param {Object} attr An optional object containing tag attributes
+ * @returns The rendered element
+ * @type String
+ * @see #tag
+ */
+helma.Html.prototype.tagAsString = function(name, attr) {
+ res.push();
+ helma.Html.renderMarkupPart(name, "<", " />", attr);
+ return res.pop();
+};
+
+/**
+ * Renders an arbitrary x/html element
+ * @param {String} name The element name
+ * @param {String} str The content of the element
+ * @param {Object} attr An optional object containing element attributes
+ */
+helma.Html.prototype.element = function(name, str, attr) {
+ helma.Html.renderMarkupPart(name, "<", ">", attr);
+ res.write(str);
+ helma.Html.renderMarkupPart(name, "", ">");
+ return;
+};
+
+/**
+ * Return an arbitrary x/html element
+ * @param {String} name The element name
+ * @param {String} str The content of the element
+ * @param {Object} attr An optional object containing element attributes
+ * @returns The rendered element
+ * @type String
+ * @see #element
+ */
+helma.Html.prototype.elementAsString = function(name, str, attr) {
+ res.push();
+ this.element(name, str, attr);
+ return res.pop();
+};
+
+/**
+ * Renders an x/html link tag
+ * @param {Object} attr An object containing the link attributes
+ * @param {String} text The text to appear as link
+ */
+helma.Html.prototype.link = function(attr, text) {
+ if (!attr) {
+ res.write("[Html.link: insufficient arguments]");
return;
- };
+ }
+ this.openTag("a", attr);
+ res.write(text);
+ this.closeTag("a");
+ return;
+};
- /**
- * helper function used in Html.checkBox
- * and Html.dropDown to check if a current value
- * matches against one or more selected values
- * @param String the current value
- * @param StringOrArray the selectedValue
- */
- var isSelected = function(value, selectedValue) {
- if (selectedValue == null || value == null)
- return false;
- if (selectedValue instanceof Array)
- return Array.contains(selectedValue, value);
- return value == selectedValue;
- };
+/**
+ * Returns a rendered x/html link tag
+ * @param {Object} attr An object containing the link attributes
+ * @param {String} text The text to appear as link
+ * @returns The rendered link tag
+ * @type String
+ * @see #link
+ */
+helma.Html.prototype.linkAsString = function(attr, text) {
+ res.push();
+ this.link(attr, text);
+ return res.pop();
+};
- /**
- * return a textual representation of this object
- * @return String
- */
- this.toString = function() {
- return "[Antville Html Library]";
- };
-
- /**
- * render the opening tag of an arbitrary x/html element
- * @param String the element's name
- * @param Object the element's attributes
- */
- this.openTag = function(name, attr) {
- renderMarkupPart(name, "<", ">", attr);
+/**
+ * Renders an x/html input tag of type "hidden"
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.hidden = function(param) {
+ if (!param) {
+ res.write("[Html.hidden: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "hidden";
+ attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
+ this.tag("input", attr);
+ return;
+};
- /**
- * return the opening tag of an arbitrary x/html element
- * @see this.openTag
- * @return String the rendered element
- */
- this.openTagAsString = function(name, attr) {
- res.push();
- renderMarkupPart(name, "<", ">", attr);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html input tag of type "hidden"
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered input element
+ * @type String
+ * @see #hidden
+ */
+helma.Html.prototype.hiddenAsString = function(attr) {
+ res.push();
+ this.hidden(attr);
+ return res.pop();
+};
- /**
- * render the closing tag of an arbitrary x/html element
- * directly to response
- * @param String the element's name
- */
- this.closeTag = function(name) {
- renderMarkupPart(name, "", ">", null);
+/**
+ * Renders an x/html text input tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.input = function(param) {
+ if (!param) {
+ res.write("[Html.input: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "text";
+ if (!attr.size)
+ attr.size = 20;
+ attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
+ this.tag("input", attr);
+ return;
+};
- /**
- * return the closing tag of an arbitray x/html element
- * @see this.closeTag
- * @return String the rendered element
- */
- this.closeTagAsString = function(name) {
- res.push();
- renderMarkupPart(name, "", ">", null);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html text input tag
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered text input tag
+ * @type String
+ * @see #input
+ */
+helma.Html.prototype.inputAsString = function(attr) {
+ res.push();
+ this.input(attr);
+ return res.pop();
+};
- /**
- * render an empty arbitrary x/html element ("contentless tag")
- * @param String the element's name
- * @param Object the element's attributes
- */
- this.tag = function(name, attr) {
- renderMarkupPart(name, "<", " />", attr);
+/**
+ * Renders an x/html textarea tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.textArea = function(param) {
+ if (!param) {
+ res.write("[Html.textArea: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ var value = (attr.value != null) ? encodeForm(attr.value) : "";
+ delete attr.value;
+ this.openTag("textarea", attr);
+ res.write(value);
+ this.closeTag("textarea");
+ return;
+};
- /**
- * return an empty arbitrary x/html element ("contentless tag")
- * @see this.tag
- * @return String the rendered element
- */
- this.tagAsString = function(name, attr) {
- res.push();
- renderMarkupPart(name, "<", " />", attr);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html textarea tag
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered textarea tag
+ * @type String
+ * @see #textArea
+ */
+helma.Html.prototype.textAreaAsString = function(attr) {
+ res.push();
+ this.textArea(attr);
+ return res.pop();
+};
- /**
- * render an arbitrary x/html element
- * @param String the element's name
- * @param String the element's content
- * @param Object the element's attributes
- */
- this.element = function(name, str, attr) {
- renderMarkupPart(name, "<", ">", attr);
- res.write(str);
- renderMarkupPart(name, "", ">");
+/**
+ * Renders an x/html checkbox input tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.checkBox = function(param) {
+ if (!param) {
+ res.write("[Html.checkBox: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "checkbox";
+ if (attr.selectedValue != null) {
+ if (helma.Html.isSelected(param.value, param.selectedValue))
+ attr.checked = "checked";
+ else
+ delete attr.checked;
+ delete attr.selectedValue;
+ }
+ this.tag("input", attr);
+ return;
+};
- /**
- * return an arbitrary x/html element
- * @see this.element
- * @param String the rendered element
- */
- this.elementAsString = function(name, str, attr) {
- res.push();
- self.element(name, str, attr);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html checkbox input tag
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered checkbox tag
+ * @type String
+ * @see #checkBox
+ */
+helma.Html.prototype.checkBoxAsString = function(attr) {
+ res.push();
+ this.checkBox(attr);
+ return res.pop();
+};
- /**
- * render an x/html link element
- * @param Object the element's attributes
- * @param String the element's content
- */
- this.link = function(attr, text) {
- if (!attr) {
- res.write("[Html.link: insufficient arguments]");
- return;
- }
- self.openTag("a", attr);
- res.write(text);
- self.closeTag("a");
+/**
+ * Renders an x/html radiobutton input tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.radioButton = function(param) {
+ if (!param) {
+ res.write("[Html.radioButton: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "radio";
+ if (attr.selectedValue != null) {
+ if (attr.value == attr.selectedValue)
+ attr.checked = "checked";
+ else
+ delete attr.checked;
+ delete attr.selectedValue;
+ }
+ this.tag("input", attr);
+ return;
+};
- /**
- * return an x/html link element
- * @see this.link
- * @return String the rendered element
- */
- this.linkAsString = function(attr, text) {
- res.push();
- self.link(attr, text);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html radio input tag
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered element
+ * @type String
+ * @see #radioButton
+ */
+helma.Html.prototype.radioButtonAsString = function(attr) {
+ res.push();
+ this.radioButton(attr);
+ return res.pop();
+};
- /**
- * render an x/html hidden input element
- * @param Object the element's attributes
- */
- this.hidden = function(param) {
- if (!param) {
- res.write("[Html.hidden: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "hidden";
- attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
- self.tag("input", attr);
+/**
+ * Renders an x/html submit input tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.submit = function(param) {
+ if (!param) {
+ res.write("[Html.submit: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "submit";
+ if (!attr.name)
+ attr.name = attr.type;
+ attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
+ this.tag("input", attr);
+ return;
+};
- /**
- * return an x/html hidden input element
- * @see this.hidden
- * @return String the rendered element
- */
- this.hiddenAsString = function(attr) {
- res.push();
- self.hidden(attr);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html submit input tag
+ * @param {Object} attr An object containing the tag attributes
+ * @returns The rendered submit input tag
+ * @type String
+ * @see #submit
+ */
+helma.Html.prototype.submitAsString = function(attr) {
+ res.push();
+ this.submit(attr);
+ return res.pop();
+};
- /**
- * render an x/html text input element
- * @param Object the element's attributes
- */
- this.input = function(param) {
- if (!param) {
- res.write("[Html.input: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "text";
- if (!attr.size)
- attr.size = 20;
- attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
- self.tag("input", attr);
+/**
+ * Renders an x/html button input tag
+ * @param {Object} param An object containing the tag attributes
+ */
+helma.Html.prototype.button = function(param) {
+ if (!param) {
+ res.write("[Html.button: insufficient arguments]");
return;
- };
+ }
+ var attr = Object.clone(param);
+ attr.type = "button";
+ if (!attr.name)
+ attr.name = attr.type;
+ attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
+ this.tag("input", attr);
+ return;
+};
- /**
- * return an x/html text input element
- * @see this.input
- * @return String the rendered element
- */
- this.inputAsString = function(attr) {
- res.push();
- self.input(attr);
- return res.pop();
- };
+/**
+ * Returns a rendered x/html button input tag
+ * @param {Object} param An object containing the tag attributes
+ * @returns The rendered button input tag
+ * @type String
+ * @see #button
+ */
+helma.Html.prototype.buttonAsString = function(attr) {
+ res.push();
+ this.button(attr);
+ return res.pop();
+};
- /**
- * render an x/html textarea element
- * @param Object the element's attributes
- */
- this.textArea = function(param) {
- if (!param) {
- res.write("[Html.textArea: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- var value = (attr.value != null) ? encodeForm(attr.value) : "";
- delete attr.value;
- self.openTag("textarea", attr);
- res.write(value);
- self.closeTag("textarea");
+/**
+ * Renders a x/html drop down select box
+ * @param {Object} param An object containing the tag attributes
+ * @param {Array} options Either an array of strings, an array with
+ * several {value: v, display: d}
objects, or a collection
+ * of ["value", "display"]
arrays in an array
+ * @param {String} selectedValue The value to pre-select
+ * @param {String} firstOption An optional first option to display in the
+ * select box (this option will always have no value)
+ */
+helma.Html.prototype.dropDown = function(param, options, selectedValue, firstOption) {
+ if (!param) {
+ res.write("[Html.dropDown: insufficient arguments]");
return;
- };
-
- /**
- * return an x/html textarea element
- * @see this.textArea
- * @return String the rendered element
- */
- this.textAreaAsString = function(attr) {
- res.push();
- self.textArea(attr);
- return res.pop();
- };
-
- /**
- * render an x/html checkbox input element
- * @param Object the element's attributes
- */
- this.checkBox = function(param) {
- if (!param) {
- res.write("[Html.checkBox: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "checkbox";
- if (attr.selectedValue != null) {
- if (isSelected(param.value, param.selectedValue))
- attr.checked = "checked";
- else
- delete attr.checked;
- delete attr.selectedValue;
- }
- self.tag("input", attr);
- return;
- };
-
- /**
- * return an x/html checkbox input element
- * @see this.checkBox
- * @return String the rendered element
- */
- this.checkBoxAsString = function(attr) {
- res.push();
- self.checkBox(attr);
- return res.pop();
- };
-
- /**
- * render an x/html radiobutton input element
- * @param Object the element's attributes
- */
- this.radioButton = function(param) {
- if (!param) {
- res.write("[Html.radioButton: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "radio";
- if (attr.selectedValue != null) {
- if (attr.value == attr.selectedValue)
- attr.checked = "checked";
- else
- delete attr.checked;
- delete attr.selectedValue;
- }
- self.tag("input", attr);
- return;
- };
-
- /**
- * return an x/html radiobutton input element
- * @see this.radioButton
- * @return String the rendered element
- */
- this.radioButtonAsString = function(attr) {
- res.push();
- self.radioButton(attr);
- return res.pop();
- };
-
- /**
- * render an x/html submit input element
- * @param Object the element's attributes
- */
- this.submit = function(param) {
- if (!param) {
- res.write("[Html.submit: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "submit";
- if (!attr.name)
- attr.name = attr.type;
- attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
- self.tag("input", attr);
- return;
- };
-
- /**
- * return an x/html submit input element
- * @see this.submit
- * @return String the rendered element
- */
- this.submitAsString = function(attr) {
- res.push();
- self.submit(attr);
- return res.pop();
- };
-
- /**
- * render an x/html button input element
- * @param Object the element's attributes
- */
- this.button = function(param) {
- if (!param) {
- res.write("[Html.button: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- attr.type = "button";
- if (!attr.name)
- attr.name = attr.type;
- attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
- self.tag("input", attr);
- return;
- };
-
- /**
- * return an x/html button input element
- * @see this.button
- * @return String the rendered element
- */
- this.buttonAsString = function(attr) {
- res.push();
- self.button(attr);
- return res.pop();
- };
-
- /**
- * render a x/html drop down box
- * @param Object the element's attributes
- * @param Array either an array of strings, an array with
- * several {value: v, display: d} objects, or a collection
- * of ["value", "display"] arrays in an array
- * @param String the currently selected value
- * @param String the first option (without a value)
- */
- this.dropDown = function(param, options, selectedValue, firstOption) {
- if (!param) {
- res.write("[Html.dropDown: insufficient arguments]");
- return;
- }
- var attr = Object.clone(param);
- if (!attr.size)
- attr.size = 1;
- self.openTag("select", attr);
+ }
+ var attr = Object.clone(param);
+ if (!attr.size)
+ attr.size = 1;
+ this.openTag("select", attr);
+ res.write("\n ");
+ if (firstOption) {
+ this.openTag("option", {value: ""});
+ res.write(firstOption);
+ this.closeTag("option");
res.write("\n ");
- if (firstOption) {
- self.openTag("option", {value: ""});
- res.write(firstOption);
- self.closeTag("option");
- res.write("\n ");
- }
- for (var i in options) {
- var attr = new Object();
- var display = "";
- if ((options[i] instanceof Array) && options[i].length > 0) {
- // option is an array
- attr.value = options[i][0];
- display = options[i][1];
- } else if (options[i].value != null && options[i].display != null) {
- // option is an object
- attr.value = options[i].value;
- if (options[i]["class"] != null) {
- attr["class"] = options[i]["class"];
- }
- display = options[i].display;
- } else {
- // assume option is a string
- attr.value = i;
- display = options[i];
+ }
+ for (var i in options) {
+ var attr = new Object();
+ var display = "";
+ if ((options[i] instanceof Array) && options[i].length > 0) {
+ // option is an array
+ attr.value = options[i][0];
+ display = options[i][1];
+ } else if (options[i].value != null && options[i].display != null) {
+ // option is an object
+ attr.value = options[i].value;
+ if (options[i]["class"] != null) {
+ attr["class"] = options[i]["class"];
}
- if (isSelected(attr.value, selectedValue))
- attr.selected = "selected";
- self.openTag("option", attr);
- res.write(display);
- self.closeTag("option");
- res.write("\n ");
+ display = options[i].display;
+ } else {
+ // assume option is a string
+ attr.value = i;
+ display = options[i];
}
- self.closeTag("select");
+ if (helma.Html.isSelected(attr.value, selectedValue))
+ attr.selected = "selected";
+ this.openTag("option", attr);
+ res.write(display);
+ this.closeTag("option");
res.write("\n ");
+ }
+ this.closeTag("select");
+ res.write("\n ");
+ return;
+};
+
+/**
+ * Returns a rendered x/html drop down select box
+ * @param {Object} param An object containing the tag attributes
+ * @param {Array} options Either an array of strings, an array with
+ * several {value: v, display: d}
objects, or a collection
+ * of ["value", "display"]
arrays in an array
+ * @param {String} selectedValue The value to pre-select
+ * @param {String} firstOption An optional first option to display in the
+ * select box (this option will always have no value)
+ * @returns The rendered drop down select box
+ * @type String
+ * @see #dropDown
+ */
+helma.Html.prototype.dropDownAsString = function(attr, options, selectedValue, firstOption) {
+ res.push();
+ this.dropDown(attr, options, selectedValue, firstOption);
+ return res.pop();
+};
+
+/**
+ * Renders an image map based on an array containing the map parameters.
+ * @param {String} name The name of the image map
+ * @param {Array} param An array containing objects, where each of them
+ * contains the attributes for a single image map entry
+ */
+helma.Html.prototype.map = function(name, param) {
+ this.openTag("map", {name: name});
+ var areas = Object.clone(param);
+ for (var i in areas) {
+ if (!areas[i].alt)
+ areas[i].alt = "";
+ if (!areas[i].shape)
+ areas[i].shape = "rect";
+ this.openTag("area", areas[i]);
+ }
+ this.closeTag("map");
+ return;
+};
+
+/**
+ * Returns a rendered image map based on an array containing the map parameters.
+ * @param {String} name The name of the image map
+ * @param {Array} areas An array containing objects, where each of them
+ * contains the attributes for a single image map entry
+ * @returns The rendered image map
+ * @type String
+ * @see #map
+ */
+helma.Html.prototype.mapAsString = function(name, areas) {
+ res.push();
+ this.map(name, areas);
+ return res.pop();
+};
+
+/**
+ * Renders a complete x/html table.
+ * @param {Array} headers An array containing table headers
+ * @param {Array} data A two-dimensional array containing the table data
+ * @param {Object} param An object containing the following properties:
+ *
table
: Attributes to render within the opening <table>
tagtr
: Attributes to render within each <tr>
tagtd
: Attributes to render within each <td>
tagth
: Attributes to render within each <th>
tagtrHead
: Attributes to render within each <tr>
tag
+ in the header area of the tabletrEven
: Attributes to render within each even <tr>
tagtrOdd
: Attributes to render within each odd <tr>
tagtdEven
: Attributes to render within each even <td>
tagtdOdd
: Attributes to render within each odd <td>
tagthEven
: Attributes to render within each even <th>
tagthOdd
: Attributes to render within each odd <th>
tag<th>
tags (defaults to false).
+ * @type Boolean
+ */
+ this.writeHeader = false;
+
+ /**
+ * If set to true the TableWriter returns the rendered table
+ * as string, otherwise the table is written directly to response,
+ * which is the default.
+ * @type Boolean
+ */
+ this.writeString = false;
+
+ this.dontEnum("ncols", "written", "attr", "writeHeader", "writeString");
+
+ return this;
+};
+
+/** @ignore */
+helma.Html.TableWriter.prototype.toString = function() {
+ return "[helma.Html.TableWriter]";
+}
+
+/**
+ * Writes a single table cell to response.
+ * @param {String} text The content of the table cess
+ * @param {Object} attr An optional object containig attributes
+ * to render for this table cell
+ */
+helma.Html.TableWriter.prototype.write = function(text, attr) {
+ // set up some variables
+ var isHeaderRow = (this.writeHeader && this.written < this.ncols);
+ var isNewRow = (this.written % this.ncols == 0);
+ var isEvenRow = ((this.written / this.ncols) % 2 == 0);
+ var isEvenCol = ((this.written % this.ncols) % 2 == 0);
+ // write out table and table row tags
+ if (this.written == 0) {
+ if (this.writeString)
+ res.push();
+ helma.Html.prototype.openTag.call(this, "table", this.attr.table);
+ helma.Html.prototype.openTag.call(this, "tr", this.attr.trHead);
+ } else if (isNewRow) {
+ helma.Html.prototype.closeTag.call(this, "tr");
+ if (isEvenRow)
+ helma.Html.prototype.openTag.call(this, "tr", this.attr.trEven);
+ else
+ helma.Html.prototype.openTag.call(this, "tr", this.attr.trOdd);
+ }
+ // get the attribute object for the table cell
+ if (!attr) {
+ // no explicit attribute given
+ if (isEvenCol) {
+ attr = isHeaderRow ? this.attr.thEven : this.attr.tdEven;
+ } else {
+ attr = isHeaderRow ? this.attr.thOdd : this.attr.tdOdd;
+ }
+ }
+ // write out table cell tag
+ helma.Html.prototype.openTag.call(this, isHeaderRow ? "th" : "td", attr);
+ // write out table cell contents
+ if (text) {
+ res.write(text);
+ }
+ // close table cell
+ helma.Html.prototype.closeTag.call(this, isHeaderRow ? "th" : "td");
+ if (attr && !isNaN(attr.colspan)) {
+ this.written += attr.colspan;
+ } else {
+ this.written += 1;
+ }
+ return;
+};
+
+/**
+ * Closes all open table tags. If {@link #writeString} is set to
+ * true, this method returns the rendered table.
+ * @returns The rendered table, if {@link #writeString} is set to
+ * true, otherwise void.
+ * @type String
+ */
+helma.Html.TableWriter.prototype.close = function() {
+ if (this.written > 0) {
+ while (this.written++ % this.ncols != 0)
+ res.write("